function _update_ckeditor5_html_filter

Same name in other branches
  1. 9 core/modules/ckeditor5/ckeditor5.module \_update_ckeditor5_html_filter()
  2. 11.x 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'
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 264

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.