You are here

function ckeditor5_form_filter_format_form_alter in Drupal 10

Implements hook_form_FORM_ID_alter().

File

core/modules/ckeditor5/ckeditor5.module, line 124

Code

function ckeditor5_form_filter_format_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  $editor = $form_state
    ->get('editor');

  // CKEditor 5 plugin config determines the available HTML tags. If an HTML
  // restricting filter is enabled and the editor is CKEditor 5, the 'Allowed
  // HTML tags' field is made read only and automatically populated with the
  // values needed by CKEditor 5 plugins.
  // @see \Drupal\ckeditor5\Plugin\Editor\CKEditor5::buildConfigurationForm()
  if ($editor && $editor
    ->getEditor() === 'ckeditor5') {
    if (isset($form['filters']['settings']['filter_html']['allowed_html'])) {
      $filter_allowed_html =& $form['filters']['settings']['filter_html']['allowed_html'];
      $filter_allowed_html['#value_callback'] = [
        CKEditor5::class,
        'getGeneratedAllowedHtmlValue',
      ];

      // Set readonly and add the form-disabled wrapper class as using #disabled
      // or the disabled attribute will prevent the new values from being
      // validated.
      $filter_allowed_html['#attributes']['readonly'] = TRUE;
      $filter_allowed_html['#wrapper_attributes']['class'][] = 'form-disabled';
      $filter_allowed_html['#description'] = t('With CKEditor 5 this is a
          read-only field. The allowed HTML tags and attributes are determined
          by the CKEditor 5 configuration. Manually removing tags would break
          enabled functionality, and any manually added tags would be removed by
          CKEditor 5 on render.');

      // The media_filter_format_edit_form_validate validator is not needed
      // with CKEditor 5 as it exists to enforce the inclusion of specific
      // allowed tags that are added automatically by CKEditor 5. The
      // validator is removed so it does not conflict with the automatic
      // addition of those allowed tags.
      $key = array_search('media_filter_format_edit_form_validate', $form['#validate']);
      if ($key !== FALSE) {
        unset($form['#validate'][$key]);
      }
    }
  }

  // Override the AJAX callbacks for changing editors, so multiple areas of the
  // form can be updated on change.
  $form['editor']['editor']['#ajax'] = [
    'callback' => '_update_ckeditor5_html_filter',
    'trigger_as' => [
      'name' => 'editor_configure',
    ],
  ];
  $form['editor']['configure']['#ajax'] = [
    'callback' => '_update_ckeditor5_html_filter',
  ];
  $form['editor']['settings']['subform']['toolbar']['items']['#ajax'] = [
    'callback' => '_update_ckeditor5_html_filter',
    'trigger_as' => [
      'name' => 'editor_configure',
    ],
    'event' => 'change',
    'ckeditor5_only' => 'true',
  ];
  foreach (Element::children($form['filters']['status']) as $filter_type) {
    $form['filters']['status'][$filter_type]['#ajax'] = [
      'callback' => '_update_ckeditor5_html_filter',
      'trigger_as' => [
        'name' => 'editor_configure',
      ],
      'event' => 'change',
      'ckeditor5_only' => 'true',
    ];
  }
  if (!function_exists('_add_ajax_listeners_to_plugin_inputs')) {

    /**
     * Recursively adds AJAX listeners to plugin settings elements.
     *
     * These are added so allowed tags and other fields that have values
     * dependent on plugin settings can be updated via AJAX when these settings
     * are changed in the editor form.
     *
     * @param array $plugins_config_form
     *   The plugins config subform render array.
     */
    function _add_ajax_listeners_to_plugin_inputs(array &$plugins_config_form) : void {
      $field_types = [
        'checkbox',
        'select',
        'radios',
        'textarea',
      ];
      if (isset($plugins_config_form['#type']) && in_array($plugins_config_form['#type'], $field_types) && !isset($plugins_config_form['#ajax'])) {
        $plugins_config_form['#ajax'] = [
          'callback' => '_update_ckeditor5_html_filter',
          'trigger_as' => [
            'name' => 'editor_configure',
          ],
          'event' => 'change',
          'ckeditor5_only' => 'true',
        ];
      }
      foreach ($plugins_config_form as $key => &$value) {
        if (is_array($value) && strpos((string) $key, '#') === FALSE) {
          _add_ajax_listeners_to_plugin_inputs($value);
        }
      }
    }
  }
  if (isset($form['editor']['settings']['subform']['plugins'])) {
    _add_ajax_listeners_to_plugin_inputs($form['editor']['settings']['subform']['plugins']);
  }

  // Add an ID to the filter settings vertical tabs wrapper to facilitate AJAX
  // updates.
  $form['filter_settings']['#wrapper_attributes']['id'] = 'filter-settings-wrapper';

  // Add an ID to the editor settings vertical tabs wrapper so it can be easily
  // targeted by JavaScript. If there are no configurable plugins, render an
  // empty container with the same ID instead.
  // @todo consider moving this to editor.module when this module is moved to
  //   Drupal core https://www.drupal.org/project/ckeditor5/issues/3231322.
  if (!empty($form['editor']['settings']['subform']['plugins'])) {
    $form['editor']['settings']['subform']['plugin_settings']['#wrapper_attributes']['id'] = 'plugin-settings-wrapper';
  }
  else {
    $form['editor']['settings']['subform']['plugin_settings'] = [
      '#type' => 'container',
      '#attributes' => [
        'id' => 'plugin-settings-wrapper',
      ],
    ];
  }
  $form['#after_build'][] = [
    CKEditor5::class,
    'assessActiveTextEditorAfterBuild',
  ];
  $form['#validate'][] = [
    CKEditor5::class,
    'validateSwitchingToCKEditor5',
  ];
  array_unshift($form['actions']['submit']['#submit'], 'ckeditor5_filter_format_edit_form_submit');
}