Unverified Commit 9e96d1c8 authored by Lauri Timmanee's avatar Lauri Timmanee
Browse files

Issue #2556069 by claudiu.cristea, bnjmnm, lauriii, pfrenssen, Tim Bozeman,...

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

(cherry picked from commit 88498c78)
parent efb1a0f4
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -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;
+3 −6
Original line number Diff line number Diff line
@@ -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);
+51 −0
Original line number Diff line number Diff line
<?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);
  }

}