aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/layout_dom/element.rs
diff options
context:
space:
mode:
authorSimon Wülker <simon.wuelker@arcor.de>2025-01-28 22:04:32 +0100
committerGitHub <noreply@github.com>2025-01-28 21:04:32 +0000
commit1188d2b2e7c18434f06df5505bed7cfd859f47e2 (patch)
tree6610915adec04c368f355e7b1e973f4ae2a84a00 /components/script/layout_dom/element.rs
parent7f1eefc182d1f11b6558d0fbffdfb184cab69ea3 (diff)
downloadservo-1188d2b2e7c18434f06df5505bed7cfd859f47e2.tar.gz
servo-1188d2b2e7c18434f06df5505bed7cfd859f47e2.zip
Never compute style for children of shadow hosts (#35198)
There is some interesting history to this change: * https://github.com/servo/servo/issues/33495: Servo crashes on Cloudflare's turnstile, because we didn't compute style for elements inside shadow trees * https://github.com/servo/servo/pull/34298: Resolves the issue by computing style for children of a potential shadow root, in addition to the children of an element * https://github.com/servo/servo/pull/34701: Changes layout of elements with shadow roots such that only the contents of the shadow root are laid out Now, we compute style for both the children of the element and a potential shadow root, but only lay out the contents of the shadow tree (if there is one). This behaviour is not technically incorrect, since regular children are not included in layout their style doesn't matter. However, it is inefficient: the only case where we need to compute style for a child of a shadow host is when that child is an assigned slottable in a slot somewhere else. This part 1/n of upstreaming the changes necessary to lay out `<slot>` contents. Note that trying to compute style for `<slot>` contents *and* children of shadow hosts will crash in stylo, since it expects to see each element only once. Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Diffstat (limited to 'components/script/layout_dom/element.rs')
-rw-r--r--components/script/layout_dom/element.rs31
1 files changed, 6 insertions, 25 deletions
diff --git a/components/script/layout_dom/element.rs b/components/script/layout_dom/element.rs
index 5c5a6da9677..45ff4450542 100644
--- a/components/script/layout_dom/element.rs
+++ b/components/script/layout_dom/element.rs
@@ -140,41 +140,22 @@ 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> {
type ConcreteNode = ServoLayoutNode<'dom>;
- type TraversalChildrenIterator = DomChildrenIncludingShadowDom<Self::ConcreteNode>;
+ type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>;
fn as_node(&self) -> ServoLayoutNode<'dom> {
ServoLayoutNode::from_layout_js(self.element.upcast())
}
fn traversal_children(&self) -> LayoutIterator<Self::TraversalChildrenIterator> {
- let children = DomChildrenIncludingShadowDom {
- children: self.as_node().dom_children(),
- children_in_shadow_root: self
- .shadow_root()
- .map(|shadow| shadow.as_node().dom_children()),
+ let iterator = if let Some(shadow_root) = self.shadow_root() {
+ shadow_root.as_node().dom_children()
+ } else {
+ self.as_node().dom_children()
};
- LayoutIterator(children)
+ LayoutIterator(iterator)
}
fn is_html_element(&self) -> bool {