script: Support shadowrootslotassignment on template elements (#44246)

This brings up to date with the specification for declarative shadow
roots: https://github.com/whatwg/html/pull/12267.

The `shadowrootslotassignment` attribute on `<template>` elements
specifies the slot assignment mode used by the declarative shadow root
created by the template.

Testing: New tests start to pass

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker
2026-04-19 16:22:06 +02:00
committed by GitHub
parent eea0c586c0
commit 18d3ad5252
8 changed files with 37 additions and 44 deletions

5
Cargo.lock generated
View File

@@ -8800,6 +8800,7 @@ dependencies = [
"url",
"urlpattern",
"uuid",
"web_atoms",
"webdriver",
"webrender_api",
"wgpu-core",
@@ -11028,9 +11029,9 @@ dependencies = [
[[package]]
name = "web_atoms"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a9779e9f04d2ac1ce317aee707aa2f6b773afba7b931222bff6983843b1576"
checksum = "d7cff6eef815df1834fd250e3a2ff436044d82a9f1bc1980ca1dbdf07effc538"
dependencies = [
"phf",
"phf_codegen",

View File

@@ -363,7 +363,7 @@ codegen-units = 1
# web_atoms = { path = "../html5ever/web_atoms" }
# xml5ever = { path = "../html5ever/xml5ever" }
# tendril = { path = "../html5ever/tendril" }
#
# For WebRender:
#
# webrender = { path = "../webrender/webrender" }

View File

@@ -164,6 +164,7 @@ unicode-script = { workspace = true }
url = { workspace = true }
urlpattern = { workspace = true }
uuid = { workspace = true, features = ["serde"] }
web_atoms = "0.2.4"
webdriver = { workspace = true }
webgpu_traits = { workspace = true, optional = true }
webrender_api = { workspace = true }

View File

@@ -85,6 +85,18 @@ impl HTMLTemplateElementMethods<crate::DomTypeHolder> for HTMLTemplateElement {
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootdelegatesfocus>
make_bool_setter!(SetShadowRootDelegatesFocus, "shadowrootdelegatesfocus");
/// <https://html.spec.whatwg.org/multipage/#attr-template-shadowrootslotassignment>
make_enumerated_getter!(
ShadowRootSlotAssignment,
"shadowrootslotassignment",
"named" | "manual",
missing => "named",
invalid => "named"
);
/// <https://html.spec.whatwg.org/multipage/#attr-template-shadowrootslotassignment>
make_atomic_setter!(SetShadowRootSlotAssignment, "shadowrootslotassignment");
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootclonable>
make_bool_getter!(ShadowRootClonable, "shadowrootclonable");

View File

@@ -2109,34 +2109,28 @@ fn attach_declarative_shadow_inner(
let template_element = template.downcast::<HTMLTemplateElement>().unwrap();
// Step 3. Let mode be template start tag's shadowrootmode attribute's value.
// Step 4. Let clonable be true if template start tag has a shadowrootclonable attribute; otherwise false.
// Step 5. Let delegatesfocus be true if template start tag
// has a shadowrootdelegatesfocus attribute; otherwise false.
// Step 6. Let serializable be true if template start tag
// has a shadowrootserializable attribute; otherwise false.
// Step 3. Let mode be templateStartTag's shadowrootmode attribute's value.
// Step 4. Let slotAssignment be "named".
// Step 5. If templateStartTag's shadowrootslotassignment attribute is in
// the Manual state, then set slotAssignment to "manual".
// Step 6. Let clonable be true if templateStartTag has a shadowrootclonable attribute; otherwise false.
// Step 7. Let serializable be true if templateStartTag has a shadowrootserializable
// attribute; otherwise false.
// Step 8. Let delegatesFocus be true if templateStartTag has a shadowrootdelegatesfocus
// attribute; otherwise false.
let mut shadow_root_mode = ShadowRootMode::Open;
let mut slot_assignment_mode = SlotAssignmentMode::Named;
let mut clonable = false;
let mut delegatesfocus = false;
let mut serializable = false;
let attributes: Vec<ElementAttribute> = attributes
.iter()
.map(|attr| {
ElementAttribute::new(
attr.name.clone(),
DOMString::from(String::from(attr.value.clone())),
)
})
.collect();
attributes
.iter()
.for_each(|attr: &ElementAttribute| match attr.name.local {
.for_each(|attr: &Attribute| match attr.name.local {
local_name!("shadowrootmode") => {
if attr.value.str().eq_ignore_ascii_case("open") {
if attr.value.eq_ignore_ascii_case("open") {
shadow_root_mode = ShadowRootMode::Open;
} else if attr.value.str().eq_ignore_ascii_case("closed") {
} else if attr.value.eq_ignore_ascii_case("closed") {
shadow_root_mode = ShadowRootMode::Closed;
} else {
unreachable!("shadowrootmode value is not open nor closed");
@@ -2151,6 +2145,11 @@ fn attach_declarative_shadow_inner(
local_name!("shadowrootserializable") => {
serializable = true;
},
local_name!("shadowrootslotassignment") => {
if attr.value.eq_ignore_ascii_case("manual") {
slot_assignment_mode = SlotAssignmentMode::Manual;
}
},
_ => {},
});
@@ -2163,7 +2162,7 @@ fn attach_declarative_shadow_inner(
clonable,
serializable,
delegatesfocus,
SlotAssignmentMode::Named,
slot_assignment_mode,
) {
Ok(shadow_root) => {
// Step 8.3. Set shadow's declarative to true.

View File

@@ -10,6 +10,7 @@ interface HTMLTemplateElement : HTMLElement {
readonly attribute DocumentFragment content;
[CEReactions] attribute DOMString shadowRootMode;
[CEReactions] attribute boolean shadowRootDelegatesFocus;
[CEReactions] attribute DOMString shadowRootSlotAssignment;
[CEReactions] attribute boolean shadowRootClonable;
[CEReactions] attribute boolean shadowRootSerializable;
};

View File

@@ -1,6 +0,0 @@
[declarative-shadow-dom-repeats-slot-assignment.html]
[attachShadow() on declarative shadow root with manual slotAssignment]
expected: FAIL
[attachShadow() on declarative shadow root does not change slotAssignment]
expected: FAIL

View File

@@ -1,15 +0,0 @@
[declarative-shadow-dom-slot-assignment.html]
[shadowrootslotassignment reflection]
expected: FAIL
[shadowrootslotassignment reflection, setter]
expected: FAIL
[Declarative Shadow DOM: shadowrootslotassignment=manual]
expected: FAIL
[Declarative Shadow DOM: shadowrootslotassignment is case insensitive]
expected: FAIL
[Declarative Shadow DOM: shadowrootslotassignment on closed shadows can be set to manual]
expected: FAIL