Files
sousa-gecko/testing/web-platform/tests/sanitizer-api/sethtml-with-declarative-shadow-root.tentative.html
T
Blink WPT Bot 72402cf2d0 Bug 2039678 [wpt PR 59888] - Fix custom element upgrade in declarative shadow roots parsed via setHTMLUnsafe, a=testonly
Automatic update from web-platform-tests
Fix custom element upgrade in declarative shadow roots parsed via setHTMLUnsafe (#59888)

When template.setHTMLUnsafe() parses declarative shadow roots, the
template document has no domWindow(), causing AttachShadowRootInternal
to call SetCustomElementRegistry(nullptr) which incorrectly sets
waiting_for_registry_=true. After adoption into the live document,
customElementRegistry() returns null, blocking TryToUpgrade.

Fix by adding an explicit waiting_for_scoped_registry parameter to
AttachShadowRootInternal to distinguish 'no window available' from
'explicitly null registry'. SetCustomElementRegistry is now only called
when registry || waiting_for_scoped_registry.

Also update sethtml-with-declarative-shadow-root.tentative.html
expectation that customElementRegistry is null when the sanitizer strips
shadowrootcustomelementregistry. The null was accidental — shadow roots
parsed in template documents (used by setHTML with sanitizer via
ForceInertTemplate) were incorrectly stuck with null registries. The
correct default when the attribute is absent is the global registry.

Bug: 512514744
Change-Id: If9cc66a90c46c6c3cdeda0bf9e090abff4da021a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7844339
Reviewed-by: Noam Rosenthal <nrosenthal@google.com>
Reviewed-by: Mason Freed <masonf@chromium.org>
Commit-Queue: Jayson Chen <jaysonchen@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1630685}

Co-authored-by: Jayson Chen <jaysonchen@microsoft.com>
--

wpt-commits: d21d659d9020b1a2ea83e443bf05e8c59a8090c1
wpt-pr: 59888
2026-06-02 10:25:54 +00:00

73 lines
3.1 KiB
HTML

<!doctype html>
<head>
<title>Sanitize template with a declarative shadow root</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div></div>
<script>
test((t) => {
const element = document.createElement("div");
element.setHTML("<div><template shadowrootmode='open'></template></div>");
assert_equals(element.firstElementChild.shadowRoot, null);
assert_equals(element.firstElementChild.firstElementChild, null);
}, "template with shadowrootmode should be removed by safe default");
test((t) => {
const element = document.createElement("div");
element.setHTMLUnsafe(
"<div><template shadowrootmode='open'></template></div>",
);
assert_not_equals(element.firstElementChild.shadowRoot, null);
}, "template with shadowrootmode should not be removed in unsafe mode");
test((t) => {
const element = document.createElement("div");
element.setHTML(
"<div><template shadowrootmode='open'></template></div>",
{ sanitizer: { removeElements: ["template"] } },
);
assert_equals(element.firstElementChild.shadowRoot, null);
assert_equals(element.firstElementChild.firstElementChild, null);
}, "template with shadowrootmode should not be processed when <template> is forbidden");
test((t) => {
const element = document.createElement("div");
element.setHTML(
"<div><template shadowrootmode='open'></template></div>",
{ sanitizer: { removeAttributes: ["shadowrootmode"] } },
);
assert_equals(element.firstElementChild.shadowRoot, null);
assert_equals(
element.firstElementChild.firstElementChild.localName,
"template",
);
}, "template with shadowrootmode should be processed as a normal template when the shadowRootMode attribute is forbidden");
for (const [attribute, value, property, expectedValue] of [
["shadowrootdelegatesfocus", "", "delegatesFocus", false],
["shadowrootserializable", "", "serializable", false],
["shadowrootclonable", "", "clonable", false],
["shadowrootreferencetarget", "something", "referenceTarget", null],
["shadowrootcustomelementregistry", "", "customElementRegistry", customElements],
["shadowrootadoptedstylesheets", "style.css", "adoptedStyleSheets", []],
]) {
test((t) => {
const element = document.createElement("div");
element.setHTML(
`<div><template shadowrootmode='open' ${attribute}="${value}"></template></div>`,
{ sanitizer: { removeAttributes: [attribute] } },
);
assert_not_equals(element.firstElementChild.shadowRoot, null, `shadowRoot should exist`);
if (Array.isArray(expectedValue)) {
assert_array_equals(element.firstElementChild.shadowRoot[property], expectedValue);
} else {
assert_equals(element.firstElementChild.shadowRoot[property], expectedValue);
}
}, `shadowRoot.${property} does not propagate to the shadow root when ${attribute} is removed by sanitizer`);
}
</script>
</body>