Issue #2556069 by claudiu.cristea, bnjmnm, lauriii, pfrenssen, Tim Bozeman, marcvangend, ikeigenwijs, Wim Leers, kevinquillen, esclapes, nod_: JS error with elements in "allowed HTML tags" that can't be direct descendants of a div

merge-requests/916/head
Lauri Eskola 2021-07-08 14:50:49 +03:00
parent e3dd03cf39
commit 88498c7846
No known key found for this signature in database
GPG Key ID: 382FC0F5B0DF53F8
3 changed files with 64 additions and 13 deletions

View File

@ -267,26 +267,29 @@
* tag name.
*/
_parseSetting(setting) {
let node;
let tag;
let rule;
let attributes;
let attribute;
const allowedTags = setting.match(/(<[^>]+>)/g);
const sandbox = document.createElement('div');
const rules = {};
for (let t = 0; t < allowedTags.length; t++) {
// Let the browser do the parsing work for us.
sandbox.innerHTML = allowedTags[t];
node = sandbox.firstChild;
tag = node.tagName.toLowerCase();
// Create a jQuery object, making it possible to easily retrieve the
// tag name of the allowed tag, regardless of what attributes are set or
// what its required parent elements are.
const $tagObject = $(allowedTags[t]);
// Parse the tag name from the jQuery object.
tag = $tagObject.prop('tagName').toLowerCase();
// Build the Drupal.FilterHtmlRule object.
rule = new Drupal.FilterHTMLRule();
// We create one rule per allowed tag, so always one tag.
rule.restrictedTags.tags = [tag];
// Add the attribute restrictions.
attributes = node.attributes;
attributes = $tagObject.prop('attributes');
for (let i = 0; i < attributes.length; i++) {
attribute = attributes.item(i);
const attributeName = attribute.nodeName;

View File

@ -129,22 +129,19 @@
return autoAllowedTags;
},
_parseSetting: function _parseSetting(setting) {
var node;
var tag;
var rule;
var attributes;
var attribute;
var allowedTags = setting.match(/(<[^>]+>)/g);
var sandbox = document.createElement('div');
var rules = {};
for (var t = 0; t < allowedTags.length; t++) {
sandbox.innerHTML = allowedTags[t];
node = sandbox.firstChild;
tag = node.tagName.toLowerCase();
var $tagObject = $(allowedTags[t]);
tag = $tagObject.prop('tagName').toLowerCase();
rule = new Drupal.FilterHTMLRule();
rule.restrictedTags.tags = [tag];
attributes = node.attributes;
attributes = $tagObject.prop('attributes');
for (var i = 0; i < attributes.length; i++) {
attribute = attributes.item(i);

View File

@ -0,0 +1,51 @@
<?php
namespace Drupal\Tests\filter\FunctionalJavascript;
use Drupal\filter\Entity\FilterFormat;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
/**
* Tests the 'filter_html' plugin javascript functionality.
*
* @group filter
*/
class FilterHtmlTest extends WebDriverTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['editor', 'filter'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Tests restricting HTML to table tags.
*/
public function testTableTags() {
FilterFormat::create([
'format' => 'some_html',
'filters' => [
'filter_html' => [
'status' => 1,
'settings' => [
'allowed_html' => '<caption> <tbody> <thead> <tfoot> <th> <td> <tr>',
],
],
],
])->save();
$this->drupalLogin($this->drupalCreateUser(['administer filters']));
$this->drupalGet('admin/config/content/formats/manage/some_html');
$js_condition = "Drupal.behaviors.filterFilterHtmlUpdating._parseSetting(
jQuery('#edit-filters-filter-html-settings-allowed-html').val()
)['td'].tags.length >= 0";
$this->assertJsCondition($js_condition);
}
}