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
73 lines
3.1 KiB
HTML
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>
|