function SmartDefaultSettings::addToolbarItemsToMatchHtmlElementsInFormat
Same name in other branches
- 9 core/modules/ckeditor5/src/SmartDefaultSettings.php \Drupal\ckeditor5\SmartDefaultSettings::addToolbarItemsToMatchHtmlElementsInFormat()
- 10 core/modules/ckeditor5/src/SmartDefaultSettings.php \Drupal\ckeditor5\SmartDefaultSettings::addToolbarItemsToMatchHtmlElementsInFormat()
Adds CKEditor 5 toolbar items to match the format's HTML elements.
Parameters
\Drupal\filter\FilterFormatInterface $format: The text format for which to compute smart default settings.
\Drupal\editor\EditorInterface $editor: The text editor config entity to update.
Return value
array|null NULL when nothing happened, otherwise an array with four values: 1. a description (for use in a message) of which CKEditor 5 plugins were enabled to match the HTML tags allowed by the text format. 2. a description (for use in a message) of which CKEditor 5 plugins were enabled to match the HTML attributes allowed by the text format. 3. the unsupported elements, in an HTMLRestrictions value object. 4. the list of enabled plugin labels.
1 call to SmartDefaultSettings::addToolbarItemsToMatchHtmlElementsInFormat()
- SmartDefaultSettings::computeSmartDefaultSettings in core/
modules/ ckeditor5/ src/ SmartDefaultSettings.php - Computes the closest possible equivalent settings for switching to CKEditor 5.
File
-
core/
modules/ ckeditor5/ src/ SmartDefaultSettings.php, line 713
Class
- SmartDefaultSettings
- Generates CKEditor 5 settings for existing text editors/formats.
Namespace
Drupal\ckeditor5Code
private function addToolbarItemsToMatchHtmlElementsInFormat(FilterFormatInterface $format, EditorInterface $editor) : ?array {
$html_restrictions_needed_elements = $format->getHtmlRestrictions();
if ($html_restrictions_needed_elements === FALSE) {
// There are no HTML restrictions, so configure CKEditor 5 to allow
// arbitrary markup to be entered.
$editor_settings_to_update = $editor->getSettings();
// Create new group for all the added toolbar items.
$editor_settings_to_update['toolbar']['items'][] = '|';
$editor_settings_to_update['toolbar']['items'][] = 'sourceEditing';
$editor_settings_to_update['plugins']['ckeditor5_sourceEditing']['allowed_tags'] = [];
$editor->setSettings($editor_settings_to_update);
return [
NULL,
NULL,
HTMLRestrictions::emptySet(),
$this->pluginManager
->getDefinition('ckeditor5_sourceEditing'),
];
}
$all_definitions = $this->pluginManager
->getDefinitions();
$enabled_definitions = $this->pluginManager
->getEnabledDefinitions($editor);
$disabled_definitions = array_diff_key($all_definitions, $enabled_definitions);
$enabled_plugins = array_keys($enabled_definitions);
$provided_elements = $this->pluginManager
->getProvidedElements($enabled_plugins, $editor);
$provided = new HTMLRestrictions($provided_elements);
$needed = HTMLRestrictions::fromTextFormat($format);
// Plugins only supporting <tag attr> cannot create the tag. For that, they
// must support plain <tag> too. With this being the case, break down what
// is needed based on what is currently provided.
// @see \Drupal\ckeditor5\Plugin\CKEditor5PluginDefinition::getCreatableElements()
// TRICKY: the HTMLRestrictions value object can only convey complete
// restrictions: merging <foo> and <foo bar> results in just <foo bar>. The
// list of already provided plain tags must hence be constructed separately.
$provided_plain_tags = new HTMLRestrictions($this->pluginManager
->getProvidedElements($enabled_plugins, NULL, FALSE, TRUE));
// Determine the still needed plain tags, the still needed attributes, and
// the union of both.
$still_needed_plain_tags = $needed->extractPlainTagsSubset()
->diff($provided_plain_tags);
$still_needed_attributes = $needed->diff($provided)
->diff($still_needed_plain_tags);
$still_needed = $still_needed_plain_tags->merge($still_needed_attributes);
if (!$still_needed->allowsNothing()) {
// Select plugins for supporting the still needed plain tags.
$prospective_editor = clone $editor;
$plugin_candidates_plain_tags = self::getCandidates($provided_plain_tags, $still_needed_plain_tags, $disabled_definitions, $prospective_editor);
$selected_plugins_plain_tags = self::selectCandidate($plugin_candidates_plain_tags, $still_needed_plain_tags, array_keys($provided_plain_tags->getAllowedElements()));
// Select plugins for supporting the still needed attributes.
$prospective_editor_settings = $prospective_editor->getSettings();
foreach (array_keys($selected_plugins_plain_tags) as $plugin_id) {
$plugin_definition = $this->pluginManager
->getDefinition($plugin_id);
assert($plugin_definition instanceof CKEditor5PluginDefinition);
if ($plugin_definition->hasToolbarItems()) {
$prospective_editor_settings['toolbar']['items'] = [
$prospective_editor_settings['toolbar']['items'],
array_keys($plugin_definition->getToolbarItems()),
];
}
if ($plugin_definition->isConfigurable()) {
$prospective_editor_settings['plugins'][$plugin_id] = $this->pluginManager
->createInstance($plugin_id)
->defaultConfiguration();
}
}
$prospective_editor->setSettings($prospective_editor_settings);
$plugin_candidates_attributes = self::getCandidates($provided, $still_needed_attributes, array_diff_key($disabled_definitions, $selected_plugins_plain_tags), $prospective_editor);
$selected_plugins_attributes = self::selectCandidate($plugin_candidates_attributes, $still_needed, array_keys($provided->getAllowedElements()));
// Combine the selection.
$selected_plugins = array_merge_recursive($selected_plugins_plain_tags, $selected_plugins_attributes);
// If additional plugins need to be enabled to support attribute config,
// loop through the list to enable the plugins and build a UI message that
// will convey this plugin-enabling to the user.
if (!empty($selected_plugins)) {
$enabled_for_tags_message_content = '';
$enabled_for_attributes_message_content = '';
$editor_settings_to_update = $editor->getSettings();
// Create new group for all the added toolbar items.
$editor_settings_to_update['toolbar']['items'][] = '|';
foreach ($selected_plugins as $plugin_id => $reason_why_enabled) {
$plugin_definition = $this->pluginManager
->getDefinition($plugin_id);
$label = $plugin_definition->label();
$plugins_enabled[] = $label;
[
$net_new,
] = self::computeNetNewElementsForPlugin($provided, $still_needed, $plugin_definition);
// Track remaining elements/attributes that are still needed.
$still_needed = $still_needed->diff($net_new);
// Fulfill the purpose of this method: generate the settings to add
// this plugin's toolbar item.
if ($plugin_definition->hasToolbarItems()) {
$editor_settings_to_update['toolbar']['items'] = array_merge($editor_settings_to_update['toolbar']['items'], array_keys($plugin_definition->getToolbarItems()));
foreach ($reason_why_enabled as $attribute_name => $attribute_config) {
// Plugin was selected for tag.
if (in_array($attribute_name, [
'-attributes-none-',
'-attributes-any-',
], TRUE)) {
$tags = array_reduce(array_keys($net_new->getAllowedElements()), function ($carry, $item) {
return $carry . "<{$item}>";
});
$enabled_for_tags_message_content .= "{$label} (for tags: {$tags}) ";
// This plugin does not add attributes: continue to next plugin.
continue;
}
// Plugin was selected for attribute.
$enabled_for_attributes_message_content .= "{$label} (";
foreach ($attribute_config as $tag_name => $attribute_value_config) {
$enabled_for_attributes_message_content .= " for tag: <{$tag_name}> to support: {$attribute_name}";
if (is_array($attribute_value_config)) {
$enabled_for_attributes_message_content .= " with value(s): ";
foreach (array_keys($attribute_value_config) as $allowed_value) {
$enabled_for_attributes_message_content .= " {$allowed_value},";
}
$enabled_for_attributes_message_content = substr($enabled_for_attributes_message_content, 0, -1) . '), ';
}
}
}
}
}
$editor->setSettings($editor_settings_to_update);
// Some plugins enabled, maybe some missing tags or attributes.
return [
substr($enabled_for_tags_message_content, 0, -1),
substr($enabled_for_attributes_message_content, 0, -2),
$still_needed,
$plugins_enabled,
];
}
else {
// No plugins enabled, maybe some missing tags or attributes.
return [
NULL,
NULL,
$still_needed,
NULL,
];
}
}
else {
return NULL;
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.