You are here

private static function StyleSensibleElementConstraintValidator::intersectionWithClasses in Drupal 10

Checks if there is an intersection on allowed 'class' attribute values.

Parameters

\Drupal\ckeditor5\HTMLRestrictions $a: One set of HTML restrictions.

\Drupal\ckeditor5\HTMLRestrictions $b: Another set of HTML restrictions.

Return value

bool Whether there is an intersection.

2 calls to StyleSensibleElementConstraintValidator::intersectionWithClasses()
StyleSensibleElementConstraintValidator::findStyleConflictingPluginLabel in core/modules/ckeditor5/src/Plugin/Validation/Constraint/StyleSensibleElementConstraintValidator.php
Finds the plugin with elements that conflict with the style element.
StyleSensibleElementConstraintValidator::validate in core/modules/ckeditor5/src/Plugin/Validation/Constraint/StyleSensibleElementConstraintValidator.php

File

core/modules/ckeditor5/src/Plugin/Validation/Constraint/StyleSensibleElementConstraintValidator.php, line 99

Class

StyleSensibleElementConstraintValidator
Styles can only be specified for HTML5 tags and extra classes.

Namespace

Drupal\ckeditor5\Plugin\Validation\Constraint

Code

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.
    if (!empty($config['class']) && $config['class'] === TRUE) {
      unset($b_without_class_wildcard[$allowedElement]['class']);
    }

    // HTMLRestrictions does not accept a tag with an empty array, make sure
    // to remove them here.
    if (empty($b_without_class_wildcard[$allowedElement])) {
      unset($b_without_class_wildcard[$allowedElement]);
    }
  }
  $intersection = $a
    ->intersect(new HTMLRestrictions($b_without_class_wildcard));

  // Leverage the "GHS configuration" representation to easily find whether
  // there is an intersection for classes. Other implementations are possible.
  $intersection_as_ghs_config = $intersection
    ->toGeneralHtmlSupportConfig();
  $ghs_config_classes = array_column($intersection_as_ghs_config, 'classes');
  return !empty($ghs_config_classes);
}