diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 977bff505dc..3f1bf1c450a 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -377,6 +377,8 @@ pub struct Document { delayed_tasks: DomRefCell>>, /// https://html.spec.whatwg.org/multipage/#completely-loaded completely_loaded: Cell, + /// List of shadow roots bound to the document tree. + shadow_roots: DomRefCell>>, } #[derive(JSTraceable, MallocSizeOf)] @@ -2680,6 +2682,7 @@ impl Document { completely_loaded: Cell::new(false), script_and_layout_blockers: Cell::new(0), delayed_tasks: Default::default(), + shadow_roots: DomRefCell::new(Vec::new()), } } @@ -3132,6 +3135,20 @@ impl Document { } } } + + pub fn register_shadow_root(&self, shadow_root: &ShadowRoot) { + self.shadow_roots + .borrow_mut() + .push(Dom::from_ref(shadow_root)); + } + + pub fn unregister_shadow_root(&self, shadow_root: &ShadowRoot) { + let mut shadow_roots = self.shadow_roots.borrow_mut(); + let position = shadow_roots.iter().position(|sr| **sr == *shadow_root); + if let Some(index) = position { + shadow_roots.remove(index); + } + } } impl Element { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 4b24ab84a90..7a69d4c781f 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -486,9 +486,13 @@ impl Element { } // Steps 4, 5 and 6. - Ok(self + let shadow_root = self .shadow_root - .or_init(|| ShadowRoot::new(self, &*self.node.owner_doc()))) + .or_init(|| ShadowRoot::new(self, &*self.node.owner_doc())); + + self.node.owner_doc().register_shadow_root(&*shadow_root); + + Ok(shadow_root) } } @@ -2787,8 +2791,9 @@ impl VirtualMethods for Element { return; } - if self.is_shadow_host() { - let shadow_root = self.shadow_root.get().unwrap(); + let doc = document_from_node(self); + + if let Some(shadow_root) = self.upcast::().owner_shadow_root() { let shadow_root = shadow_root.upcast::(); shadow_root.set_flag(NodeFlags::IS_CONNECTED, tree_connected); for node in shadow_root.children() { @@ -2797,7 +2802,6 @@ impl VirtualMethods for Element { } } - let doc = document_from_node(self); if let Some(ref value) = *self.id_attribute.borrow() { doc.register_named_element(self, value.clone()); } @@ -2816,8 +2820,12 @@ impl VirtualMethods for Element { return; } + let doc = document_from_node(self); + if self.is_shadow_host() { let shadow_root = self.shadow_root.get().unwrap(); + doc.unregister_shadow_root(&shadow_root); + let shadow_root = shadow_root.upcast::(); let shadow_root = shadow_root.upcast::(); shadow_root.set_flag(NodeFlags::IS_CONNECTED, false); for node in shadow_root.children() { @@ -2826,7 +2834,6 @@ impl VirtualMethods for Element { } } - let doc = document_from_node(self); let fullscreen = doc.GetFullscreenElement(); if fullscreen.deref() == Some(self) { doc.exit_fullscreen();