progressive_image_loading-8.x-1.x-dev/src/Plugin/Filter/ProgressiveImageLoadingFilter.php
src/Plugin/Filter/ProgressiveImageLoadingFilter.php
<?php
namespace Drupal\progressive_image_loading\Plugin\Filter;
use Drupal\Component\Utility\Html as HtmlUtility;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\progressive_image_loading\ProgressiveImageLoadingManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a filter to attach the libraries for this module.
*
* @Filter(
* id = "progressive_image_loading",
* title = @Translation("Progressive Image Loading"),
* description = @Translation("Loads progressively all the images and iframes."),
* type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE
* )
*/
class ProgressiveImageLoadingFilter extends FilterBase implements ContainerFactoryPluginInterface {
/**
* The Progressive Image Loading manager.
*
* @var \Drupal\progressive_image_loading\ProgressiveImageLoadingManagerInterface
*/
protected $manager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = new static($configuration, $plugin_id, $plugin_definition);
$instance->setManager($container->get('progressive_image_loading.manager'));
return $instance;
}
/**
* {@inheritdoc}
*/
public function process($text, $langcode) {
$result = new FilterProcessResult($text);
if (!$this->manager->currentPathIsExcluded()) {
$dom = HtmlUtility::load($text);
$xpath = new \DOMXPath($dom);
$enabled = $xpath->query('//*[contains(@class, "progressive-image-loading")]')->length +
$xpath->query('//*[@data-toggle-class]')->length;
$images = $xpath->query('//img');
if ($images->length) {
/** @var \DOMElement[] $images */
foreach ($images as $image) {
$classes = $image->getAttribute('class');
if (strpos($classes, 'progressive-image-loading-disabled') === FALSE) {
$image->setAttribute('class', trim('progressive-image-loading ' . $classes));
if ($image->hasAttribute('srcset')) {
$image->setAttribute('data-srcset', $image->getAttribute('srcset'));
$image->removeAttribute('srcset');
}
// Generate a LQIP image.
$url = $image->getAttribute('src');
$width = $image->getAttribute('width') ?? 1;
$height = $image->getAttribute('height') ?? 1;
$placeholder = $this->manager->createPlaceholder($url, $width, $height);
// Only use this attribute if the placeholder is different.
if ($url != $placeholder) {
$image->setAttribute('data-src', $url);
}
$image->setAttribute('src', $placeholder);
$enabled++;
}
}
}
$backgrounds = $xpath->query('//*[@data-background-image]');
if ($backgrounds->length) {
/** @var \DOMElement[] $backgrounds */
foreach ($backgrounds as $background) {
$classes = $background->getAttribute('class');
if (strpos($classes, 'progressive-image-loading-disabled') === FALSE) {
$background->setAttribute('class', trim('progressive-image-loading ' . $classes));
// Generate a LQIP image.
$url = $background->getAttribute('data-background-image');
$placeholder = $this->manager->createPlaceholder($url);
// Only use this attribute if the placeholder is different.
if ($url != $placeholder) {
$style = 'background-image: url("' . $placeholder . '")' . $background->getAttribute('style');
$background->setAttribute('style', $style);
}
$enabled++;
}
}
}
$iframes = $xpath->query('//iframe');
if ($iframes->length) {
/** @var \DOMElement[] $iframes */
foreach ($iframes as $iframe) {
$classes = $iframe->getAttribute('class');
if (strpos($classes, 'progressive-image-loading-disabled') === FALSE) {
$iframe->setAttribute('class', trim('progressive-image-loading ' . $classes));
$iframe->setAttribute('data-src', $iframe->getAttribute('src'));
$iframe->removeAttribute('src');
$enabled++;
}
}
}
if ($images->length || $backgrounds->length || $iframes->length) {
$result->setProcessedText(HtmlUtility::serialize($dom));
}
if ($enabled) {
$result->addAttachments([
'library' => [
'progressive_image_loading/library',
],
]);
}
}
return $result;
}
/**
* {@inheritdoc}
*/
public function tips($long = FALSE) {
return $this->t('
<p>You can disable progressive image loading adding (<code>class="progressive-image-loading-disabled"</code>) to yours images or iframes.</p>
<p>You can disable progressive image loading blur effect adding (<code>class="progressive-image-loading-disable-blur"</code>) to yours images or iframes.</p>
<p>You can add progressive background image loading. Example: <code><div data-background-image=""> </div></code></p>
');
}
/**
* Sets the Progressive Image Loading manager for this filter.
*
* @param \Drupal\progressive_image_loading\ProgressiveImageLoadingManagerInterface $manager
* The Progressive Image Loading manager.
*
* @return $this
*/
protected function setManager(ProgressiveImageLoadingManagerInterface $manager) {
$this->manager = $manager;
return $this;
}
}
