You are here

function _update_ckeditor5_html_filter in Drupal 10

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'
ckeditor5_form_filter_format_form_alter in core/modules/ckeditor5/ckeditor5.module
Implements hook_form_FORM_ID_alter().

File

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

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')) {
    $response
      ->addCommand(new ReplaceCommand('#plugin-settings-wrapper', $form['editor']['settings']['subform']['plugin_settings']['#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,
  ]));
  if (!function_exists('_add_attachments_to_editor_update_response')) {

    /**
     * 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.
     */
    function _add_attachments_to_editor_update_response(array $form, AjaxResponse &$response) : void {
      foreach ($form as $key => $value) {
        if ($key === "#attached") {
          $response
            ->addAttachments(array_diff_key($value, [
            'placeholders' => '',
          ]));
        }
        elseif (is_array($value) && strpos((string) $key, '#') === FALSE) {
          _add_attachments_to_editor_update_response($value, $response);
        }
      }
    }
  }
  _add_attachments_to_editor_update_response($form, $response);
  return $response;
}