Commit 11ac481e authored by Ben Mullins's avatar Ben Mullins
Browse files

Issue #3259593 by hooroomoo, Dom., Wim Leers, lauriii: Alignment being...

Issue #3259593 by hooroomoo, Dom., Wim Leers, lauriii: Alignment being available as separate buttons AND in dropdown is confusing
parent f0f493c5
Loading
Loading
Loading
Loading
+3 −46
Original line number Diff line number Diff line
@@ -391,7 +391,7 @@ ckeditor5_horizontalLine:
      - <hr>

ckeditor5_alignment:
  ckeditor5: &alignment_ckeditor5_section
  ckeditor5:
    plugins: [alignment.Alignment]
    config:
      # @see core/modules/system/css/components/align.module.css
@@ -405,60 +405,17 @@ ckeditor5_alignment:
            className: text-align-right
          - name: justify
            className: text-align-justify
  drupal: &alignment_drupal_section
  drupal:
    label: Alignment
    library: core/ckeditor5.alignment
    admin_library: ckeditor5/admin.alignment
    class: Drupal\ckeditor5\Plugin\CKEditor5Plugin\Alignment
    toolbar_items:
      alignment:
        label: Text alignment
    elements:
      - <$text-container class="text-align-left text-align-center text-align-right text-align-justify">

ckeditor5_alignment.left:
  ckeditor5: *alignment_ckeditor5_section
  drupal:
    label: Align left
    toolbar_items:
      "alignment:left":
        label: Align left
    elements:
      - <$text-container class="text-align-left">
    <<: *alignment_drupal_section

ckeditor5_alignment.center:
  ckeditor5: *alignment_ckeditor5_section
  drupal:
    label: Align center
    toolbar_items:
      "alignment:center":
        label: Align center
    elements:
      - <$text-container class="text-align-center">
    <<: *alignment_drupal_section

ckeditor5_alignment.right:
  ckeditor5: *alignment_ckeditor5_section
  drupal:
    label: Align right
    toolbar_items:
      "alignment:right":
        label: Align right
    elements:
      - <$text-container class="text-align-right">
    <<: *alignment_drupal_section

ckeditor5_alignment.justify:
  ckeditor5: *alignment_ckeditor5_section
  drupal:
    label: Justify
    toolbar_items:
      "alignment:justify":
        label: Justify
    elements:
      - <$text-container class="text-align-justify">
    <<: *alignment_drupal_section

ckeditor5_removeFormat:
  ckeditor5:
    plugins: [removeFormat.RemoveFormat]
+53 −0
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Post update functions for CKEditor 5.
 */

use Drupal\Core\Config\Entity\ConfigEntityUpdater;
use Drupal\editor\Entity\Editor;

/**
 * Updates if an already migrated CKEditor 5 configuration for text formats
 * has alignment shown as individual buttons instead of a dropdown.
 */
function ckeditor5_post_update_alignment_buttons(&$sandbox = []) {
  $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);

  $callback = function (Editor $editor) {
    // Only try to update editors using CKEditor 5.
    if ($editor->getEditor() !== 'ckeditor5') {
      return FALSE;
    }

    $needs_update = FALSE;
    // Only update if the editor is using the non-dropdown buttons.
    $settings = $editor->getSettings();
    $old_alignment_buttons_to_types = [
      'alignment:left' => 'left',
      'alignment:right' => 'right',
      'alignment:center' => 'center',
      'alignment:justify' => 'justify',
    ];
    if (is_array($settings['toolbar']['items'])) {
      foreach ($old_alignment_buttons_to_types as $button => $type) {
        if (in_array($button, $settings['toolbar']['items'], TRUE)) {
          $settings['toolbar']['items'] = array_values(array_diff($settings['toolbar']['items'], [$button]));
          $settings['plugins']['ckeditor5_alignment']['enabled_alignments'][] = $type;
          if (!in_array('alignment', $settings['toolbar']['items'], TRUE)) {
            $settings['toolbar']['items'][] = 'alignment';
          }
          // Flag this display as needing to be updated.
          $needs_update = TRUE;
        }
      }
    }
    if ($needs_update) {
      $editor->setSettings($settings);
    }
    return $needs_update;
  };

  $config_entity_updater->update($sandbox, 'editor', $callback);
}
+21 −0
Original line number Diff line number Diff line
@@ -87,6 +87,27 @@ ckeditor5.plugin.ckeditor5_sourceEditing:
          SourceEditingRedundantTags: []
          SourceEditingPreventSelfXssConstraint: []

# Plugin \Drupal\ckeditor5\Plugin\CKEditor5Plugin\Alignment
ckeditor5.plugin.ckeditor5_alignment:
  type: mapping
  label: Alignments
  mapping:
    enabled_alignments:
      type: sequence
      label: 'Enabled Alignments'
      constraints:
        NotBlank:
          message: "Enable at least one alignment, otherwise disable the Alignment button."
      sequence:
        type: string
        label: 'Alignment type'
        constraints:
          Choice:
            - left
            - center
            - right
            - justify

# Plugin \Drupal\ckeditor5\Plugin\CKEditor5Plugin\ListPlugin
ckeditor5.plugin.ckeditor5_list:
  type: mapping
+38 −7
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
 *   },
 *   cke5_plugin_elements_subset_configuration = {
 *    "ckeditor5_heading",
 *    "ckeditor5_alignment",
 *    "ckeditor5_list",
 *    "media_media",
 *   }
@@ -73,6 +74,7 @@ class Core extends PluginBase implements CKEditor4To5UpgradePluginInterface {
   * {@inheritdoc}
   */
  public function mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem(string $cke4_button, HTMLRestrictions $text_format_html_restrictions): ?array {
    static $alignment_mapped;
    switch ($cke4_button) {
      // @see \Drupal\ckeditor\Plugin\CKEditorPlugin\DrupalImage
      case 'DrupalImage':
@@ -103,16 +105,14 @@ public function mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem(string $cke4_but
        return ['blockQuote'];

      case 'JustifyLeft':
        return ["alignment:left"];

      case 'JustifyCenter':
        return ["alignment:center"];

      case 'JustifyRight':
        return ["alignment:right"];

      case 'JustifyBlock':
        return ["alignment:justify"];
        if (!isset($alignment_mapped)) {
          $alignment_mapped = TRUE;
          return ['alignment'];
        }
        return NULL;

      case 'HorizontalRule':
        return ['horizontalLine'];
@@ -228,6 +228,37 @@ public function computeCKEditor5PluginSubsetConfiguration(string $cke5_plugin_id
        }
        return $configuration;

      case 'ckeditor5_alignment':
        $alignment_classes_to_types = [
          'text-align-left' => 'left',
          'text-align-right' => 'right',
          'text-align-center' => 'center',
          'text-align-justify' => 'justify',
        ];
        $restrictions = $text_format->getHtmlRestrictions();
        if ($restrictions === FALSE) {
          // The default is to allow all alignments. This makes sense when there
          // are no restrictions.
          // @see \Drupal\ckeditor5\Plugin\CKEditor5Plugin\Alignment::DEFAULT_CONFIGURATION
          return NULL;
        }
        // Otherwise, enable alignment types based on the provided restrictions.
        // I.e. if a tag is found with a text-align-{alignment type} class,
        // activate that alignment type.
        $configuration = [];
        foreach ($restrictions['allowed'] as $tag) {
          $classes = isset($tag['class']) && is_array($tag['class']) ? $tag['class'] : [];
          foreach (array_keys($classes) as $class) {
            if (isset($alignment_classes_to_types[$class])) {
              $configuration['enabled_alignments'][] = $alignment_classes_to_types[$class];
            }
          }
        }
        if (isset($configuration['enabled_alignments'])) {
          $configuration['enabled_alignments'] = array_unique($configuration['enabled_alignments']);
        }
        return $configuration;

      case 'ckeditor5_list':
        $restrictions = $text_format->getHtmlRestrictions();
        if ($restrictions === FALSE) {
+125 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\ckeditor5\Plugin\CKEditor5Plugin;

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;
use Drupal\ckeditor5\HTMLRestrictions;

/**
 * CKEditor 5 Alignment plugin.
 *
 * @internal
 *   Plugin classes are internal.
 */
class Alignment extends CKEditor5PluginDefault implements CKEditor5PluginConfigurableInterface, CKEditor5PluginElementsSubsetInterface {

  use CKEditor5PluginConfigurableTrait;

  /**
   * The default configuration for this plugin.
   *
   * @var string[][]
   */
  const DEFAULT_CONFIGURATION = [
    'enabled_alignments' => [
      'left',
      'center',
      'right',
      'justify',
    ],
  ];

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return static::DEFAULT_CONFIGURATION;
  }

  /**
   * {@inheritdoc}
   *
   * Form for choosing which alignment types are available.
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form['enabled_alignments'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Enabled Alignments'),
      '#description' => $this->t('These are the alignment types that will appear in the alignment dropdown.'),
    ];

    foreach ($this->getPluginDefinition()->getCKEditor5Config()['alignment']['options'] as $alignment_option) {
      $name = $alignment_option['name'];
      $form['enabled_alignments'][$name] = [
        '#type' => 'checkbox',
        '#title' => $this->t($name),
        '#return_value' => $name,
        '#default_value' => in_array($name, $this->configuration['enabled_alignments'], TRUE) ? $name : NULL,
      ];
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
    // Match the config schema structure at ckeditor5.plugin.ckeditor5_alignment.
    $form_value = $form_state->getValue('enabled_alignments');
    $config_value = array_values(array_filter($form_value));
    $form_state->setValue('enabled_alignments', $config_value);
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this->configuration['enabled_alignments'] = $form_state->getValue('enabled_alignments');
  }

  /**
   * {@inheritdoc}
   *
   * Filters the alignment options to those chosen in editor config.
   */
  public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array {
    $enabled_alignments = $this->configuration['enabled_alignments'];
    $all_alignment_options = $static_plugin_config['alignment']['options'];

    $configured_alignment_options = array_filter($all_alignment_options, function ($option) use ($enabled_alignments) {
      return in_array($option['name'], $enabled_alignments, TRUE);
    });

    return [
      'alignment' => [
        'options' => array_values($configured_alignment_options),
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getElementsSubset(): array {
    $enabled_alignments = $this->configuration['enabled_alignments'];
    $plugin_definition = $this->getPluginDefinition();
    $all_elements = $plugin_definition->getElements();
    $subset = HTMLRestrictions::fromString(implode($all_elements));
    foreach ($plugin_definition->getCKEditor5Config()['alignment']['options'] as $configured_alignment) {
      if (!in_array($configured_alignment['name'], $enabled_alignments, TRUE)) {
        $element_string = '<$text-container class=' . '"' . $configured_alignment["className"] . '"' . '>';
        $subset = $subset->diff(HTMLRestrictions::fromString($element_string));
      }
    }
    return $subset->toCKEditor5ElementsArray();
  }

}
Loading