From 50c9c727788bfb3b7b108eacd404321542598530 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Thu, 19 Dec 2024 20:24:42 +0100 Subject: [PATCH] layout: Lay out Shadow DOM elements (#34701) When an element is a shadow root, lay out the shadow root elements instead of the non-shadow children. This fixes some tests and introduces some failures, due to bugs in the Shadow DOM implementation. In general, this is very low impact as the Shadow DOM is still disabled by default. At least this gets elements rendering when the preference is turned on though. Signed-off-by: Martin Robinson --- components/layout_2020/dom_traversal.rs | 5 +++++ components/script/dom/element.rs | 21 ++++++++++++------- ...nimation-shadow-slot-invalidation.html.ini | 2 -- .../css-content/quotes-slot-scoping.html.ini | 2 +- ...y-contents-shadow-host-whitespace.html.ini | 2 -- ...y-contents-slot-attach-whitespace.html.ini | 2 ++ .../file-selector-button-after-part.html.ini | 2 ++ ...ext-decoration-propagation-shadow.html.ini | 2 ++ tests/wpt/meta/dom/slot-recalc.html.ini | 2 -- .../2d.text-outside-of-the-flat-tree.html.ini | 2 +- .../cross-shadow-boundary-1.html.ini | 2 -- .../cross-shadow-boundary-2.html.ini | 2 -- .../cross-shadow-boundary-3.html.ini | 2 -- .../cross-shadow-boundary-4.html.ini | 2 -- .../cross-shadow-boundary-5.html.ini | 2 -- .../cross-shadow-boundary-img.html.ini | 2 -- ...s-shadow-boundary-select-document.html.ini | 2 -- ...cross-shadow-boundary-select-root.html.ini | 2 -- .../focus-pseudo-on-shadow-host-2.html.ini | 2 -- .../layout-slot-no-longer-fallback.html.ini | 2 ++ ...etParent-across-shadow-boundaries.html.ini | 12 ----------- ...hadow-style-invalidation-vw-units.html.ini | 2 -- .../slot-fallback-content-001.html.ini | 2 ++ .../slot-fallback-content-002.html.ini | 2 ++ .../slot-fallback-content-003.html.ini | 2 -- .../slot-fallback-content-004.html.ini | 2 -- .../slot-fallback-content-005.html.ini | 2 -- .../methods/test-002.html.ini | 3 --- .../nested_tree_reftest.html.ini | 2 -- .../shadow-trees/shadow-root-001.html.ini | 2 -- .../untriaged/styles/test-001.html.ini | 6 ------ 31 files changed, 32 insertions(+), 67 deletions(-) delete mode 100644 tests/wpt/meta/css/css-animations/cancel-animation-shadow-slot-invalidation.html.ini delete mode 100644 tests/wpt/meta/css/css-display/display-contents-shadow-host-whitespace.html.ini create mode 100644 tests/wpt/meta/css/css-display/display-contents-slot-attach-whitespace.html.ini create mode 100644 tests/wpt/meta/css/css-pseudo/file-selector-button-after-part.html.ini create mode 100644 tests/wpt/meta/css/css-text-decor/text-decoration-propagation-shadow.html.ini delete mode 100644 tests/wpt/meta/dom/slot-recalc.html.ini delete mode 100644 tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-1.html.ini delete mode 100644 tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-2.html.ini delete mode 100644 tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-3.html.ini delete mode 100644 tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-4.html.ini delete mode 100644 tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-5.html.ini delete mode 100644 tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-img.html.ini delete mode 100644 tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-select-document.html.ini delete mode 100644 tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-select-root.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/focus/focus-pseudo-on-shadow-host-2.html.ini create mode 100644 tests/wpt/meta/shadow-dom/layout-slot-no-longer-fallback.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/shadow-style-invalidation-vw-units.html.ini create mode 100644 tests/wpt/meta/shadow-dom/slot-fallback-content-001.html.ini create mode 100644 tests/wpt/meta/shadow-dom/slot-fallback-content-002.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/slot-fallback-content-003.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/slot-fallback-content-004.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/slot-fallback-content-005.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/untriaged/shadow-trees/shadow-root-001.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/untriaged/styles/test-001.html.ini diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs index f5f27fa7e08..7c7697be740 100644 --- a/components/layout_2020/dom_traversal.rs +++ b/components/layout_2020/dom_traversal.rs @@ -10,6 +10,7 @@ use script_layout_interface::wrapper_traits::{ThreadSafeLayoutElement, ThreadSaf use script_layout_interface::{LayoutElementType, LayoutNodeType}; use selectors::Element as SelectorsElement; use servo_arc::Arc as ServoArc; +use style::dom::{TElement, TShadowRoot}; use style::properties::ComputedValues; use style::selector_parser::PseudoElement; use style::values::generics::counters::{Content, ContentItem}; @@ -467,6 +468,10 @@ pub(crate) fn iter_child_nodes<'dom, Node>(parent: Node) -> impl Iterator, { + if let Some(shadow) = parent.as_element().and_then(|e| e.shadow_root()) { + return iter_child_nodes(shadow.as_node()); + }; + let mut next = parent.first_child(); std::iter::from_fn(move || { next.inspect(|child| { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 44838256cf5..2bef3e3508f 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -558,19 +558,24 @@ impl Element { }; shadow_root.bind_to_tree(&bind_context); - self.upcast::().dirty(NodeDamage::OtherNodeDamage); + let node = self.upcast::(); + node.dirty(NodeDamage::OtherNodeDamage); + node.rev_version(); Ok(shadow_root) } pub fn detach_shadow(&self) { - if let Some(ref shadow_root) = self.shadow_root() { - self.upcast::().note_dirty_descendants(); - shadow_root.detach(); - self.ensure_rare_data().shadow_root = None; - } else { - debug_assert!(false, "Trying to detach a non-attached shadow root"); - } + let Some(ref shadow_root) = self.shadow_root() else { + unreachable!("Trying to detach a non-attached shadow root"); + }; + + let node = self.upcast::(); + node.note_dirty_descendants(); + node.rev_version(); + + shadow_root.detach(); + self.ensure_rare_data().shadow_root = None; } // https://html.spec.whatwg.org/multipage/#translation-mode diff --git a/tests/wpt/meta/css/css-animations/cancel-animation-shadow-slot-invalidation.html.ini b/tests/wpt/meta/css/css-animations/cancel-animation-shadow-slot-invalidation.html.ini deleted file mode 100644 index 001271124aa..00000000000 --- a/tests/wpt/meta/css/css-animations/cancel-animation-shadow-slot-invalidation.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cancel-animation-shadow-slot-invalidation.html] - expected: TIMEOUT diff --git a/tests/wpt/meta/css/css-content/quotes-slot-scoping.html.ini b/tests/wpt/meta/css/css-content/quotes-slot-scoping.html.ini index 8edc9adb64f..d6d7a8fd026 100644 --- a/tests/wpt/meta/css/css-content/quotes-slot-scoping.html.ini +++ b/tests/wpt/meta/css/css-content/quotes-slot-scoping.html.ini @@ -1,2 +1,2 @@ [quotes-slot-scoping.html] - expected: PASS + expected: FAIL diff --git a/tests/wpt/meta/css/css-display/display-contents-shadow-host-whitespace.html.ini b/tests/wpt/meta/css/css-display/display-contents-shadow-host-whitespace.html.ini deleted file mode 100644 index 33b35202817..00000000000 --- a/tests/wpt/meta/css/css-display/display-contents-shadow-host-whitespace.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[display-contents-shadow-host-whitespace.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-display/display-contents-slot-attach-whitespace.html.ini b/tests/wpt/meta/css/css-display/display-contents-slot-attach-whitespace.html.ini new file mode 100644 index 00000000000..040a59456d7 --- /dev/null +++ b/tests/wpt/meta/css/css-display/display-contents-slot-attach-whitespace.html.ini @@ -0,0 +1,2 @@ +[display-contents-slot-attach-whitespace.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-pseudo/file-selector-button-after-part.html.ini b/tests/wpt/meta/css/css-pseudo/file-selector-button-after-part.html.ini new file mode 100644 index 00000000000..07bc9140696 --- /dev/null +++ b/tests/wpt/meta/css/css-pseudo/file-selector-button-after-part.html.ini @@ -0,0 +1,2 @@ +[file-selector-button-after-part.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-text-decor/text-decoration-propagation-shadow.html.ini b/tests/wpt/meta/css/css-text-decor/text-decoration-propagation-shadow.html.ini new file mode 100644 index 00000000000..74c4b81399e --- /dev/null +++ b/tests/wpt/meta/css/css-text-decor/text-decoration-propagation-shadow.html.ini @@ -0,0 +1,2 @@ +[text-decoration-propagation-shadow.html] + expected: FAIL diff --git a/tests/wpt/meta/dom/slot-recalc.html.ini b/tests/wpt/meta/dom/slot-recalc.html.ini deleted file mode 100644 index 887763d3d5f..00000000000 --- a/tests/wpt/meta/dom/slot-recalc.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[slot-recalc.html] - expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/2d.text-outside-of-the-flat-tree.html.ini b/tests/wpt/meta/html/canvas/element/2d.text-outside-of-the-flat-tree.html.ini index a41bcb75d55..e4c366d067c 100644 --- a/tests/wpt/meta/html/canvas/element/2d.text-outside-of-the-flat-tree.html.ini +++ b/tests/wpt/meta/html/canvas/element/2d.text-outside-of-the-flat-tree.html.ini @@ -1,2 +1,2 @@ [2d.text-outside-of-the-flat-tree.html] - expected: PASS + expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-1.html.ini b/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-1.html.ini deleted file mode 100644 index 7f1e8723d79..00000000000 --- a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-1.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-shadow-boundary-1.html] - expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-2.html.ini b/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-2.html.ini deleted file mode 100644 index 2aa9f3ec76b..00000000000 --- a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-2.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-shadow-boundary-2.html] - expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-3.html.ini b/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-3.html.ini deleted file mode 100644 index 794aa590c3b..00000000000 --- a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-3.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-shadow-boundary-3.html] - expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-4.html.ini b/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-4.html.ini deleted file mode 100644 index 243b26a8b7e..00000000000 --- a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-4.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-shadow-boundary-4.html] - expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-5.html.ini b/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-5.html.ini deleted file mode 100644 index 3391d915df4..00000000000 --- a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-5.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-shadow-boundary-5.html] - expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-img.html.ini b/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-img.html.ini deleted file mode 100644 index 0edbdcb6fa6..00000000000 --- a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-img.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-shadow-boundary-img.html] - expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-select-document.html.ini b/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-select-document.html.ini deleted file mode 100644 index 76283d07903..00000000000 --- a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-select-document.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-shadow-boundary-select-document.html] - expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-select-root.html.ini b/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-select-root.html.ini deleted file mode 100644 index 2bf190b10cc..00000000000 --- a/tests/wpt/meta/selection/shadow-dom/cross-shadow-boundary-select-root.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-shadow-boundary-select-root.html] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/focus/focus-pseudo-on-shadow-host-2.html.ini b/tests/wpt/meta/shadow-dom/focus/focus-pseudo-on-shadow-host-2.html.ini deleted file mode 100644 index 808653f1453..00000000000 --- a/tests/wpt/meta/shadow-dom/focus/focus-pseudo-on-shadow-host-2.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[focus-pseudo-on-shadow-host-2.html] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/layout-slot-no-longer-fallback.html.ini b/tests/wpt/meta/shadow-dom/layout-slot-no-longer-fallback.html.ini new file mode 100644 index 00000000000..0b6e3431ed9 --- /dev/null +++ b/tests/wpt/meta/shadow-dom/layout-slot-no-longer-fallback.html.ini @@ -0,0 +1,2 @@ +[layout-slot-no-longer-fallback.html] + expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/offsetParent-across-shadow-boundaries.html.ini b/tests/wpt/meta/shadow-dom/offsetParent-across-shadow-boundaries.html.ini index 6ec35fbbfa4..5df3c73d89c 100644 --- a/tests/wpt/meta/shadow-dom/offsetParent-across-shadow-boundaries.html.ini +++ b/tests/wpt/meta/shadow-dom/offsetParent-across-shadow-boundaries.html.ini @@ -1,16 +1,4 @@ [offsetParent-across-shadow-boundaries.html] - [offsetParent must return the offset parent in the same shadow tree of open mode] - expected: FAIL - - [offsetParent must return the offset parent in the same shadow tree of closed mode] - expected: FAIL - - [offsetParent must return the offset parent in the same shadow tree of open mode even when nested] - expected: FAIL - - [offsetParent must return the offset parent in the same shadow tree of closed mode even when nested] - expected: FAIL - [offsetParent must skip offset parents of an element when the context object is assigned to a slot in a shadow tree of open mode] expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/shadow-style-invalidation-vw-units.html.ini b/tests/wpt/meta/shadow-dom/shadow-style-invalidation-vw-units.html.ini deleted file mode 100644 index d79a6a7d952..00000000000 --- a/tests/wpt/meta/shadow-dom/shadow-style-invalidation-vw-units.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[shadow-style-invalidation-vw-units.html] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/slot-fallback-content-001.html.ini b/tests/wpt/meta/shadow-dom/slot-fallback-content-001.html.ini new file mode 100644 index 00000000000..99cfddb8bf3 --- /dev/null +++ b/tests/wpt/meta/shadow-dom/slot-fallback-content-001.html.ini @@ -0,0 +1,2 @@ +[slot-fallback-content-001.html] + expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/slot-fallback-content-002.html.ini b/tests/wpt/meta/shadow-dom/slot-fallback-content-002.html.ini new file mode 100644 index 00000000000..2ec0637e458 --- /dev/null +++ b/tests/wpt/meta/shadow-dom/slot-fallback-content-002.html.ini @@ -0,0 +1,2 @@ +[slot-fallback-content-002.html] + expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/slot-fallback-content-003.html.ini b/tests/wpt/meta/shadow-dom/slot-fallback-content-003.html.ini deleted file mode 100644 index 6bcd7a3f667..00000000000 --- a/tests/wpt/meta/shadow-dom/slot-fallback-content-003.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[slot-fallback-content-003.html] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/slot-fallback-content-004.html.ini b/tests/wpt/meta/shadow-dom/slot-fallback-content-004.html.ini deleted file mode 100644 index c333328c8e7..00000000000 --- a/tests/wpt/meta/shadow-dom/slot-fallback-content-004.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[slot-fallback-content-004.html] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/slot-fallback-content-005.html.ini b/tests/wpt/meta/shadow-dom/slot-fallback-content-005.html.ini deleted file mode 100644 index f3a768eb490..00000000000 --- a/tests/wpt/meta/shadow-dom/slot-fallback-content-005.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[slot-fallback-content-005.html] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html.ini b/tests/wpt/meta/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html.ini deleted file mode 100644 index 410d47668ae..00000000000 --- a/tests/wpt/meta/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[test-002.html] - [A_10_02_02_02_T01] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html.ini b/tests/wpt/meta/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html.ini deleted file mode 100644 index b6681ba0e7d..00000000000 --- a/tests/wpt/meta/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[nested_tree_reftest.html] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/untriaged/shadow-trees/shadow-root-001.html.ini b/tests/wpt/meta/shadow-dom/untriaged/shadow-trees/shadow-root-001.html.ini deleted file mode 100644 index 9fe59c6ff27..00000000000 --- a/tests/wpt/meta/shadow-dom/untriaged/shadow-trees/shadow-root-001.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[shadow-root-001.html] - expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/untriaged/styles/test-001.html.ini b/tests/wpt/meta/shadow-dom/untriaged/styles/test-001.html.ini deleted file mode 100644 index 010d6cf6e7b..00000000000 --- a/tests/wpt/meta/shadow-dom/untriaged/styles/test-001.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[test-001.html] - [A_06_00_01_T01] - expected: FAIL - - [A_06_00_01_T02] - expected: FAIL