Created
March 23, 2023 12:19
-
-
Save mherchel/8a6dbc1a60afbbd7558b91057d12fd59 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/modules/ckeditor5/ckeditor5.ckeditor5.yml b/core/modules/ckeditor5/ckeditor5.ckeditor5.yml | |
index 4396b64ed4..0372fddc89 100644 | |
--- a/core/modules/ckeditor5/ckeditor5.ckeditor5.yml | |
+++ b/core/modules/ckeditor5/ckeditor5.ckeditor5.yml | |
@@ -263,6 +263,7 @@ ckeditor5_codeBlock: | |
label: Code Block | |
library: ckeditor5/internal.drupal.ckeditor5.codeBlock | |
admin_library: ckeditor5/internal.admin.codeBlock | |
+ class: Drupal\ckeditor5\Plugin\CKEditor5Plugin\CodeBlock | |
toolbar_items: | |
codeBlock: | |
label: Code Block | |
diff --git a/core/modules/ckeditor5/ckeditor5.post_update.php b/core/modules/ckeditor5/ckeditor5.post_update.php | |
index 1e56e029c1..e7d18c19fc 100644 | |
--- a/core/modules/ckeditor5/ckeditor5.post_update.php | |
+++ b/core/modules/ckeditor5/ckeditor5.post_update.php | |
@@ -100,3 +100,19 @@ function ckeditor5_post_update_image_toolbar_item(&$sandbox = []) { | |
$config_entity_updater->update($sandbox, 'editor', $callback); | |
} | |
+ | |
+/** | |
+ * Updates Text Editors using CKEditor 5 Code Block. | |
+ */ | |
+function ckeditor5_post_update_code_block(&$sandbox = []) { | |
+ $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class); | |
+ $config_entity_updater->update($sandbox, 'editor', function (Editor $editor): bool { | |
+ // Only try to update editors using CKEditor 5. | |
+ if ($editor->getEditor() !== 'ckeditor5') { | |
+ return FALSE; | |
+ } | |
+ $settings = $editor->getSettings(); | |
+ | |
+ return in_array('codeBlock', $settings['toolbar']['items'], TRUE); | |
+ }); | |
+} | |
diff --git a/core/modules/ckeditor5/config/schema/ckeditor5.schema.yml b/core/modules/ckeditor5/config/schema/ckeditor5.schema.yml | |
index b7b2bc3b20..7c1d527ae6 100644 | |
--- a/core/modules/ckeditor5/config/schema/ckeditor5.schema.yml | |
+++ b/core/modules/ckeditor5/config/schema/ckeditor5.schema.yml | |
@@ -136,6 +136,31 @@ ckeditor5.plugin.media_media: | |
constraints: | |
NotNull: [] | |
+# Plugin \Drupal\ckeditor5\Plugin\CKEditor5Plugin\CodeBlock | |
+ckeditor5.plugin.ckeditor5_codeBlock: | |
+ type: mapping | |
+ label: Code Block | |
+ mapping: | |
+ languages: | |
+ type: sequence | |
+ orderby: ~ | |
+ label: 'Languages' | |
+ constraints: | |
+ NotBlank: | |
+ message: "Enable at least one language, otherwise disable the Code Block plugin." | |
+ UniqueLabelInList: | |
+ labelKey: label | |
+ sequence: | |
+ type: mapping | |
+ label: 'Language' | |
+ mapping: | |
+ label: | |
+ type: label | |
+ label: 'Language label' | |
+ language: | |
+ type: string | |
+ label: 'Language key' | |
+ | |
# Plugin \Drupal\ckeditor5\Plugin\CKEditor5Plugin\Style | |
ckeditor5.plugin.ckeditor5_style: | |
type: mapping | |
diff --git a/core/modules/ckeditor5/src/Plugin/CKEditor5Plugin/CodeBlock.php b/core/modules/ckeditor5/src/Plugin/CKEditor5Plugin/CodeBlock.php | |
new file mode 100644 | |
index 0000000000..2f05a6f231 | |
--- /dev/null | |
+++ b/core/modules/ckeditor5/src/Plugin/CKEditor5Plugin/CodeBlock.php | |
@@ -0,0 +1,151 @@ | |
+<?php | |
+ | |
+declare(strict_types=1); | |
+ | |
+namespace Drupal\ckeditor5\Plugin\CKEditor5Plugin; | |
+ | |
+use Drupal\ckeditor5\HTMLRestrictions; | |
+use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableTrait; | |
+use Drupal\ckeditor5\Plugin\CKEditor5PluginDefault; | |
+use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableInterface; | |
+use Drupal\ckeditor5\Plugin\CKEditor5PluginElementsSubsetInterface; | |
+use Drupal\Core\Form\FormStateInterface; | |
+use Drupal\editor\EditorInterface; | |
+ | |
+/** | |
+ * CKEditor 5 Code Block plugin configuration. | |
+ * | |
+ * @internal | |
+ * Plugin classes are internal. | |
+ */ | |
+class CodeBlock extends CKEditor5PluginDefault implements CKEditor5PluginConfigurableInterface, CKEditor5PluginElementsSubsetInterface { | |
+ | |
+ use CKEditor5PluginConfigurableTrait; | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { | |
+ $form['languages'] = [ | |
+ '#title' => $this->t('Code Block Languages'), | |
+ '#type' => 'textarea', | |
+ '#description' => $this->t('A list of code block languages that will be provided in the "Code Block" dropdown. Enter one value per line, in the format key|label. Example: php|PHP'), | |
+ ]; | |
+ if (!empty($this->configuration['languages'])) { | |
+ $as_selectors = ''; | |
+ foreach ($this->configuration['languages'] as $language) { | |
+ $as_selectors .= sprintf("%s|%s\n", $language['language'], $language['label']); | |
+ } | |
+ $form['languages']['#default_value'] = $as_selectors; | |
+ } | |
+ | |
+ return $form; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { | |
+ $form_value = $form_state->getValue('languages'); | |
+ [$styles, $unparseable_lines] = self::parseLanguagesFromValue($form_value); | |
+ if (!empty($unparseable_lines)) { | |
+ $line_numbers = array_keys($unparseable_lines); | |
+ $form_state->setError($form['languages'], $this->formatPlural( | |
+ count($unparseable_lines), | |
+ 'Line @line-number does not contain a valid value. Enter a valid language key followed by a pipe symbol and a label.', | |
+ 'Lines @line-numbers do not contain a valid value. Enter a valid language key followed by a pipe symbol and a label.', | |
+ [ | |
+ '@line-number' => reset($line_numbers), | |
+ '@line-numbers' => implode(', ', $line_numbers), | |
+ ] | |
+ )); | |
+ } | |
+ $form_state->setValue('languages', $styles); | |
+ } | |
+ | |
+ /** | |
+ * Parses the line-based (for form) Code Block configuration. | |
+ * | |
+ * @param string $form_value | |
+ * A string containing >=1 lines with on each line a language key and label. | |
+ * | |
+ * @return array | |
+ * The parsed equivalent: a list of arrays with each containing: | |
+ * - label: the label after the pipe symbol, with whitespace trimmed | |
+ * - language: the key for the language | |
+ * | |
+ * @internal | |
+ * This method is public only to allow the CKEditor 4 to 5 upgrade path to | |
+ * reuse this logic. Mark this private in https://www.drupal.org/i/3239012. | |
+ */ | |
+ public static function parseLanguagesFromValue(string $form_value): array { | |
+ $unparseable_lines = []; | |
+ | |
+ $lines = explode("\n", $form_value); | |
+ $languages = []; | |
+ foreach ($lines as $index => $line) { | |
+ if (empty(trim($line))) { | |
+ continue; | |
+ } | |
+ | |
+ // Parse the line. | |
+ [$language, $label] = array_map('trim', explode('|', $line)); | |
+ | |
+ $languages[] = [ | |
+ 'label' => $label, | |
+ 'language' => $language, | |
+ ]; | |
+ } | |
+ return [$languages, $unparseable_lines]; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { | |
+ $this->configuration['languages'] = $form_state->getValue('languages'); | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function defaultConfiguration() { | |
+ return [ | |
+ 'languages' => [ | |
+ [ 'language' => 'plaintext', 'label' => 'Plain text' ], | |
+ [ 'language' => 'c', 'label' => 'C' ], | |
+ [ 'language' => 'cs', 'label' => 'C#' ], | |
+ [ 'language' => 'cpp', 'label' => 'C++' ], | |
+ [ 'language' => 'css', 'label' => 'CSS' ], | |
+ [ 'language' => 'diff', 'label' => 'Diff' ], | |
+ [ 'language' => 'html', 'label' => 'HTML' ], | |
+ [ 'language' => 'java', 'label' => 'Java' ], | |
+ [ 'language' => 'javascript', 'label' => 'JavaScript' ], | |
+ [ 'language' => 'php', 'label' => 'PHP' ], | |
+ [ 'language' => 'python', 'label' => 'Python' ], | |
+ [ 'language' => 'ruby', 'label' => 'Ruby' ], | |
+ [ 'language' => 'typescript', 'label' => 'TypeScript' ], | |
+ [ 'language' => 'xml', 'label' => 'XML' ], | |
+ ], | |
+ ]; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function getElementsSubset(): array { | |
+ return array_column($this->configuration['languages'], 'language'); | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array { | |
+ return [ | |
+ 'codeBlock' => [ | |
+ 'languages' => $this->configuration['languages'], | |
+ ], | |
+ ]; | |
+ } | |
+ | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment