Implement shadow dom slots (#35013)

* Implement slot-related algorithms

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Hook up slot elements to DOM creation logic

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Set a slot assignment mode for servo-internal shadow roots

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Assign slots when a slottable's slot attribute changes

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Properly compute slot name

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* ./mach test-tidy

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Update <slot> name when name attribute changes

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Implement fast path for Node::assign_slottables_for_a_tree

assign_slottables_for_a_tree traverses all descendants of the node
and is potentially very expensive. If the node is not a shadow root
then assigning slottables to it won't have any effect, so we
take a fast path out.

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Move slottable data into ElementRareData

This shrinks all element descendants back to their
original size.

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Address review comments

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Update WPT expectations

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-01-19 15:05:05 +01:00 committed by GitHub
parent 8bb50fa3c9
commit dabe162d44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 758 additions and 355 deletions

View file

@ -12,8 +12,10 @@ use style::stylesheets::Stylesheet;
use style::stylist::{CascadeData, Stylist};
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::ShadowRootMode;
use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::ShadowRoot_Binding::ShadowRootMethods;
use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{
ShadowRootMode, SlotAssignmentMode,
};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::reflect_dom_object;
@ -57,6 +59,9 @@ pub(crate) struct ShadowRoot {
/// <https://dom.spec.whatwg.org/#dom-shadowroot-mode>
mode: ShadowRootMode,
/// <https://dom.spec.whatwg.org/#dom-shadowroot-slotassignment>
slot_assignment_mode: SlotAssignmentMode,
/// <https://dom.spec.whatwg.org/#dom-shadowroot-clonable>
clonable: bool,
}
@ -67,6 +72,7 @@ impl ShadowRoot {
host: &Element,
document: &Document,
mode: ShadowRootMode,
slot_assignment_mode: SlotAssignmentMode,
clonable: bool,
) -> ShadowRoot {
let document_fragment = DocumentFragment::new_inherited(document);
@ -86,6 +92,7 @@ impl ShadowRoot {
stylesheet_list: MutNullableDom::new(None),
window: Dom::from_ref(document.window()),
mode,
slot_assignment_mode,
clonable,
}
}
@ -94,10 +101,17 @@ impl ShadowRoot {
host: &Element,
document: &Document,
mode: ShadowRootMode,
slot_assignment_mode: SlotAssignmentMode,
clonable: bool,
) -> DomRoot<ShadowRoot> {
reflect_dom_object(
Box::new(ShadowRoot::new_inherited(host, document, mode, clonable)),
Box::new(ShadowRoot::new_inherited(
host,
document,
mode,
slot_assignment_mode,
clonable,
)),
document.window(),
CanGc::note(),
)
@ -306,6 +320,11 @@ impl ShadowRootMethods<crate::DomTypeHolder> for ShadowRoot {
// Step 4. Replace all with fragment within this.
Node::replace_all(Some(frag.upcast()), self.upcast());
}
/// <https://dom.spec.whatwg.org/#dom-shadowroot-slotassignment>
fn SlotAssignment(&self) -> SlotAssignmentMode {
self.slot_assignment_mode
}
}
impl VirtualMethods for ShadowRoot {