private static function intersectionWithClasses(HTMLRestrictions
$a, HTMLRestrictions
$b): bool
{ // Compute the intersection, but first resolve wildcards, by merging
// tags of the other operand. Because only tags are merged, this cannot
// introduce a 'class' attribute intersection.
// For example: a plugin may support `<$text-container class="foo">`. On its
// own that would not trigger an intersection, but when resolved into
// concrete tags it could.
$tags_from_a =
array_diff(array_keys($a->
getConcreteSubset()->
getAllowedElements()),
['*'
]);
$tags_from_b =
array_diff(array_keys($b->
getConcreteSubset()->
getAllowedElements()),
['*'
]);
$a =
$a->
merge(new HTMLRestrictions(array_fill_keys($tags_from_b, FALSE
)));
$b =
$b->
merge(new HTMLRestrictions(array_fill_keys($tags_from_a, FALSE
)));
// When a plugin allows all classes on a tag, we assume there is no
// problem with having the style plugin adding classes to that element.
// When allowing all classes we don't expect a specific user experience
// so adding a class through a plugin or the style plugin is the same.
$b_without_class_wildcard =
$b->
getAllowedElements();
foreach ($b_without_class_wildcard as $allowedElement =>
$config) { // When all classes are allowed, remove the configuration so that
// the intersect below does not include classes.