Issue #3278636 by nod_, Wim Leers, mrinalini9, bnjmnm: HTMLRestrictions::fromString() bug: multiple occurrences of same tag results in only last one being respected
(cherry picked from commit f7ef84514c
)
merge-requests/2643/merge
parent
fe19730b23
commit
3682bd2927
|
@ -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
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ use Drupal\media\Entity\MediaType;
|
|||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
|
||||
use Drupal\ckeditor5\Plugin\CKEditor5PluginDefinition;
|
||||
use Drupal\ckeditor5\HTMLRestrictions;
|
||||
|
||||
/**
|
||||
* CKEditor 5 Media plugin.
|
||||
|
@ -194,14 +193,12 @@ class Media extends CKEditor5PluginDefault implements ContainerFactoryPluginInte
|
|||
* {@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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -302,6 +302,26 @@ class HTMLRestrictionsTest extends UnitTestCase {
|
|||
'<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' => [
|
||||
|
@ -309,8 +329,8 @@ class HTMLRestrictionsTest extends UnitTestCase {
|
|||
['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.
|
||||
|
@ -328,6 +348,20 @@ class HTMLRestrictionsTest extends UnitTestCase {
|
|||
],
|
||||
],
|
||||
];
|
||||
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">',
|
||||
[
|
||||
|
|
|
@ -135,6 +135,18 @@ class SourceEditingPluginTest extends UnitTestCase {
|
|||
[
|
||||
'name' => 'foo2',
|
||||
'attributes' => [
|
||||
[
|
||||
'key' => [
|
||||
'regexp' => [
|
||||
'pattern' => '/^bar-.*$/',
|
||||
],
|
||||
],
|
||||
'value' => [
|
||||
'regexp' => [
|
||||
'pattern' => '/^(baz)$/',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'key' => 'bar',
|
||||
'value' => [
|
||||
|
@ -148,6 +160,18 @@ class SourceEditingPluginTest extends UnitTestCase {
|
|||
[
|
||||
'name' => 'foo3',
|
||||
'attributes' => [
|
||||
[
|
||||
'key' => [
|
||||
'regexp' => [
|
||||
'pattern' => '/^bar-.*$/',
|
||||
],
|
||||
],
|
||||
'value' => [
|
||||
'regexp' => [
|
||||
'pattern' => '/^(baz|qux-.*)$/',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'key' => 'bar',
|
||||
'value' => [
|
||||
|
|
|
@ -266,12 +266,29 @@ class FilterHtml extends FilterBase {
|
|||
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.
|
||||
$restrictions['allowed'][$tag] = [];
|
||||
// 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);
|
||||
|
||||
|
@ -302,7 +319,8 @@ class FilterHtml extends FilterBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (empty($restrictions['allowed'][$tag])) {
|
||||
// Mark the tag as allowed, but with no attributes allowed.
|
||||
$restrictions['allowed'][$tag] = FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue