View source
<?php
namespace Drupal\jquery_ui_filter\Plugin\Filter;
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
class jQueryUiFilter extends FilterBase {
public static $widgets = [
'accordion' => [
'title' => 'Accordion',
'api' => 'https://api.jqueryui.com/accordion/',
'options' => [
'headerTag' => 'h3',
'mediaType' => 'screen',
'scrollTo' => TRUE,
'scrollToDuration' => 500,
'scrollToOffset' => 'auto',
],
],
'tabs' => [
'title' => 'Tabs',
'api' => 'https://api.jqueryui.com/tabs/',
'options' => [
'headerTag' => 'h3',
'mediaType' => 'screen',
'scrollTo' => TRUE,
'scrollToDuration' => 500,
'scrollToOffset' => 'auto',
],
],
];
public function process($text, $langcode) {
$result = new FilterProcessResult($text);
$has_widget = FALSE;
foreach (self::$widgets as $name => $widget) {
if (strpos($text, '[' . $name) === FALSE) {
continue;
}
$has_widget = TRUE;
$text = preg_replace('#<(p|div)[^>]*>\\s*(\\[/?' . $name . '[^]]*\\])\\s*</\\1>#', '\\2', $text);
$text = preg_replace_callback('#\\[' . $name . '([^]]*)?\\]#is', function ($match) use ($name) {
$attributes = new Attribute([
'data-ui-role' => $name,
]);
$options = $this
->parseOptions($match[1]);
foreach ($options as $name => $value) {
$attributes
->setAttribute('data-ui-' . $name, $value);
}
return "<div{$attributes}>";
}, $text);
$text = str_replace('[/' . $name . ']', '</div>', $text);
}
if ($has_widget) {
$result
->setAttachments([
'library' => [
'jquery_ui_filter/jquery_ui_filter',
],
'drupalSettings' => [
'jquery_ui_filter' => \Drupal::config('jquery_ui_filter.settings')
->get(),
],
]);
$result
->addCacheableDependency(\Drupal::config('jquery_ui_filter.settings'));
}
return $result
->setProcessedText($text);
}
public function tips($long = FALSE) {
if ($long) {
$html = '<p>' . $this
->t('You can create jQuery UI accordion or tabs by inserting <code>[accordion]</code> or <code>[tabs]</code> wrappers. Examples:') . '</p>';
$html .= '<ul>';
foreach (self::$widgets as $name => $widget) {
$t_args = [
'@title' => $widget['title'],
'@name' => $name,
'@tag' => \Drupal::config('jquery_ui_filter.settings')
->get($name . '.options.headerTag') ?: 'h3',
'@href' => "http://jqueryui.com/demos/{$name}/",
];
$html .= '<li>' . $this
->t('Use <code>[@name]</code> and <code>[/@name]</code> with <code><@tag></code> header tags to create a jQuery UI <a href="@href">@title</a> widget.', $t_args) . '</li>';
}
$html .= '</ul>';
return $html;
}
else {
return '<p>' . $this
->t('You can create jQuery UI accordion or tabs by inserting <code>[accordion]</code> or <code>[tabs]</code> token wrappers.') . '</p>';
}
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$form['settings'] = [
'#markup' => $this
->t('See the <a href="@href">jQuery UI filter</a> settings form to modify the accordion and tabs widget\'s global settings', [
'@href' => Url::fromRoute('jquery_ui_filter.settings')
->toString(),
]),
];
return $form;
}
public function parseOptions($text) {
$text = html_entity_decode($text);
$text = str_replace("", ' ', $text);
$text = strtolower(preg_replace('/([a-z])([A-Z])/', '\\1-\\2', $text));
$html = Html::load('<div ' . $text . ' />');
$dom_node = $html
->getElementsByTagName('div')
->item(0);
$options = [];
foreach ($dom_node->attributes as $attribute_name => $attribute_node) {
$options[$attribute_name] = $attribute_node->nodeValue ?: 'true';
}
return $options;
}
}