You are here

public function LazyFilter::process in Lazy-load 8.3

Same name and namespace in other branches
  1. 8 src/Plugin/Filter/LazyFilter.php \Drupal\lazy\Plugin\Filter\LazyFilter::process()
  2. 8.2 src/Plugin/Filter/LazyFilter.php \Drupal\lazy\Plugin\Filter\LazyFilter::process()

Performs the filter processing.

Parameters

string $text: The text string to be filtered.

string $langcode: The language code of the text to be filtered.

Return value

\Drupal\filter\FilterProcessResult The filtered text, wrapped in a FilterProcessResult object, and possibly with associated assets, cacheability metadata and placeholders.

Overrides FilterInterface::process

See also

\Drupal\filter\FilterProcessResult

File

src/Plugin/Filter/LazyFilter.php, line 123

Class

LazyFilter
Provides a filter to lazy-load images.

Namespace

Drupal\lazy\Plugin\Filter

Code

public function process($text, $langcode) : FilterProcessResult {
  $result = new FilterProcessResult($text);
  if ($this->status && ($this->settings['image'] || $this->settings['iframe']) && $this->lazyLoad
    ->isPathAllowed() && ($lazy_settings = $this->configFactory
    ->get('lazy.settings')
    ->get())) {
    $html_dom = Html::load($text);
    $xpath = new \DOMXPath($html_dom);

    /** @var \DOMElement $node */
    foreach ($xpath
      ->query('//img | //iframe') as $node) {
      $classes = empty($node
        ->getAttribute('class')) ? [] : explode(' ', $node
        ->getAttribute('class'));
      $parent_classes = empty($node->parentNode
        ->getAttribute('class')) ? [] : explode(' ', $node->parentNode
        ->getAttribute('class'));

      // Get original source value.
      $src = $node
        ->getAttribute('src');

      // Check which tags are enabled in text-format settings.
      $enabled_tags = [
        'img' => $this->settings['image'],
        'iframe' => $this->settings['iframe'],
      ];
      foreach ($enabled_tags as $tag => $status) {

        // Act only on the elements that are enabled under "Lazy-load images
        // and iframes" in filter settings.
        if ($node->tagName === $tag && $enabled_tags[$node->tagName]) {

          // Check if the element, or its parent has a skip class.
          if (in_array($lazy_settings['skipClass'], $classes, TRUE) || in_array($lazy_settings['skipClass'], $parent_classes, TRUE)) {

            // Leave this node unchanged.
            continue;
          }
          if ($lazy_settings['preferNative']) {

            // Set required attribute `loading="lazy"`.
            $node
              ->setAttribute('loading', 'lazy');
          }
          else {

            // Add Lazysizes selector class name to element attributes.
            $classes[] = $lazy_settings['lazysizes']['lazyClass'];
            $classes = array_unique($classes);
            $node
              ->setAttribute('class', implode(' ', $classes));

            // Change source attribute from `src` to `data-src`, or whatever
            // is defined in Lazysizes configuration for `srcAttr` at
            // /admin/config/content/lazy.
            $opt_src = $lazy_settings['lazysizes']['srcAttr'] !== 'src' ? $lazy_settings['lazysizes']['srcAttr'] : 'data-filterlazy-src';
            $node
              ->removeAttribute('src');
            $node
              ->setAttribute($opt_src, $src);

            // If the default placeholder defined, it would be used in `src`
            // attribute.
            if ($lazy_settings['placeholderSrc']) {
              $node
                ->setAttribute('src', $lazy_settings['placeholderSrc']);
            }
          }
        }
      }
    }
    $result
      ->setProcessedText(Html::serialize($html_dom));
  }
  return $result;
}