Include non-shadowdom children of shadow hosts in style calculation (#34298)

* Include non-shadowdom children of shadow hosts in style calculation

This was previously causing crashes because the layout nodes
of those children would never be assigned style data by stylo.

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 2024-11-20 20:28:35 +01:00 committed by GitHub
parent 2889e934f5
commit f3ad078358
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
77 changed files with 284 additions and 96 deletions

View file

@ -140,20 +140,41 @@ impl<'dom> ServoLayoutElement<'dom> {
} }
} }
pub struct DomChildrenIncludingShadowDom<N> {
children: DomChildren<N>,
children_in_shadow_root: Option<DomChildren<N>>,
}
impl<N> Iterator for DomChildrenIncludingShadowDom<N>
where
N: TNode,
{
type Item = N;
fn next(&mut self) -> Option<Self::Item> {
self.children
.next()
.or_else(|| self.children_in_shadow_root.as_mut()?.next())
}
}
impl<'dom> style::dom::TElement for ServoLayoutElement<'dom> { impl<'dom> style::dom::TElement for ServoLayoutElement<'dom> {
type ConcreteNode = ServoLayoutNode<'dom>; type ConcreteNode = ServoLayoutNode<'dom>;
type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>; type TraversalChildrenIterator = DomChildrenIncludingShadowDom<Self::ConcreteNode>;
fn as_node(&self) -> ServoLayoutNode<'dom> { fn as_node(&self) -> ServoLayoutNode<'dom> {
ServoLayoutNode::from_layout_js(self.element.upcast()) ServoLayoutNode::from_layout_js(self.element.upcast())
} }
fn traversal_children(&self) -> LayoutIterator<Self::TraversalChildrenIterator> { fn traversal_children(&self) -> LayoutIterator<Self::TraversalChildrenIterator> {
LayoutIterator(if let Some(shadow) = self.shadow_root() { let children = DomChildrenIncludingShadowDom {
shadow.as_node().dom_children() children: self.as_node().dom_children(),
} else { children_in_shadow_root: self
self.as_node().dom_children() .shadow_root()
}) .map(|shadow| shadow.as_node().dom_children()),
};
LayoutIterator(children)
} }
fn is_html_element(&self) -> bool { fn is_html_element(&self) -> bool {

View file

@ -1,2 +1,2 @@
[cancel-animation-shadow-slot-invalidation.html] [cancel-animation-shadow-slot-invalidation.html]
expected: CRASH expected: TIMEOUT

View file

@ -1,2 +1,2 @@
[layer-slotted-rule.html] [layer-slotted-rule.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[revert-layer-014.html] [revert-layer-014.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[quotes-slot-scoping.html] [quotes-slot-scoping.html]
expected: CRASH expected: PASS

View file

@ -1,2 +1,2 @@
[display-contents-shadow-dom-1.html] [display-contents-shadow-dom-1.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[counter-list-item-slot-order.html] [counter-list-item-slot-order.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[counter-slot-order-scoping.html] [counter-slot-order-scoping.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[counter-slot-order.html] [counter-slot-order.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +0,0 @@
[text-decoration-propagation-shadow.html]
expected: CRASH

View file

@ -1,2 +1,2 @@
[remove-slotted-with-whitespace-sibling.html] [remove-slotted-with-whitespace-sibling.html]
expected: CRASH expected: FAIL

View file

@ -1,5 +1,4 @@
[checkVisibility.html] [checkVisibility.html]
expected: CRASH
[checkVisibility on visibility:hidden element.] [checkVisibility on visibility:hidden element.]
expected: FAIL expected: FAIL
@ -29,3 +28,18 @@
[checkVisibility on content-visibility:hidden element after forced layout update.] [checkVisibility on content-visibility:hidden element after forced layout update.]
expected: FAIL expected: FAIL
[checkVisibility on element slotted in content-visibility: hidden shadow host.]
expected: FAIL
[checkVisibility on element slotted in display:none shadow host.]
expected: FAIL
[checkVisibility on display:contents element.]
expected: FAIL
[checkVisibility on element slotted in opacity: 0; shadow host.]
expected: FAIL
[checkVisibility on root element with content-visibility: hidden returns true.]
expected: FAIL

View file

@ -1,2 +0,0 @@
[insert-dir-rule-crash.html]
expected: CRASH

View file

@ -1,2 +0,0 @@
[insert-dir-rule-in-iframe-crash.html]
expected: CRASH

View file

@ -1,2 +1,2 @@
[focus-within-shadow-001.html] [focus-within-shadow-001.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[focus-within-shadow-002.html] [focus-within-shadow-002.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[focus-within-shadow-003.html] [focus-within-shadow-003.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[focus-within-shadow-004.html] [focus-within-shadow-004.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[focus-within-shadow-005.html] [focus-within-shadow-005.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[focus-within-shadow-006.html] [focus-within-shadow-006.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[lang-pseudo-class-across-shadow-boundaries.html] [lang-pseudo-class-across-shadow-boundaries.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,9 @@
[is-where-shadow.html] [is-where-shadow.html]
expected: CRASH [:is() inside :host()]
expected: FAIL
[:is() inside :host-context()]
expected: FAIL
[:is() inside ::slotted()]
expected: FAIL

View file

@ -1,2 +1,2 @@
[2d.text-outside-of-the-flat-tree.html] [2d.text-outside-of-the-flat-tree.html]
expected: CRASH expected: PASS

View file

@ -1,5 +1,5 @@
[dir-auto-dynamic-changes.window.html] [dir-auto-dynamic-changes.window.html]
expected: CRASH expected: OK
[dynamic insertion of RTL text in a child element] [dynamic insertion of RTL text in a child element]
expected: FAIL expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-01.html] [dir-shadow-01.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-02.html] [dir-shadow-02.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-03.html] [dir-shadow-03.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-04.html] [dir-shadow-04.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-05.html] [dir-shadow-05.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-06.html] [dir-shadow-06.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-07.html] [dir-shadow-07.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-08.html] [dir-shadow-08.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-09.html] [dir-shadow-09.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-10.html] [dir-shadow-10.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-11.html] [dir-shadow-11.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-12.html] [dir-shadow-12.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-31.html] [dir-shadow-31.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-35.html] [dir-shadow-35.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-41.html] [dir-shadow-41.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[dir-shadow-42.html] [dir-shadow-42.html]
expected: CRASH expected: FAIL

View file

@ -1,5 +1,5 @@
[dir-slots-directionality.html] [dir-slots-directionality.html]
expected: CRASH expected: OK
[Slots: Directionality: dir=rtl on slot] [Slots: Directionality: dir=rtl on slot]
expected: FAIL expected: FAIL

View file

@ -1,5 +1,5 @@
[contentEditable-slotted-inherit.html] [contentEditable-slotted-inherit.html]
expected: CRASH expected: OK
[Slotted child of contenteditable host should be editable - slot direct child of shadow root] [Slotted child of contenteditable host should be editable - slot direct child of shadow root]
expected: FAIL expected: FAIL

View file

@ -1,2 +1,2 @@
[legend-in-slot.html] [legend-in-slot.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[sticky-content-crash.html] [sticky-content-crash.html]
expected: CRASH expected: PASS

View file

@ -1,2 +0,0 @@
[showmodal-in-shadow-crash.html]
expected: CRASH

View file

@ -1,5 +1,5 @@
[Selection-getComposedRanges-dom-mutations-removal.html?mode=open] [Selection-getComposedRanges-dom-mutations-removal.html?mode=open]
expected: CRASH expected: OK
[Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.] [Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.]
expected: FAIL expected: FAIL
@ -17,7 +17,7 @@
[Selection-getComposedRanges-dom-mutations-removal.html?mode=closed] [Selection-getComposedRanges-dom-mutations-removal.html?mode=closed]
expected: CRASH expected: OK
[Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.] [Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.]
expected: FAIL expected: FAIL

View file

@ -1,4 +1,4 @@
[Selection-later-become-slotted-content.html] [Selection-later-become-slotted-content.html]
expected: CRASH expected: OK
[test to select a light DOM element and it becomes a slotted content after the selection] [test to select a light DOM element and it becomes a slotted content after the selection]
expected: FAIL expected: FAIL

View file

@ -1,2 +1,3 @@
[declarative-after-attachshadow.html] [declarative-after-attachshadow.html]
expected: CRASH [Declarative Shadow DOM: declarative shadow should fail if attachShadow() already called]
expected: FAIL

View file

@ -1,2 +1,9 @@
[declarative-shadow-dom-repeats.html] [declarative-shadow-dom-repeats.html]
expected: CRASH [Repeated declarative shadow roots keep only the first]
expected: FAIL
[Calling attachShadow() on declarative shadow root must match mode]
expected: FAIL
[Calling attachShadow() on declarative shadow root must match all parameters]
expected: FAIL

View file

@ -1,2 +1,3 @@
[innerhtml-on-ordinary-template.html] [innerhtml-on-ordinary-template.html]
expected: CRASH [Declarative Shadow DOM: innerHTML should work on <template shadowroot> that is left over]
expected: FAIL

View file

@ -1,2 +1,2 @@
[directionality-001.tentative.html] [directionality-001.tentative.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[directionality-002.tentative.html] [directionality-002.tentative.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,60 @@
[event-inside-slotted-node.html] [event-inside-slotted-node.html]
expected: CRASH [Firing an event inside a grand child of a detached open mode shadow host]
expected: FAIL
[Firing an event inside a grand child of a detached closed mode shadow host]
expected: FAIL
[Firing an event inside a grand child of an in-document open mode shadow host]
expected: FAIL
[Firing an event inside a grand child of an in-document closed mode shadow host]
expected: FAIL
[Firing an event on a node with two ancestors with a detached open and open shadow trees with an inner open shadow tree]
expected: FAIL
[Firing an event on a node with two ancestors with a detached open and open shadow trees with an inner closed shadow tree]
expected: FAIL
[Firing an event on a node with two ancestors with a detached open and closed shadow trees with an inner open shadow tree]
expected: FAIL
[Firing an event on a node with two ancestors with a detached open and closed shadow trees with an inner closed shadow tree]
expected: FAIL
[Firing an event on a node with two ancestors with a detached closed and open shadow trees with an inner open shadow tree]
expected: FAIL
[Firing an event on a node with two ancestors with a detached closed and open shadow trees with an inner closed shadow tree]
expected: FAIL
[Firing an event on a node with two ancestors with a detached closed and closed shadow trees with an inner open shadow tree]
expected: FAIL
[Firing an event on a node with two ancestors with a detached closed and closed shadow trees with an inner closed shadow tree]
expected: FAIL
[Firing an event on a node within a open shadow tree that is itself a open shadow tree (the latter being the descendent of a host for a separate open shadow tree)]
expected: FAIL
[Firing an event on a node within a closed shadow tree that is itself a open shadow tree (the latter being the descendent of a host for a separate open shadow tree)]
expected: FAIL
[Firing an event on a node within a open shadow tree that is itself a closed shadow tree (the latter being the descendent of a host for a separate open shadow tree)]
expected: FAIL
[Firing an event on a node within a closed shadow tree that is itself a closed shadow tree (the latter being the descendent of a host for a separate open shadow tree)]
expected: FAIL
[Firing an event on a node within a open shadow tree that is itself a open shadow tree (the latter being the descendent of a host for a separate closed shadow tree)]
expected: FAIL
[Firing an event on a node within a closed shadow tree that is itself a open shadow tree (the latter being the descendent of a host for a separate closed shadow tree)]
expected: FAIL
[Firing an event on a node within a open shadow tree that is itself a closed shadow tree (the latter being the descendent of a host for a separate closed shadow tree)]
expected: FAIL
[Firing an event on a node within a closed shadow tree that is itself a closed shadow tree (the latter being the descendent of a host for a separate closed shadow tree)]
expected: FAIL

View file

@ -1,2 +1,2 @@
[focus-pseudo-on-shadow-host-2.html] [focus-pseudo-on-shadow-host-2.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +0,0 @@
[focus-pseudo-on-shadow-host-3.html]
expected: CRASH

View file

@ -1,2 +0,0 @@
[imperative-slot-api-crash.html]
expected: CRASH

View file

@ -1,2 +1,6 @@
[imperative-slot-fallback-clear.html] [imperative-slot-fallback-clear.html]
expected: CRASH [Text node fallback should be cleared in a subsequently layout]
expected: FAIL
[Element fallback should be cleared in a subsequent layout]
expected: FAIL

View file

@ -1,2 +1,2 @@
[imperative-slot-layout-invalidation-001.html] [imperative-slot-layout-invalidation-001.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +0,0 @@
[layout-slot-no-longer-assigned.html]
expected: CRASH

View file

@ -1,2 +0,0 @@
[layout-slot-no-longer-fallback.html]
expected: CRASH

View file

@ -1,2 +0,0 @@
[slot-fallback-content-001.html]
expected: CRASH

View file

@ -1,2 +0,0 @@
[slot-fallback-content-002.html]
expected: CRASH

View file

@ -1,2 +1,2 @@
[slot-fallback-content-004.html] [slot-fallback-content-004.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[slot-fallback-content-005.html] [slot-fallback-content-005.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[slot-fallback-content-006.html] [slot-fallback-content-006.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[slot-fallback-content-007.html] [slot-fallback-content-007.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[slot-fallback-content-008.html] [slot-fallback-content-008.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,96 @@
[slotchange-event.html] [slotchange-event.html]
expected: CRASH [slotchange event must fire on a default slot element inside an open shadow root in a document]
expected: FAIL
[slotchange event must fire on a default slot element inside a closed shadow root in a document]
expected: FAIL
[slotchange event must fire on a default slot element inside an open shadow root not in a document]
expected: FAIL
[slotchange event must fire on a default slot element inside a closed shadow root not in a document]
expected: FAIL
[slotchange event must fire on a named slot element insidean open shadow root in a document]
expected: FAIL
[slotchange event must fire on a named slot element insidea closed shadow root in a document]
expected: FAIL
[slotchange event must fire on a named slot element insidean open shadow root not in a document]
expected: FAIL
[slotchange event must fire on a named slot element insidea closed shadow root not in a document]
expected: FAIL
[slotchange event must not fire on a slot element inside an open shadow root in a document when another slot's assigned nodes change]
expected: FAIL
[slotchange event must not fire on a slot element inside a closed shadow root in a document when another slot's assigned nodes change]
expected: FAIL
[slotchange event must not fire on a slot element inside an open shadow root not in a document when another slot's assigned nodes change]
expected: FAIL
[slotchange event must not fire on a slot element inside a closed shadow root not in a document when another slot's assigned nodes change]
expected: FAIL
[slotchange event must fire on a slot element when a shadow host has a slottable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside an open shadow root in a document]
expected: FAIL
[slotchange event must fire on a slot element when a shadow host has a slottable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside a closed shadow root in a document]
expected: FAIL
[slotchange event must fire on a slot element when a shadow host has a slottable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside an open shadow root not in a document]
expected: FAIL
[slotchange event must fire on a slot element when a shadow host has a slottable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside a closed shadow root not in a document]
expected: FAIL
[slotchange event must fire on a slot element inside an open shadow root in a document even if the slot was removed immediately after the assigned nodes were mutated]
expected: FAIL
[slotchange event must fire on a slot element inside a closed shadow root in a document even if the slot was removed immediately after the assigned nodes were mutated]
expected: FAIL
[slotchange event must fire on a slot element inside an open shadow root not in a document even if the slot was removed immediately after the assigned nodes were mutated]
expected: FAIL
[slotchange event must fire on a slot element inside a closed shadow root not in a document even if the slot was removed immediately after the assigned nodes were mutated]
expected: FAIL
[slotchange event must fire on a slot element inside an open shadow root in a document when innerHTML modifies the children of the shadow host]
expected: FAIL
[slotchange event must fire on a slot element inside a closed shadow root in a document when innerHTML modifies the children of the shadow host]
expected: FAIL
[slotchange event must fire on a slot element inside an open shadow root not in a document when innerHTML modifies the children of the shadow host]
expected: FAIL
[slotchange event must fire on a slot element inside a closed shadow root not in a document when innerHTML modifies the children of the shadow host]
expected: FAIL
[slotchange event must fire on a slot element inside an open shadow root in a document when nested slots's contents change]
expected: FAIL
[slotchange event must fire on a slot element inside a closed shadow root in a document when nested slots's contents change]
expected: FAIL
[slotchange event must fire on a slot element inside an open shadow root not in a document when nested slots's contents change]
expected: FAIL
[slotchange event must fire on a slot element inside a closed shadow root not in a document when nested slots's contents change]
expected: FAIL
[slotchange event must fire at the end of current microtask after mutation observers are invoked inside an open shadow root in a document when slots's contents change]
expected: FAIL
[slotchange event must fire at the end of current microtask after mutation observers are invoked inside a closed shadow root in a document when slots's contents change]
expected: FAIL
[slotchange event must fire at the end of current microtask after mutation observers are invoked inside an open shadow root not in a document when slots's contents change]
expected: FAIL
[slotchange event must fire at the end of current microtask after mutation observers are invoked inside a closed shadow root not in a document when slots's contents change]
expected: FAIL

View file

@ -1,2 +1,3 @@
[slots-outside-shadow-dom.html] [slots-outside-shadow-dom.html]
expected: CRASH [Light DOM slot element should be in flattened assignedNodes]
expected: FAIL

View file

@ -1,2 +1,3 @@
[test-002.html] [test-002.html]
expected: CRASH [A_10_02_02_02_T01]
expected: FAIL

View file

@ -1,2 +0,0 @@
[test-003.html]
expected: CRASH

View file

@ -1,2 +0,0 @@
[test-001.html]
expected: CRASH

View file

@ -1,2 +1,2 @@
[reprojection-001.html] [reprojection-001.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,2 @@
[shadow-root-002.html] [shadow-root-002.html]
expected: CRASH expected: FAIL

View file

@ -1,2 +1,3 @@
[test-008.html] [test-008.html]
expected: CRASH [A_06_00_09_T01]
expected: FAIL

View file

@ -1,2 +0,0 @@
[test-001.html]
expected: CRASH

View file

@ -1,2 +1,6 @@
[test-002.html] [test-002.html]
expected: CRASH [A_07_01_02_T01]
expected: FAIL
[A_07_07_02_T02]
expected: FAIL