function _update_ckeditor5_html_filter

Same name and namespace in other branches
  1. 9 core/modules/ckeditor5/ckeditor5.module \_update_ckeditor5_html_filter()
  2. 10 core/modules/ckeditor5/ckeditor5.module \_update_ckeditor5_html_filter()

AJAX callback handler for filter_format_form().

Used instead of editor_form_filter_admin_form_ajax from the editor module.

1 string reference to '_update_ckeditor5_html_filter'
Ckeditor5Hooks::formFilterFormatFormAlter in core/modules/ckeditor5/src/Hook/Ckeditor5Hooks.php
Implements hook_form_FORM_ID_alter().

File

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

Code

function _update_ckeditor5_html_filter(array $form, FormStateInterface $form_state) {
  $response = new AjaxResponse();
  $renderer = \Drupal::service('renderer');
  // Replace the editor settings with the settings for the currently selected
  // editor. This is the default behavior of editor.module. Except when using
  // CKEditor 5: then we only want CKEditor 5's plugin settings to be updated:
  // the client side-rendered admin UI would otherwise be dependent on network
  // latency.
  $renderedField = $renderer->render($form['editor']['settings']);
  if ($form_state->get('ckeditor5_is_active') && $form_state->get('ckeditor5_is_selected')) {
    $plugin_settings_markup = $form['editor']['settings']['subform']['plugin_settings']['#markup'];
    // If no configurable plugins are enabled, render an empty container with
    // the same ID instead. Otherwise it'll be impossible to render plugin
    // settings vertical tabs in the correct location when such a plugin is
    // enabled.
    // @see \Drupal\Core\Render\Element\VerticalTabs::preRenderVerticalTabs
    $markup = $plugin_settings_markup ?? [
      '#type' => 'container',
      '#attributes' => [
        'id' => 'plugin-settings-wrapper',
      ],
    ];
    $response->addCommand(new ReplaceCommand('#plugin-settings-wrapper', $markup));
  }
  else {
    $response->addCommand(new ReplaceCommand('#editor-settings-wrapper', $renderedField));
  }
  if ($form_state->get('ckeditor5_is_active')) {
    // Delete all existing validation messages, replace them with the current
    // set.
    $response->addCommand(new RemoveCommand('#ckeditor5-realtime-validation-messages-container > *'));
    $messages = \Drupal::messenger()->deleteAll();
    foreach ($messages as $type => $messages_by_type) {
      foreach ($messages_by_type as $message) {
        $response->addCommand(new MessageCommand($message, '#ckeditor5-realtime-validation-messages-container', [
          'type' => $type,
        ], FALSE));
      }
    }
  }
  else {
    // If switching to CKEditor 5 triggers a validation error, the real-time
    // validation messages container will not exist, because CKEditor 5's
    // configuration form will not be rendered.
    // In this case, render it into the (empty) editor settings wrapper. When
    // the validation error is addressed, CKEditor 5's configuration form will
    // get rendered and will overwrite those validation error messages.
    $response->addCommand(new PrependCommand('#editor-settings-wrapper', [
      '#type' => 'status_messages',
    ]));
  }
  // Rebuild filter_settings form item when one of the following is true:
  // - Switching to CKEditor 5 from another text editor, and the current
  //   configuration triggers no fundamental compatibility errors.
  // - Switching from CKEditor 5 to a different editor.
  // - The editor is not being switched, and is currently CKEditor 5.
  if ($form_state->get('ckeditor5_is_active') || $form_state->get('ckeditor5_is_selected') && !$form_state->getError($form['editor']['editor'])) {
    // Replace the filter settings with the settings for the currently selected
    // editor.
    $renderedSettings = $renderer->render($form['filter_settings']);
    $response->addCommand(new ReplaceCommand('#filter-settings-wrapper', $renderedSettings));
  }
  // If switching to CKEditor 5 from another editor and there are errors in that
  // switch, add an error class and attribute to the editor select, otherwise
  // remove.
  $ckeditor5_selected_but_errors = !$form_state->get('ckeditor5_is_active') && $form_state->get('ckeditor5_is_selected') && !empty($form_state->getErrors());
  $response->addCommand(new InvokeCommand('[data-drupal-selector="edit-editor-editor"]', $ckeditor5_selected_but_errors ? 'addClass' : 'removeClass', [
    'error',
  ]));
  $response->addCommand(new InvokeCommand('[data-drupal-selector="edit-editor-editor"]', $ckeditor5_selected_but_errors ? 'attr' : 'removeAttr', [
    'data-error-switching-to-ckeditor5',
    TRUE,
  ]));
  
  /*
   * Recursively find #attach items in the form and add as attachments to the
   * AJAX response.
   *
   * @param array $form
   *   A form array.
   * @param \Drupal\Core\Ajax\AjaxResponse $response
   *   The AJAX response attachments will be added to.
   */
  $attach = function (array $form, AjaxResponse &$response) use (&$attach) : void {
    foreach ($form as $key => $value) {
      if ($key === "#attached") {
        $response->addAttachments(array_diff_key($value, [
          'placeholders' => '',
        ]));
      }
      elseif (is_array($value) && !str_contains((string) $key, '#')) {
        $attach($value, $response);
      }
    }
  };
  $attach($form, $response);
  return $response;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.