Loading core/modules/ckeditor5/ckeditor5.ckeditor5.yml +2 −1 Original line number Diff line number Diff line Loading @@ -629,7 +629,8 @@ media_media: class: Drupal\ckeditor5\Plugin\CKEditor5Plugin\Media elements: - <drupal-media> - <drupal-media data-entity-type data-entity-uuid alt data-view-mode> - <drupal-media data-entity-type data-entity-uuid alt> - <drupal-media data-view-mode> conditions: filter: media_embed Loading core/modules/ckeditor5/src/Plugin/CKEditor5Plugin/Media.php +3 −6 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; use Drupal\ckeditor5\Plugin\CKEditor5PluginDefinition; use Drupal\ckeditor5\HTMLRestrictions; /** * CKEditor 5 Media plugin. Loading Loading @@ -194,14 +193,12 @@ public function getDynamicPluginConfig(array $static_plugin_config, EditorInterf * {@inheritdoc} */ public function getElementsSubset(): array { $all_elements = $this->getPluginDefinition()->getElements(); $subset = HTMLRestrictions::fromString(implode($all_elements)); $subset = $this->getPluginDefinition()->getElements(); $view_mode_override_enabled = $this->getConfiguration()['allow_view_mode_override']; if (!$view_mode_override_enabled) { $subset = $subset->diff(HTMLRestrictions::fromString('<drupal-media data-view-mode>')); $subset = array_diff($subset, ['<drupal-media data-view-mode>']); } // @todo Simplify in https://www.drupal.org/project/drupal/issues/3278636, that will allow removing all uses of HTMLRestrictions in this class. return array_merge(['<drupal-media>'], $subset->toCKEditor5ElementsArray()); return $subset; } /** Loading core/modules/ckeditor5/tests/src/Unit/HTMLRestrictionsTest.php +36 −2 Original line number Diff line number Diff line Loading @@ -302,6 +302,26 @@ public function providerConvenienceConstructors(): \Generator { '<ol type="I A 1">', ['ol' => ['type' => ['I' => TRUE, 'A' => TRUE, 1 => TRUE]]], ]; yield 'tag with two attributes, spread across declarations' => [ '<a target> <a class>', ['a' => ['target' => TRUE, 'class' => TRUE]], ]; yield 'tag with conflicting attribute config, allow one attribute and forbid all attributes' => [ '<a target> <a>', ['a' => ['target' => TRUE]], ]; yield 'tag with conflicting attribute config, allow one attribute and allow all attributes' => [ '<a *> <a target>', ['a' => TRUE], ]; yield 'tag attribute configuration spread across declarations' => [ '<a target="_blank"> <a target="_self"> <a target="_*">', ['a' => ['target' => ['_blank' => TRUE, '_self' => TRUE, '_*' => TRUE]]], ]; yield 'tag attribute configuration spread across declarations, allow all attributes values' => [ '<a target> <a target="_blank"> <a target="_self"> <a target="_*">', ['a' => ['target' => TRUE]], ]; // Multiple tag cases. yield 'two tags' => [ Loading @@ -309,8 +329,8 @@ public function providerConvenienceConstructors(): \Generator { ['a' => FALSE, 'p' => FALSE], ]; yield 'two tags (reverse order)' => [ '<a> <p>', ['a' => FALSE, 'p' => FALSE], '<p> <a>', ['p' => FALSE, 'a' => FALSE], ]; // Wildcard tag, attribute and attribute value. Loading @@ -328,6 +348,20 @@ public function providerConvenienceConstructors(): \Generator { ], ], ]; yield '$text-container, with attribute values spread across declarations' => [ '<$text-container class="text-align-left"> <$text-container class="text-align-center"> <$text-container class="text-align-right"> <$text-container class="text-align-justify">', [], [ '$text-container' => [ 'class' => [ 'text-align-left' => TRUE, 'text-align-center' => TRUE, 'text-align-right' => TRUE, 'text-align-justify' => TRUE, ], ], ], ]; yield '$text-container + one concrete tag to resolve into' => [ '<p> <$text-container class="text-align-left text-align-center text-align-right text-align-justify">', [ Loading core/modules/ckeditor5/tests/src/Unit/SourceEditingPluginTest.php +24 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,18 @@ public function providerGetDynamicPluginConfig(): array { [ 'name' => 'foo2', 'attributes' => [ [ 'key' => [ 'regexp' => [ 'pattern' => '/^bar-.*$/', ], ], 'value' => [ 'regexp' => [ 'pattern' => '/^(baz)$/', ], ], ], [ 'key' => 'bar', 'value' => [ Loading @@ -148,6 +160,18 @@ public function providerGetDynamicPluginConfig(): array { [ 'name' => 'foo3', 'attributes' => [ [ 'key' => [ 'regexp' => [ 'pattern' => '/^bar-.*$/', ], ], 'value' => [ 'regexp' => [ 'pattern' => '/^(baz|qux-.*)$/', ], ], ], [ 'key' => 'bar', 'value' => [ Loading core/modules/filter/src/Plugin/Filter/FilterHtml.php +22 −4 Original line number Diff line number Diff line Loading @@ -266,12 +266,29 @@ public function getHTMLRestrictions() { continue; } $tag = $node->tagName; // All attributes are already allowed on this tag, this is the most // permissive configuration, no additional processing is required. if (isset($restrictions['allowed'][$tag]) && $restrictions['allowed'][$tag] === TRUE) { continue; } if ($node->hasAttributes()) { // Mark the tag as allowed, assigning TRUE for each attribute name if // all values are allowed, or an array of specific allowed values. // If the tag is not yet present, prepare to add attribute restrictions. // Otherwise, check if a more restrictive configuration (FALSE, meaning // no attributes were allowed) is present: then override the existing // value to prepare to add attribute restrictions. if (!isset($restrictions['allowed'][$tag]) || $restrictions['allowed'][$tag] === FALSE) { $restrictions['allowed'][$tag] = []; } // Iterate over any attributes, and mark them as allowed. foreach ($node->attributes as $name => $attribute) { // Only add specific attribute values if all values are not already // allowed. if (isset($restrictions['allowed'][$tag][$name]) && $restrictions['allowed'][$tag][$name] === TRUE) { continue; } // Put back any trailing * on wildcard attribute name. $name = str_replace($star_protector, '*', $name); Loading Loading @@ -302,7 +319,8 @@ public function getHTMLRestrictions() { } } } else { if (empty($restrictions['allowed'][$tag])) { // Mark the tag as allowed, but with no attributes allowed. $restrictions['allowed'][$tag] = FALSE; } Loading Loading
core/modules/ckeditor5/ckeditor5.ckeditor5.yml +2 −1 Original line number Diff line number Diff line Loading @@ -629,7 +629,8 @@ media_media: class: Drupal\ckeditor5\Plugin\CKEditor5Plugin\Media elements: - <drupal-media> - <drupal-media data-entity-type data-entity-uuid alt data-view-mode> - <drupal-media data-entity-type data-entity-uuid alt> - <drupal-media data-view-mode> conditions: filter: media_embed Loading
core/modules/ckeditor5/src/Plugin/CKEditor5Plugin/Media.php +3 −6 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; use Drupal\ckeditor5\Plugin\CKEditor5PluginDefinition; use Drupal\ckeditor5\HTMLRestrictions; /** * CKEditor 5 Media plugin. Loading Loading @@ -194,14 +193,12 @@ public function getDynamicPluginConfig(array $static_plugin_config, EditorInterf * {@inheritdoc} */ public function getElementsSubset(): array { $all_elements = $this->getPluginDefinition()->getElements(); $subset = HTMLRestrictions::fromString(implode($all_elements)); $subset = $this->getPluginDefinition()->getElements(); $view_mode_override_enabled = $this->getConfiguration()['allow_view_mode_override']; if (!$view_mode_override_enabled) { $subset = $subset->diff(HTMLRestrictions::fromString('<drupal-media data-view-mode>')); $subset = array_diff($subset, ['<drupal-media data-view-mode>']); } // @todo Simplify in https://www.drupal.org/project/drupal/issues/3278636, that will allow removing all uses of HTMLRestrictions in this class. return array_merge(['<drupal-media>'], $subset->toCKEditor5ElementsArray()); return $subset; } /** Loading
core/modules/ckeditor5/tests/src/Unit/HTMLRestrictionsTest.php +36 −2 Original line number Diff line number Diff line Loading @@ -302,6 +302,26 @@ public function providerConvenienceConstructors(): \Generator { '<ol type="I A 1">', ['ol' => ['type' => ['I' => TRUE, 'A' => TRUE, 1 => TRUE]]], ]; yield 'tag with two attributes, spread across declarations' => [ '<a target> <a class>', ['a' => ['target' => TRUE, 'class' => TRUE]], ]; yield 'tag with conflicting attribute config, allow one attribute and forbid all attributes' => [ '<a target> <a>', ['a' => ['target' => TRUE]], ]; yield 'tag with conflicting attribute config, allow one attribute and allow all attributes' => [ '<a *> <a target>', ['a' => TRUE], ]; yield 'tag attribute configuration spread across declarations' => [ '<a target="_blank"> <a target="_self"> <a target="_*">', ['a' => ['target' => ['_blank' => TRUE, '_self' => TRUE, '_*' => TRUE]]], ]; yield 'tag attribute configuration spread across declarations, allow all attributes values' => [ '<a target> <a target="_blank"> <a target="_self"> <a target="_*">', ['a' => ['target' => TRUE]], ]; // Multiple tag cases. yield 'two tags' => [ Loading @@ -309,8 +329,8 @@ public function providerConvenienceConstructors(): \Generator { ['a' => FALSE, 'p' => FALSE], ]; yield 'two tags (reverse order)' => [ '<a> <p>', ['a' => FALSE, 'p' => FALSE], '<p> <a>', ['p' => FALSE, 'a' => FALSE], ]; // Wildcard tag, attribute and attribute value. Loading @@ -328,6 +348,20 @@ public function providerConvenienceConstructors(): \Generator { ], ], ]; yield '$text-container, with attribute values spread across declarations' => [ '<$text-container class="text-align-left"> <$text-container class="text-align-center"> <$text-container class="text-align-right"> <$text-container class="text-align-justify">', [], [ '$text-container' => [ 'class' => [ 'text-align-left' => TRUE, 'text-align-center' => TRUE, 'text-align-right' => TRUE, 'text-align-justify' => TRUE, ], ], ], ]; yield '$text-container + one concrete tag to resolve into' => [ '<p> <$text-container class="text-align-left text-align-center text-align-right text-align-justify">', [ Loading
core/modules/ckeditor5/tests/src/Unit/SourceEditingPluginTest.php +24 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,18 @@ public function providerGetDynamicPluginConfig(): array { [ 'name' => 'foo2', 'attributes' => [ [ 'key' => [ 'regexp' => [ 'pattern' => '/^bar-.*$/', ], ], 'value' => [ 'regexp' => [ 'pattern' => '/^(baz)$/', ], ], ], [ 'key' => 'bar', 'value' => [ Loading @@ -148,6 +160,18 @@ public function providerGetDynamicPluginConfig(): array { [ 'name' => 'foo3', 'attributes' => [ [ 'key' => [ 'regexp' => [ 'pattern' => '/^bar-.*$/', ], ], 'value' => [ 'regexp' => [ 'pattern' => '/^(baz|qux-.*)$/', ], ], ], [ 'key' => 'bar', 'value' => [ Loading
core/modules/filter/src/Plugin/Filter/FilterHtml.php +22 −4 Original line number Diff line number Diff line Loading @@ -266,12 +266,29 @@ public function getHTMLRestrictions() { continue; } $tag = $node->tagName; // All attributes are already allowed on this tag, this is the most // permissive configuration, no additional processing is required. if (isset($restrictions['allowed'][$tag]) && $restrictions['allowed'][$tag] === TRUE) { continue; } if ($node->hasAttributes()) { // Mark the tag as allowed, assigning TRUE for each attribute name if // all values are allowed, or an array of specific allowed values. // If the tag is not yet present, prepare to add attribute restrictions. // Otherwise, check if a more restrictive configuration (FALSE, meaning // no attributes were allowed) is present: then override the existing // value to prepare to add attribute restrictions. if (!isset($restrictions['allowed'][$tag]) || $restrictions['allowed'][$tag] === FALSE) { $restrictions['allowed'][$tag] = []; } // Iterate over any attributes, and mark them as allowed. foreach ($node->attributes as $name => $attribute) { // Only add specific attribute values if all values are not already // allowed. if (isset($restrictions['allowed'][$tag][$name]) && $restrictions['allowed'][$tag][$name] === TRUE) { continue; } // Put back any trailing * on wildcard attribute name. $name = str_replace($star_protector, '*', $name); Loading Loading @@ -302,7 +319,8 @@ public function getHTMLRestrictions() { } } } else { if (empty($restrictions['allowed'][$tag])) { // Mark the tag as allowed, but with no attributes allowed. $restrictions['allowed'][$tag] = FALSE; } Loading