Skip to content

Commit

Permalink
Merge pull request #1204 from openeuropa/update-EPIC-EWPP-2575
Browse files Browse the repository at this point in the history
EWPP-2575: Update Calendar item epic branch.
  • Loading branch information
22Alexandra authored Oct 31, 2022
2 parents 5b4689c + 72eb2ab commit 628878d
Show file tree
Hide file tree
Showing 25 changed files with 1,106 additions and 397 deletions.
94 changes: 94 additions & 0 deletions modules/oe_theme_helper/js/table_sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* @file
* Plugin for adding sorting of table.
*/

(function ($, CKEDITOR) {
"use strict";

CKEDITOR.plugins.add('table_sort', {
afterInit: function afterInit (editor) {
CKEDITOR.on('dialogDefinition', function(event) {
const dialog_name = event.data.name;
const sort_attribute = 'data-sortable';

if (dialog_name !== 'cellProperties') {
return;
}

const dialog_definition = event.data.definition;
const info_tab = dialog_definition.getContents('info');
const langCell = event.editor.lang.table.cell;
// Avoid multiple selectbox adding.
if (!info_tab.get('columnSortable')) {
info_tab.add({
type: 'select',
label: 'Sortable',
id: 'columnSortable',
requiredContent: 'th[' + sort_attribute + ']',
items: [
[langCell.yes, 'yes'],
[langCell.no, 'no'],
],

/**
* @param {CKEDITOR.dom.element[]} selectedCells
*/
setup: function (selectedCells) {
// Disable the element if any of the selected cells is not a header cell.
for (let i = 0; i < selectedCells.length; i++) {
if (selectedCells[i].getName() !== 'th') {
this.disable();
this.setValue(null);
return;
}
}

// This method receives an array of selected cells.
// We use the value of the first one as driver for the remaining cells.
// @see setupCells() in /plugins/tabletools/dialogs/tableCell.js
let value = selectedCells[0].hasAttribute(sort_attribute);

for (let i = 1; i < selectedCells.length; i++) {
if (selectedCells[i].hasAttribute(sort_attribute) !== value) {
// If any of the cells has a different sortable value, set the value
// to undetermined.
value = null;
break;
}
}

// Convert the value to the matching option.
if (value !== null) {
value = value ? 'yes' : 'no';
}

this.setValue(value);

// The only way to have an empty select value in Firefox is
// to set a negative selectedIndex.
if (value === null && CKEDITOR.env.gecko) {
this.getInputElement().$.selectedIndex = -1;
}
},

/**
* @param {CKEDITOR.dom.element} selectedCell
*/
commit: function (selectedCell) {
const value = this.getValue();

// Handle only supported values.
if (value === 'yes') {
selectedCell.setAttribute(sort_attribute, true);
} else if (value === 'no') {
selectedCell.removeAttribute(sort_attribute);
}
}
});
}
});
}
});

})(jQuery, CKEDITOR);
45 changes: 45 additions & 0 deletions modules/oe_theme_helper/js/table_zebra_striping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @file
* Plugin for adding zebra striping of table.
*/

(function ($, CKEDITOR) {
"use strict";

CKEDITOR.plugins.add('table_zebra_striping', {
afterInit: function afterInit (editor) {
CKEDITOR.on('dialogDefinition', function(event) {
const dialog_name = event.data.name;

if (dialog_name !== 'table' && dialog_name !== 'tableProperties') {
return;
}

const dialog_definition = event.data.definition;
const info_tab = dialog_definition.getContents('info');
const zebra_attribute = 'data-striped';
// Avoid multiple checkbox adding.
if (!info_tab.get('zebraStriping')) {
info_tab.add({
type: 'checkbox',
label: event.editor.config.zebra_striping__checkboxLabel,
id: 'zebraStriping',
labelStyle: 'display: inline;',
requiredContent: 'table[' + zebra_attribute + ']',
setup: function (selectedTable) {
this.setValue(selectedTable.getAttribute(zebra_attribute));
},
commit: function (data, selectedTable) {
if (this.getValue()) {
selectedTable.setAttribute(zebra_attribute, true);
} else {
selectedTable.removeAttribute(zebra_attribute);
}
}
});
}
});
}
});

})(jQuery, CKEDITOR);
70 changes: 70 additions & 0 deletions modules/oe_theme_helper/src/Plugin/CKEditorPlugin/TableSort.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types = 1);

namespace Drupal\oe_theme_helper\Plugin\CKEditorPlugin;

use Drupal\ckeditor\CKEditorPluginBase;
use Drupal\ckeditor\CKEditorPluginContextualInterface;
use Drupal\editor\Entity\Editor;

/**
* Defines the "table_sort" with altering Table plugins.
*
* @CKEditorPlugin(
* id = "table_sort",
* label = @Translation("Table sort")
* )
*/
class TableSort extends CKEditorPluginBase implements CKEditorPluginContextualInterface {

/**
* {@inheritdoc}
*/
public function getFile() {
return $this->getModulePath('oe_theme_helper') . '/js/table_sort.js';
}

/**
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
return [];
}

/**
* {@inheritdoc}
*/
public function getButtons() {
return [];
}

/**
* {@inheritdoc}
*/
public function isEnabled(Editor $editor) {
if (!$editor->hasAssociatedFilterFormat()) {
return FALSE;
}

// "Sortable" option should be available only when the ECL table
// filter is enabled and the table button is present in the WYSIWYG toolbar.
$enabled = FALSE;
$format = $editor->getFilterFormat();
if ($format->filters('filter_ecl_table')->status) {
$settings = $editor->getSettings();
foreach ($settings['toolbar']['rows'] as $row) {
foreach ($row as $group) {
foreach ($group['items'] as $button) {
if ($button === 'Table') {
$enabled = TRUE;
}
}
}
}
}

return $enabled;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types = 1);

namespace Drupal\oe_theme_helper\Plugin\CKEditorPlugin;

use Drupal\ckeditor\CKEditorPluginBase;
use Drupal\ckeditor\CKEditorPluginContextualInterface;
use Drupal\editor\Entity\Editor;

/**
* Defines the "table_zebra_striping" with altering Table plugins.
*
* @CKEditorPlugin(
* id = "table_zebra_striping",
* label = @Translation("Zebra striping")
* )
*/
class TableZebraStriping extends CKEditorPluginBase implements CKEditorPluginContextualInterface {

/**
* {@inheritdoc}
*/
public function getFile() {
return $this->getModulePath('oe_theme_helper') . '/js/table_zebra_striping.js';
}

/**
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
return [
'zebra_striping__checkboxLabel' => $this->t('Zebra striping'),
];
}

/**
* {@inheritdoc}
*/
public function getButtons() {
return [];
}

/**
* {@inheritdoc}
*/
public function isEnabled(Editor $editor) {
if (!$editor->hasAssociatedFilterFormat()) {
return FALSE;
}

// "Zebra striping" option should be available only when the ECL table
// filter is enabled and the table button is present in the WYSIWYG toolbar.
$enabled = FALSE;
$format = $editor->getFilterFormat();
if ($format->filters('filter_ecl_table')->status) {
$settings = $editor->getSettings();
foreach ($settings['toolbar']['rows'] as $row) {
foreach ($row as $group) {
foreach ($group['items'] as $button) {
if ($button === 'Table') {
$enabled = TRUE;
}
}
}
}
}

return $enabled;
}

}
79 changes: 69 additions & 10 deletions modules/oe_theme_helper/src/Plugin/Filter/FilterEclTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class FilterEclTable extends FilterBase {
* {@inheritdoc}
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function process($text, $langcode) {
$result = new FilterProcessResult($text);
Expand All @@ -36,12 +37,40 @@ public function process($text, $langcode) {
$dom = Html::load($text);
$xpath = new \DOMXPath($dom);

foreach ($xpath->query('//table[.//th]') as $table) {
// Skip the table if any cell spans over multiple columns or rows.
$span_cells = $xpath->query('.//*[self::th or self::td][(@colspan and @colspan > 1) or (@rowspan and @rowspan > 1)]', $table);
if ($span_cells->count() !== 0) {
foreach ($xpath->query('//table') as $table) {
// Put ECL related classes for table tag.
$this->elementAddClass($table, 'ecl-table');
// Add classes related to "Zebra striping".
if ($table->getAttribute('data-striped') === 'true') {
$this->elementAddClass($table, 'ecl-table--zebra');
$table->removeAttribute('data-striped');
}

// Put ECL related classes for thead tag.
foreach ($xpath->query('./thead', $table) as $thead) {
$this->elementAddClass($thead, 'ecl-table__head');
}

// Put ECL related classes for tbody tag.
foreach ($xpath->query('./tbody', $table) as $tbody) {
$this->elementAddClass($tbody, 'ecl-table__body');
}

// Put ECL related classes for tr tags.
foreach ($xpath->query('.//tr', $table) as $trow) {
$this->elementAddClass($trow, 'ecl-table__row');
}

// Skip further processing of the table if table without headers.
$ths = $xpath->query('.//th', $table);
if ($ths->count() === 0) {
continue;
}
else {
foreach ($xpath->query('.//thead/tr[1]/th', $table) as $th) {
$this->elementAddClass($th, 'ecl-table__header');
}
}

// Do not process tables that use th cells anywhere but in the first
// column.
Expand All @@ -56,19 +85,33 @@ public function process($text, $langcode) {
$has_header_row = $xpath->query('(./thead/tr[1])[count(./*[not(self::th)]) = 0]', $table);
if ($has_header_row->count()) {
$header_row = $has_header_row[0];
foreach ($xpath->query('./th', $header_row) as $cell) {
$headers[] = $cell->nodeValue;
foreach ($xpath->query('./th', $header_row) as $thead_cell) {
$this->elementAddClass($thead_cell, 'ecl-table__header');
// Add data attribute related to "Sort".
if ($thead_cell->getAttribute('data-sortable') === 'true') {
$thead_cell->setAttribute('data-ecl-table-sort-toggle', '');
$thead_cell->removeAttribute('data-sortable');

// Add additional attributes to enable sorting for table.
$table->setAttribute('data-ecl-table', '');
$table->setAttribute('data-ecl-auto-init', 'Table');
}
$headers[] = $thead_cell->nodeValue;
}
}

// Skip further processing of the table if any cell spans
// over multiple columns or rows.
$span_cells = $xpath->query('.//*[self::th or self::td][(@colspan and @colspan > 1) or (@rowspan and @rowspan > 1)]', $table);
if ($span_cells->count() !== 0) {
continue;
}

// Loop through all the table rows, aside from header ones.
foreach ($xpath->query('.//tr[not(parent::thead)]', $table) as $row) {
// Fetch all the cells inside the row.
foreach ($xpath->query('./*[self::th or self::td]', $row) as $cell_index => $cell) {
$existing_class = $cell->getAttribute('class');
$new_class = $existing_class ? "$existing_class ecl-table__cell" : 'ecl-table__cell';
$cell->setAttribute('class', $new_class);

$this->elementAddClass($cell, 'ecl-table__cell');
if (array_key_exists($cell_index, $headers)) {
$cell->setAttribute('data-ecl-table-header', $headers[$cell_index]);
}
Expand All @@ -81,4 +124,20 @@ public function process($text, $langcode) {
return $result;
}

/**
* Adds class to element.
*
* @param \DOMNode $element
* Element.
* @param string $class
* Class that should be added.
*/
public function elementAddClass(\DOMNode $element, string $class): void {
$classes = $element->getAttribute('class');
$classes_array = array_filter(array_map('trim', explode(' ', $classes)));
$classes_array[] = $class;
$classes = implode(' ', array_unique($classes_array));
$element->setAttribute('class', $classes);
}

}
Loading

0 comments on commit 628878d

Please sign in to comment.