From 4242ff9626048942d72f0352c7f8a8edecdd6a08 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 6 Dec 2024 23:28:34 -0500 Subject: [PATCH] Make traverse_preorder follow shadow roots (#34503) * script: Ensure shadow-inclusve preorder traversals follow hosted shadow roots. Signed-off-by: Josh Matthews * script: Handle unregistering element id/name values inside of a shadow root. Signed-off-by: Josh Matthews * script: Merge shadow root tree iteration logic. Signed-off-by: Josh Matthews --------- Signed-off-by: Josh Matthews --- components/script/dom/element.rs | 16 +- components/script/dom/node.rs | 11 +- components/script/dom/shadowroot.rs | 7 - .../custom-elements/adopted-callback.html.ini | 42 - .../connected-callbacks.html.ini | 24 - .../custom-element-registry/upgrade.html.ini | 3 - .../disconnected-callbacks.html.ini | 24 - ...define-upgrade-criteria.tentative.html.ini | 3 - .../event-listeners.window.js.ini | 3 - .../shadow-dom/declarative/gethtml.html.ini | 20712 +++++++++++++++- .../getinnerhtml.tentative.html.ini | 1 - .../shadow-dom/input-element-list.html.ini | 2 - .../meta/shadow-dom/input-type-radio.html.ini | 2 - .../leaktests/window-frames.html.ini | 3 + .../window-named-properties-001.html.ini | 3 +- 15 files changed, 20733 insertions(+), 123 deletions(-) delete mode 100644 tests/wpt/meta/custom-elements/connected-callbacks.html.ini delete mode 100644 tests/wpt/meta/custom-elements/custom-element-registry/upgrade.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/input-element-list.html.ini delete mode 100644 tests/wpt/meta/shadow-dom/input-type-radio.html.ini create mode 100644 tests/wpt/meta/shadow-dom/leaktests/window-frames.html.ini diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 88963521d71..75f8f4d4b20 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -492,7 +492,7 @@ impl Element { self.ScrollWidth(can_gc) > self.ClientWidth(can_gc) } - fn shadow_root(&self) -> Option> { + pub(crate) fn shadow_root(&self) -> Option> { self.rare_data() .as_ref()? .shadow_root @@ -3632,19 +3632,21 @@ impl VirtualMethods for Element { let doc = document_from_node(self); - if let Some(ref shadow_root) = self.shadow_root() { - shadow_root.unbind_from_tree(context); - } - let fullscreen = doc.GetFullscreenElement(); if fullscreen.as_deref() == Some(self) { doc.exit_fullscreen(CanGc::note()); } if let Some(ref value) = *self.id_attribute.borrow() { - doc.unregister_element_id(self, value.clone()); + if let Some(ref shadow_root) = self.upcast::().containing_shadow_root() { + shadow_root.unregister_element_id(self, value.clone()); + } else { + doc.unregister_element_id(self, value.clone()); + } } if let Some(ref value) = self.name_attribute() { - doc.unregister_element_name(self, value.clone()); + if self.upcast::().containing_shadow_root().is_none() { + doc.unregister_element_name(self, value.clone()); + } } // This is used for layout optimization. doc.decrement_dom_count(); diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 04408a9248c..00501ea1718 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -1744,9 +1744,14 @@ impl Iterator for TreeIterator { fn next(&mut self) -> Option> { let current = self.current.take()?; - if !self.shadow_including { - if let Some(element) = current.downcast::() { - if element.is_shadow_host() { + // Handle a potential shadow root on the element + if let Some(element) = current.downcast::() { + if let Some(shadow_root) = element.shadow_root() { + if self.shadow_including { + self.current = Some(DomRoot::from_ref(shadow_root.upcast::())); + self.depth += 1; + return Some(current); + } else { return self.next_skipping_children_impl(current); } } diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index 58fb42b57da..da918ec0f51 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -315,13 +315,6 @@ impl VirtualMethods for ShadowRoot { let document = document_from_node(self); document.unregister_shadow_root(self); } - - let shadow_root = self.upcast::(); - shadow_root.set_flag(NodeFlags::IS_CONNECTED, false); - for node in shadow_root.children() { - node.set_flag(NodeFlags::IS_CONNECTED, false); - node.unbind_from_tree(context); - } } } diff --git a/tests/wpt/meta/custom-elements/adopted-callback.html.ini b/tests/wpt/meta/custom-elements/adopted-callback.html.ini index e6783ac9315..77d8f6821de 100644 --- a/tests/wpt/meta/custom-elements/adopted-callback.html.ini +++ b/tests/wpt/meta/custom-elements/adopted-callback.html.ini @@ -1,82 +1,40 @@ [adopted-callback.html] - [Inserting the shadow host of a custom element into the document of the template elements must enqueue and invoke adoptedCallback] - expected: FAIL - - [Moving the shadow host of a custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback] - expected: FAIL - [Moving the shadow host's shadow of a custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback] expected: FAIL [Moving the