Search code examples
phphtmlhtmlpurifier

HTMLPurifier - Change attribute value instead of remove


htmlpurifier removes attributes if value is not allowed. For example;

<div contenteditable="true"></div>

I set the permissions for div tags for contenteditable attribute, so the value can be only false. But if contenteditable="true" or anything other than false, htmlpurifier totally removes the attribute. I don't like this behavior. I would like to have htmlpurifier always keep the contenteditable attribute and set it to false.

Is this a possibility?

Actual Configs

$config = \HTMLPurifier_Config::createDefault();

$config->set('HTML.Allowed', 'div[contenteditable]');
$config->set('HTML.TargetNoopener', false);
$config->set('HTML.TargetNoreferrer', false);

$def = $config->getHTMLDefinition(true);
$def->addAttribute('div', 'contenteditable', 'Enum#false');

Result with this configs

Input:

<div contenteditable="true"></div>

Output:

<div></div>

Desired Results

Input:

<div contenteditable="true"></div>

Output:

<div contenteditable="false"></div>

Solution

  • I don't think there's an easy way to change an attribute's handling to coercing a known-good value as opposed to just dropping the bad value. You may need to write an attribute transformation; something like this:

    class HTMLPurifier_AttrTransform_ContentEditable extends HTMLPurifier_AttrTransform
    {
        public function transform($attr, $config, $context)
        {
            if (array_key_exists('contenteditable', $attr)) {
                $attr['contenteditable'] = 'true';
            }
            return $attr;
        }
    }
    

    Using/installing the class:

    $htmlDef = $htmlPurifierConfiguration->getHTMLDefinition(true);
    $tag     = $htmlDef->addBlankElement('div');
    $tag->attr_transform_post[] = new HTMLPurifier_AttrTransform_ContentEditable();
    // purify down here