View source
<?php
namespace Drupal\responsive_tables_filter\Plugin\Filter;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\Core\Form\FormStateInterface;
class FilterResponsiveTablesFilter extends FilterBase {
public static $modes = [
'stack' => "Stack Mode",
'columntoggle' => "Column Toggle Mode",
'swipe' => "Swipe Mode",
];
public function process($text, $langcode) {
if ($filtered = $this
->runFilter($text)) {
$result = new FilterProcessResult($filtered);
$result
->setAttachments([
'library' => [
'responsive_tables_filter/tablesaw-filter',
],
]);
}
else {
$result = new FilterProcessResult($text);
}
return $result;
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$form['tablesaw_type'] = [
'#type' => 'select',
'#title' => $this
->t('Default mode'),
'#default_value' => $this->settings['tablesaw_type'] ?? 'stack',
'#description' => $this
->t('This will apply by default to tables in WYSIWYGs, but can be overridden on an individual basis by adding the <code>class</code> "tablesaw-stack", "tablesaw-columntoggle", or "tablesaw-swipe" to the <code>table</code> tag. See documentation: https://github.com/filamentgroup/tablesaw'),
'#options' => self::$modes,
];
$form['tablesaw_persist'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Persistent first column?'),
'#default_value' => $this->settings['tablesaw_persist'] ?? TRUE,
'#description' => $this
->t('This will apply to all tables in WYSIWYGs.'),
];
return $form;
}
public function runFilter($text) {
static $new_libxml;
if (!isset($new_libxml)) {
$new_libxml = version_compare(PHP_VERSION, '5.4', '>=') && defined('LIBXML_HTML_NOIMPLIED') && defined('LIBXML_HTML_NODEFDTD');
}
if ($text != '') {
$tables = [];
libxml_use_internal_errors(TRUE);
$text = '<root>' . $text . '</root>';
$dom = new \DOMDocument();
if ($new_libxml) {
$dom
->loadHTML(mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
}
else {
$dom
->loadHTML(mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'));
}
$tables = $dom
->getElementsByTagName('table');
if ($tables->length !== 0) {
foreach ($tables as $table) {
$existing_classes = $table
->getAttribute('class');
if (strpos($existing_classes, 'no-tablesaw') === FALSE) {
$mode = $this->settings['tablesaw_type'] ?? 'stack';
foreach (array_keys(self::$modes) as $mode_option) {
if (strpos($existing_classes, "tablesaw-" . $mode_option) !== FALSE) {
$mode = $mode_option;
break;
}
}
$new_classes = !empty($existing_classes) ? $existing_classes . ' tablesaw tablesaw-' . $mode : 'tablesaw tablesaw-' . $mode;
$table
->setAttribute('class', $new_classes);
$table
->setAttribute('data-tablesaw-mode', $mode);
$table
->setAttribute('data-tablesaw-minimap', NULL);
$persist = $this->settings['tablesaw_persist'] ?? TRUE;
$ths = $table
->getElementsByTagName('th');
$inc = 1;
foreach ($ths as $delta => $th) {
if (in_array($mode, [
'columntoggle',
'swipe',
])) {
$th
->setAttribute('data-tablesaw-sortable-col', '');
if (!$th
->getAttribute('data-tablesaw-priority')) {
$th
->setAttribute('data-tablesaw-priority', $inc);
$inc++;
}
}
if ($persist && $delta === 0 && !$th
->getAttribute('data-tablesaw-priority')) {
$th
->setAttribute('data-tablesaw-priority', 'persist');
}
}
}
}
$html = "";
foreach ($dom
->getElementsByTagName('root')
->item(0)->childNodes as $child) {
$html .= $dom
->saveHTML($child);
}
if (!$new_libxml) {
$html_start = strpos($html, '<html><body>') + 12;
$html_length = strpos($html, '</body></html>') - $html_start;
$html = substr($html, $html_start, $html_length);
}
return $html;
}
}
return FALSE;
}
}