intersect example


      // Map any expected 'a' or 'b' string value to the corresponding operand.       if ($$parameter === 'a') {
        $$parameter = $a;
      }
      elseif ($$parameter === 'b') {
        $$parameter = $b;
      }
      assert($$parameter instanceof HTMLRestrictions);
    }
    $this->assertEquals($expected_diff$a->diff($b));
    $this->assertEquals($expected_intersection$a->intersect($b));
    $this->assertEquals($expected_union$a->merge($b));
  }

  public function providerOperands(): \Generator {
    // Empty set operand cases.     yield 'any set + empty set' => [
      'a' => new HTMLRestrictions(['a' => ['href' => TRUE]]),
      'b' => HTMLRestrictions::emptySet(),
      'diff' => 'a',
      'intersection' => 'b',
      'union' => 'a',
    ];
        // to avoid push freshly deleted translations.         $providerReadTranslatorBag = new TranslatorBag();
        $providerReadTranslatorBag->addCatalogue($arrayLoader->load(['note' => 'NOTE'], 'en'));
        $providerReadTranslatorBag->addCatalogue($arrayLoader->load(['note' => 'NOTE'], 'fr'));

        $provider->expects($this->any())
            ->method('read')
            ->with($domains$locales)
            ->willReturn($providerReadTranslatorBag);

        $translationBagToWrite = $localTranslatorBag->diff($providerReadTranslatorBag);
        $translationBagToWrite->addBag($localTranslatorBag->intersect($providerReadTranslatorBag));

        $provider->expects($this->once())
            ->method('write')
            ->with($translationBagToWrite);

        $provider->expects($this->exactly(2))
            ->method('__toString')
            ->willReturn('null://default');

        $tester = $this->createCommandTester($provider$locales$domains);

        
$io->success(sprintf('Missing translations on "%s" has been deleted (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME)implode(', ', $locales)implode(', ', $domains)));

            // Read provider translations again, after missing translations deletion,             // to avoid push freshly deleted translations.             $providerTranslations = $provider->read($domains$locales);
        }

        $translationsToWrite = $localTranslations->diff($providerTranslations);

        if ($force) {
            $translationsToWrite->addBag($localTranslations->intersect($providerTranslations));
        }

        $provider->write($translationsToWrite);

        $io->success(sprintf('%s local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', $force ? 'All' : 'New', parse_url($provider, \PHP_URL_SCHEME)implode(', ', $locales)implode(', ', $domains)));

        return 0;
    }

    private function getDomainsFromTranslatorBag(TranslatorBag $translatorBag): array
    {
        
    // ::intersect() to detect a conflict.     $conflicting_restrictions = new self(array_fill_keys(
      array_keys($elements_with_attribute_level_restrictions),
      // The disallowed attributes converted to allowed, to allow using the       // ::intersect() method to detect a conflict.       // In the example: `['style' => TRUE', 'bar' => TRUE]`.       array_fill_keys(array_keys($globally_disallowed_attribute_restrictions), TRUE)
    ));

    // When there is a non-empty intersection at the attribute level, an     // override of a globally disallowed attribute was found.     $conflict = $potentially_overriding->intersect($conflicting_restrictions);
    $elements_overriding_globally_disallowed_attributes = array_filter($conflict->getAllowedElements());

    // No conflict found.     if (empty($elements_overriding_globally_disallowed_attributes)) {
      return NULL;
    }

    return [$globally_disallowed_attribute_restrictions$elements_overriding_globally_disallowed_attributes];
  }

  /** * Creates the empty set of HTML restrictions: nothing is allowed. * * @return \Drupal\ckeditor5\HTMLRestrictions */
$needed_tags = $tags_and_attributes->extractPlainTagsSubset();
    $non_creatable_tags = $needed_tags->diff($creatable_tags);
    if (!$non_creatable_tags->allowsNothing()) {
      foreach ($non_creatable_tags->toCKEditor5ElementsArray() as $non_creatable_tag) {
        // Find the plugin which has a non-creatable tag.         $needle = HTMLRestrictions::fromString($non_creatable_tag);
        $matching_plugins = array_filter($enabled_definitionsfunction DCKEditor5PluginDefinition $d) use ($needle$text_editor) {
          if (!$d->hasElements()) {
            return FALSE;
          }
          $haystack = new HTMLRestrictions($this->pluginManager->getProvidedElements([$d->id()]$text_editor, FALSE, FALSE));
          return !$haystack->extractPlainTagsSubset()->intersect($needle)->allowsNothing();
        });
        assert(count($matching_plugins) === 1);
        $plugin_definition = reset($matching_plugins);
        assert($plugin_definition instanceof CKEditor5PluginDefinition);

        // Compute which attributes it would be able to create on this tag.         $provided_elements = new HTMLRestrictions($this->pluginManager->getProvidedElements([$plugin_definition->id()]$text_editor, FALSE, FALSE));
        $attributes_on_tag = $provided_elements->intersect(
          new HTMLRestrictions(array_fill_keys(array_keys($needle->getAllowedElements()), TRUE))
        );

        

        $catalogueA = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo', 'bar' => 'bar'], 'domain2' => ['baz' => 'baz', 'qux' => 'qux']]);

        $bagA = new TranslatorBag();
        $bagA->addCatalogue($catalogueA);

        $catalogueB = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo', 'baz' => 'baz'], 'domain2' => ['baz' => 'baz', 'corge' => 'corge']]);

        $bagB = new TranslatorBag();
        $bagB->addCatalogue($catalogueB);

        $bagResult = $bagA->intersect($bagB);

        $this->assertEquals([
            'en' => [
                'domain1' => ['foo' => 'foo'],
                'domain2' => ['baz' => 'baz'],
            ],
        ]$this->getAllMessagesFromTranslatorBag($bagResult));
    }

    private function getAllMessagesFromTranslatorBag(TranslatorBag $translatorBag): array
    {
        
    // purposes of this validator, HTML restrictions containing only wildcards     // should be considered empty.     // @todo Remove this early return in     // https://www.drupal.org/project/drupal/issues/2820364. It is only     // necessary because CKEditor5ElementConstraintValidator does not run     // before this, which means that this validator cannot assume it receives     // valid values.     if (count($source_enabled_element->getAllowedElements()) !== 1) {
      return;
    }

    $enabled_plugin_overlap = $enabled_plugin_elements->intersect($source_enabled_element);
    $disabled_plugin_overlap = $disabled_plugin_elements
      // Merge the enabled plugins' elements, to allow wildcards to be resolved.       ->merge($enabled_plugin_elements)
      // Compute the overlap.       ->intersect($source_enabled_element)
      // Exclude the enabled plugin tags from the overlap; we merged these       // previously to be able to resolve wildcards.       ->diff($enabled_plugin_overlap);
    foreach ([$enabled_plugin_overlap$disabled_plugin_overlap] as $overlap) {
      $checking_enabled = $overlap === $enabled_plugin_overlap;
      if (!$overlap->allowsNothing()) {
        

  private static function computeNetNewElementsForPlugin(HTMLRestrictions $baseline, HTMLRestrictions $needed, CKEditor5PluginDefinition $added_plugin): array {
    $plugin_support = HTMLRestrictions::fromString(implode(' ', $added_plugin->getElements()));
    // Do not inspect just $plugin_support, but the union of that with the     // already supported elements: wildcard restrictions will only resolve     // if the concrete tags they support are also present.     $potential_future = $baseline->merge($plugin_support);
    // This is the heart of the operation: intersect the potential future     // with what we need to achieve, then subtract what is already     // supported. This yields the net new elements.     $net_new = $potential_future->intersect($needed)->diff($baseline);
    // But … we may compute too many.     $surplus_additions = $potential_future->diff($needed)->diff($baseline);
    return [$net_new$surplus_additions];
  }

  /** * Computes a score for the given surplus compared to the given need. * * @param \Drupal\ckeditor5\HTMLRestrictions $surplus * A surplus compared to what is needed. * @param \Drupal\ckeditor5\HTMLRestrictions $needed * Exactly what is needed. * * @return int * A surplus score. Lower is better. Scores are a positive integer. * * @see https://www.drupal.org/project/drupal/issues/3231328#comment-14444987 */
// 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);
  }

  /** * Finds the plugin with elements that conflict with the style element. * * @param \Drupal\ckeditor5\HTMLRestrictions $needle * A style definition element: a single tag, plus the 'class' attribute, * plus >=1 allowed 'class' attribute values. * * @return \Drupal\Core\StringTranslation\TranslatableMarkup * The label of the plugin that is conflicting with this style. * * @throws \OutOfBoundsException * When a $needle is provided which does not exist among the other plugins. */
else {
              throw new \LogicException(sprintf('The "%s" CKEditor 5 plugin implements ::getElementsSubset() and did not return a subset, the following tags are absent from the plugin definition: "%s".', $idimplode(' ', $not_in_max_supported->toCKEditor5ElementsArray())));
            }
          }

          // Also detect what is technically a valid subset, but has lost the           // ability to create tags that are still in the subset. This points to           // a bug in the plugin's ::getElementsSubset() logic.           $defined_creatable = HTMLRestrictions::fromString(implode($definition->getCreatableElements()));
          $subset_creatable_actual = HTMLRestrictions::fromString(implode(array_filter($subset[CKEditor5PluginDefinition::class, 'isCreatableElement'])));
          $subset_creatable_needed = $subset_restrictions->extractPlainTagsSubset()
            ->intersect($defined_creatable);
          $missing_creatable_for_subset = $subset_creatable_needed->diff($subset_creatable_actual);
          if (!$missing_creatable_for_subset->allowsNothing()) {
            throw new \LogicException(sprintf('The "%s" CKEditor 5 plugin implements ::getElementsSubset() and did return a subset ("%s") but the following tags can no longer be created: "%s".', $idimplode($subset_restrictions->toCKEditor5ElementsArray())implode($missing_creatable_for_subset->toCKEditor5ElementsArray())));
          }

          $defined_elements = $subset;
        }
      }
      assert(Inspector::assertAllStrings($defined_elements));
      if ($creatable_elements_only) {
        // @see \Drupal\ckeditor5\Plugin\CKEditor5PluginDefinition::getCreatableElements()
Home | Imprint | This part of the site doesn't use cookies.