Even if I allow the attribute style from configuration, CKEditor is removing it when is loaded. It works perfectly when I see the content, but when I try to edit it, the CKEditor removes the attribute.

This is my config

'safe' => 1, 'elements' => 'a, em, strong, cite, code, ol, ul, li, dl, dt, dd, br, p', 'deny_attribute' => 'id'

When I see the content

<p style="background-color:#fafafa;">Hello</p>

When I go to the edit page, on CKEditor

<p>Hello</p>

Comments

juanramonperez created an issue. See original summary.

juanramonperez’s picture

Issue summary: View changes
alpha2zee’s picture

Assigned: Unassigned » alpha2zee

Hi... sorry for the delay in responding. I tested the htmLawed module with the latest version of Drupal 8, with text formats with either CKEditor enabled or disabled. With CKEditor disabled, the htmLawed filtering occurs as expected, with 'style' attribute and values passing the filter. However, with CKEditor enabled, I do see that an input such as

<p style="background-color:#fafafa;">Hello</p>

when put in as 'source' in the CKEditor editor ends up becoming

<p>Hello</p>

I suspect that this is a CKEditor issue. E.g., see https://www.drupal.org/node/2510970. Could it be that CKEditor itself is removing 'style'?

juanramonperez’s picture

Thanks for your response.

I did some debugging and I found that if your filter type is of type FilterInterface::TYPE_HTML_RESTRICTOR the editor module is calling to the Drupal\editor\EditorXssFilter\Standard::filterXss( ) function which calls to Drupal\Component\Utility\Xss::filter( ) (this function ALWAYS stripes the style attribute, no matter the configuration that you passed, is hardcoded) when the editor is loaded. Thats because the style attribute is removed on the editor side and not when the content is rendered. As a workaround I implemented the hook_editor_xss_filter_alter and then pass my own XssFilter class.

on mymodule.module file

/**
 * Implements hook_editor_xss_filter_alter().
 */
function mymodule_editor_xss_filter_alter(&$editor_xss_filter_class, FilterFormatInterface $format, FilterFormatInterface $original_format = NULL) {
  $filters = $format->filters()->getAll();
  if (isset($filters['filter_htmlawed']) && $filters['filter_htmlawed']->status) {
    $editor_xss_filter_class = '\Drupal\mymodule\EditorXssFilter\Htmlawed';
  }
}

on src/EditorXssFilter/Htmlawed.php file


namespace Drupal\mymodule\EditorXssFilter;

use Drupal\filter\FilterFormatInterface;
use Drupal\editor\EditorXssFilterInterface;

/**
 * Defines a new text editor XSS filter.
 *
 * The original filter ALWAYS strip the "style" attribute.
 */
class Htmlawed implements EditorXssFilterInterface {

  /**
   * {@inheritdoc}
   */
  public static function filterXss($html, FilterFormatInterface $format, FilterFormatInterface $original_format = NULL) {
    // Apply all enabled filters to the html text. Secure (?).
    return check_markup($html, $format->id());
  }

}

Hope this helps

alpha2zee’s picture

Thanks for looking into this. So, do you think I can put the suggested or similar code within the htmLawed module?

I did a test but the code suggested in your post is not working; when I try to edit content using an htmLawed filter-enabled format, I get a page with "The website encountered an unexpected error. Please try again later." and the error log shows:

TypeError: Argument 2 passed to htmlawed_editor_xss_filter_alter() must be an instance of FilterFormatInterface, instance of Drupal\filter\Entity\FilterFormat given...

To test the code, I had done the following.

(1) Modified current htmlawed/htmLawed.module file so it includes:

/**
 * Implements hook_editor_xss_filter_alter().
 */
function htmlawed_editor_xss_filter_alter(&$editor_xss_filter_class, FilterFormatInterface $format, FilterFormatInterface $original_format = NULL) {
  $filters = $format->filters()->getAll();
  if (isset($filters['filter_htmlawed']) && $filters['filter_htmlawed']->status) {
    $editor_xss_filter_class = '\Drupal\htmlawed\EditorXssFilter\Filterhtmlawed';
  }
}

(2) Created file htmlawed/src/EditorXssFilter/Filterhtmlawed.php with:

<?php
/**
 * @file
 * Contains Drupal\htmlawed\src\EditorXssFilter\Filterhtmlawed
 */

namespace Drupal\htmlawed\EditorXssFilter;

use Drupal\filter\FilterFormatInterface;
use Drupal\editor\EditorXssFilterInterface;

/**
 * Defines a new text editor XSS filter.
 *
 * The original filter ALWAYS strip the "style" attribute.
 */
class Filterhtmlawed implements EditorXssFilterInterface {

  /**
   * {@inheritdoc}
   */
  public static function filterXss($html, FilterFormatInterface $format, FilterFormatInterface $original_format = NULL) {
    // Apply all enabled filters to the html text. Secure (?).
    return check_markup($html, $format->id());
  }

}

I will appreciate your feedback. Thanks.

collin.rickford’s picture

Have you added
use Drupal\filter\FilterFormatInterface;
to htmlawed/htmLawed.module?

alpha2zee’s picture

I have now tried adding use Drupal\filter\FilterFormatInterface; to the .module file, but it doesn't help. When I create new content using an htmLawed-using text format, I the text object Object is shown in the editor window.

collin.rickford’s picture

StatusFileSize
new1.73 KB

It appears the hooks in htmLawed.module don't run unless they match the module name (case-sensitive). I have added the exact code above and renamed the module from htmLawed.module to htmlawed.module - now working for me.

Patch rolled against 8.x-3.x branch

alpha2zee’s picture

Status: Active » Closed (duplicate)

@juanramonperez, @collin.rockford: Thanks for your various suggestions. The codes work, though I am not finding a need to lowercase the 'l' in the 'htmLawed.module' filename.

One problem with the current code noted above for function 'filterXss' is that it raises a security risk when the text editor is in use in WYSIWYG mode (in which rendered HTML and not HTML source is displayed).

It seems the best way to deal with this is to implement the 'getHtmlRestrictions' function, as suggested in this issue.

I am now closing this particular issue.