View source
<?php
namespace Drupal\filter\Plugin\Filter;
use Drupal\Component\Utility\Html;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\filter\FilterPluginManager;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\filter\Render\FilteredMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
class FilterCaption extends FilterBase implements ContainerFactoryPluginInterface {
protected $filterManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, FilterPluginManager $filter_manager = NULL) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->filterManager = $filter_manager ?: \Drupal::service('plugin.manager.filter');
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('plugin.manager.filter'));
}
public function process($text, $langcode) {
$result = new FilterProcessResult($text);
if (stristr($text, 'data-caption') !== FALSE) {
$dom = Html::load($text);
$xpath = new \DOMXPath($dom);
$html_filter = $this->filterManager
->createInstance('filter_html', [
'settings' => [
'allowed_html' => '<a href hreflang target rel> <em> <strong> <cite> <code> <br>',
'filter_html_help' => FALSE,
'filter_html_nofollow' => FALSE,
],
]);
foreach ($xpath
->query('//*[@data-caption]') as $node) {
$caption = Html::escape($node
->getAttribute('data-caption'));
$node
->removeAttribute('data-caption');
$caption = Html::decodeEntities($caption);
$raw_caption = $caption;
$filtered_caption = $html_filter
->process($caption, $langcode);
$result
->addCacheableDependency($filtered_caption);
$caption = FilteredMarkup::create($filtered_caption
->getProcessedText());
if (mb_strlen($caption) === 0 && $raw_caption !== ' ') {
continue;
}
$tag = $node->tagName;
$classes = $node
->getAttribute('class');
$node
->removeAttribute('class');
$node = $node->parentNode->tagName === 'a' ? $node->parentNode : $node;
$filter_caption = [
'#theme' => 'filter_caption',
'#node' => FilteredMarkup::create($node
->C14N()),
'#tag' => $tag,
'#caption' => $caption,
'#classes' => $classes,
];
$altered_html = \Drupal::service('renderer')
->render($filter_caption);
$updated_nodes = Html::load($altered_html)
->getElementsByTagName('body')
->item(0)->childNodes;
foreach ($updated_nodes as $updated_node) {
$updated_node = $dom
->importNode($updated_node, TRUE);
$node->parentNode
->insertBefore($updated_node, $node);
}
$node->parentNode
->removeChild($node);
}
$result
->setProcessedText(Html::serialize($dom))
->addAttachments([
'library' => [
'filter/caption',
],
]);
}
return $result;
}
public function tips($long = FALSE) {
if ($long) {
return $this
->t('
<p>You can caption images, videos, blockquotes, and so on. Examples:</p>
<ul>
<li><code><img src="" data-caption="This is a caption" /></code></li>
<li><code><video src="" data-caption="The Drupal Dance" /></code></li>
<li><code><blockquote data-caption="Dries Buytaert">Drupal is awesome!</blockquote></code></li>
<li><code><code data-caption="Hello world in JavaScript.">alert("Hello world!");</code></code></li>
</ul>');
}
else {
return $this
->t('You can caption images (<code>data-caption="Text"</code>), but also videos, blockquotes, and so on.');
}
}
}