openeuropa / oe_bootstrap_theme

Bootstrap-based theme
European Union Public License 1.2
6 stars 13 forks source link

Consider adding utility class for DOM manipulation methods #333

Closed kp77 closed 4 months ago

kp77 commented 1 year ago

In the BootstrapTable filter plugin, there is a public method for adding a class to a DOM element. It solves the issue to only add the class if it doesn't exist and keeps the existing classes on the element.

We also need to create our own filter plugins, and similar method(s) would be helpful when dealing with classes of elements. Although the method is public, it's not really reusable like this (the plugin class is final, but it would also not make sense to extend it by another filter that has a different purpose).

I created a utility class in our project that does something similar (and added some other methods, also it's working with multiple classes at once). Would you consider including it in the base theme, so that other projects can use it if needed? Here's the code as it is now:

<?php

declare(strict_types=1);

namespace Ucpkn;

/**
 * Utility class for DOM manipulation methods.
 *
 * This is meant for useful methods that are not found in 3rd party packages,
 * and that do not depend on anything in Drupal.
 */
class DomUtil {

  /**
   * Returns an array of classes of a DOM element.
   *
   * @param \DOMElement $element
   *   The DOM element.
   *
   * @return array
   *   An array of classes.
   */
  public static function getElementClasses(\DOMElement $element): array {
    return self::parseClasses($element->getAttribute('class'));
  }

  /**
   * Adds classes to a DOM element.
   *
   * @param \DOMElement $element
   *   The DOM element.
   * @param string $classes
   *   Classes to add, separated by space.
   */
  public static function addElementClasses(\DOMElement $element, string $classes): void {
    $class = array_unique(array_merge(self::getElementClasses($element), self::parseClasses($classes)));
    $element->setAttribute('class', implode(' ', $class));
  }

  /**
   * Removes classes from a DOM element.
   *
   * @param \DOMElement $element
   *   The DOM element.
   * @param string $classes
   *   Classes to remove, separated by space.
   */
  public static function removeElementClasses(\DOMElement $element, string $classes): void {
    $class = array_diff(self::getElementClasses($element), self::parseClasses($classes));
    $element->setAttribute('class', implode(' ', $class));
  }

  /**
   * Parses a string of classes into an array.
   *
   * @param string $classes
   *   The string of classes.
   *
   * @return array
   *   An array of classes.
   */
  private static function parseClasses(string $classes): array {
    return array_filter(array_map('trim', explode(' ', $classes)));
  }

}
brummbar commented 4 months ago

Such a class belongs to a PHP library and not in a Drupal theme. Similar libraries already exists, such as https://github.com/Rct567/DomQuery .