fix: interactions are builder-only for users without unfiltered_html (P16)

Divi's frontend applies the interaction effect "Attribute" with setAttribute
(e.g. an onclick handler) and sets cookies; *.decoration.interactions joins
the S7 gate in ValueCleaner, which also covers removals and StoredNodeGuard.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-27 01:54:25 +02:00
co-authored by Claude Opus 5.5
parent f8275ad325
commit 9d92808918
7 changed files with 107 additions and 7 deletions
@@ -54,9 +54,12 @@ final class ValueCleaner
/**
* Raw HTML/CSS fields, and the ones Divi re-serializes whole pages for (rulings S7/S26), by
* path shape at any depth: module.advanced.html(.htmlBefore), module.decoration.attributes,
* any free-form custom CSS path of any module (css, css.*, title.css.*, css.advanced.customCss).
* any free-form custom CSS path of any module (css, css.*, title.css.*, css.advanced.customCss),
* and interactions (ruling P16: *.decoration.interactions – Divi's frontend script applies the
* "Attribute" effect with setAttribute, e.g. an onclick handler, and sets cookies/presets).
*/
private const BUILDER_ONLY = '/(^|\.)(decoration\.attributes|advanced\.html|advanced\.customCss|css)(\.|$)/';
private const BUILDER_ONLY
= '/(^|\.)(decoration\.attributes|decoration\.interactions|advanced\.html|advanced\.customCss|css)(\.|$)/';
public function __construct(
private ModuleCatalog $catalog,
@@ -134,7 +137,7 @@ final class ValueCleaner
{
if (preg_match(self::BUILDER_ONLY, $path) === 1 && ! $this->sanitizer->allowsUnfilteredHtml()) {
throw new InvalidArgumentException(sprintf(
'"%s" (eigenes HTML, CSS oder HTML-Attribute) ist nur im Divi-Builder änderbar '
'"%s" (eigenes HTML, CSS, HTML-Attribute oder Interaktionen) ist nur im Divi-Builder änderbar '
. '(oder mit dem Recht unfiltered_html).',
$path
));