From 40133ce29a4158d33a352dd6a20b7f4c0dbff018 Mon Sep 17 00:00:00 2001 From: Kunga Derick Abongho Date: Sat, 29 Mar 2025 14:12:14 +0100 Subject: [PATCH] Propagate CanGc arguments through HTMLCollection constructors (#36180) Signed-off-by: dericko681 --- components/script/dom/document.rs | 87 +++++++++++++------ components/script/dom/documentfragment.rs | 2 +- components/script/dom/element.rs | 13 ++- components/script/dom/htmlcollection.rs | 29 ++++--- components/script/dom/htmldatalistelement.rs | 9 +- components/script/dom/htmlfieldsetelement.rs | 15 ++-- components/script/dom/htmltableelement.rs | 1 + components/script/dom/htmltablerowelement.rs | 1 + .../script/dom/htmltablesectionelement.rs | 13 ++- components/script/script_thread.rs | 4 + components/script/webdriver_handlers.rs | 4 + 11 files changed, 125 insertions(+), 53 deletions(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 35635d6e58e..146ef3ffacb 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -4979,8 +4979,12 @@ impl DocumentMethods for Document { if let Some(entry) = self.tag_map.borrow_mut().get(&qualified_name) { return DomRoot::from_ref(entry); } - let result = - HTMLCollection::by_qualified_name(&self.window, self.upcast(), qualified_name.clone()); + let result = HTMLCollection::by_qualified_name( + &self.window, + self.upcast(), + qualified_name.clone(), + CanGc::note(), + ); self.tag_map .borrow_mut() .insert(qualified_name, Dom::from_ref(&*result)); @@ -4999,7 +5003,12 @@ impl DocumentMethods for Document { if let Some(collection) = self.tagns_map.borrow().get(&qname) { return DomRoot::from_ref(collection); } - let result = HTMLCollection::by_qual_tag_name(&self.window, self.upcast(), qname.clone()); + let result = HTMLCollection::by_qual_tag_name( + &self.window, + self.upcast(), + qname.clone(), + CanGc::note(), + ); self.tagns_map .borrow_mut() .insert(qname, Dom::from_ref(&*result)); @@ -5012,8 +5021,12 @@ impl DocumentMethods for Document { if let Some(collection) = self.classes_map.borrow().get(&class_atoms) { return DomRoot::from_ref(collection); } - let result = - HTMLCollection::by_atomic_class_name(&self.window, self.upcast(), class_atoms.clone()); + let result = HTMLCollection::by_atomic_class_name( + &self.window, + self.upcast(), + class_atoms.clone(), + CanGc::note(), + ); self.classes_map .borrow_mut() .insert(class_atoms, Dom::from_ref(&*result)); @@ -5489,18 +5502,24 @@ impl DocumentMethods for Document { // https://html.spec.whatwg.org/multipage/#dom-document-images fn Images(&self) -> DomRoot { self.images.or_init(|| { - HTMLCollection::new_with_filter_fn(&self.window, self.upcast(), |element, _| { - element.is::() - }) + HTMLCollection::new_with_filter_fn( + &self.window, + self.upcast(), + |element, _| element.is::(), + CanGc::note(), + ) }) } // https://html.spec.whatwg.org/multipage/#dom-document-embeds fn Embeds(&self) -> DomRoot { self.embeds.or_init(|| { - HTMLCollection::new_with_filter_fn(&self.window, self.upcast(), |element, _| { - element.is::() - }) + HTMLCollection::new_with_filter_fn( + &self.window, + self.upcast(), + |element, _| element.is::(), + CanGc::note(), + ) }) } @@ -5512,44 +5531,60 @@ impl DocumentMethods for Document { // https://html.spec.whatwg.org/multipage/#dom-document-links fn Links(&self) -> DomRoot { self.links.or_init(|| { - HTMLCollection::new_with_filter_fn(&self.window, self.upcast(), |element, _| { - (element.is::() || element.is::()) && - element.has_attribute(&local_name!("href")) - }) + HTMLCollection::new_with_filter_fn( + &self.window, + self.upcast(), + |element, _| { + (element.is::() || element.is::()) && + element.has_attribute(&local_name!("href")) + }, + CanGc::note(), + ) }) } // https://html.spec.whatwg.org/multipage/#dom-document-forms fn Forms(&self) -> DomRoot { self.forms.or_init(|| { - HTMLCollection::new_with_filter_fn(&self.window, self.upcast(), |element, _| { - element.is::() - }) + HTMLCollection::new_with_filter_fn( + &self.window, + self.upcast(), + |element, _| element.is::(), + CanGc::note(), + ) }) } // https://html.spec.whatwg.org/multipage/#dom-document-scripts fn Scripts(&self) -> DomRoot { self.scripts.or_init(|| { - HTMLCollection::new_with_filter_fn(&self.window, self.upcast(), |element, _| { - element.is::() - }) + HTMLCollection::new_with_filter_fn( + &self.window, + self.upcast(), + |element, _| element.is::(), + CanGc::note(), + ) }) } // https://html.spec.whatwg.org/multipage/#dom-document-anchors fn Anchors(&self) -> DomRoot { self.anchors.or_init(|| { - HTMLCollection::new_with_filter_fn(&self.window, self.upcast(), |element, _| { - element.is::() && element.has_attribute(&local_name!("href")) - }) + HTMLCollection::new_with_filter_fn( + &self.window, + self.upcast(), + |element, _| { + element.is::() && element.has_attribute(&local_name!("href")) + }, + CanGc::note(), + ) }) } // https://html.spec.whatwg.org/multipage/#dom-document-applets fn Applets(&self) -> DomRoot { self.applets - .or_init(|| HTMLCollection::always_empty(&self.window, self.upcast())) + .or_init(|| HTMLCollection::always_empty(&self.window, self.upcast(), CanGc::note())) } // https://html.spec.whatwg.org/multipage/#dom-document-location @@ -5563,7 +5598,7 @@ impl DocumentMethods for Document { // https://dom.spec.whatwg.org/#dom-parentnode-children fn Children(&self) -> DomRoot { - HTMLCollection::children(&self.window, self.upcast()) + HTMLCollection::children(&self.window, self.upcast(), CanGc::note()) } // https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild diff --git a/components/script/dom/documentfragment.rs b/components/script/dom/documentfragment.rs index 6a68ac4a36c..25c81b99664 100644 --- a/components/script/dom/documentfragment.rs +++ b/components/script/dom/documentfragment.rs @@ -78,7 +78,7 @@ impl DocumentFragmentMethods for DocumentFragment { // https://dom.spec.whatwg.org/#dom-parentnode-children fn Children(&self) -> DomRoot { let window = self.owner_window(); - HTMLCollection::children(&window, self.upcast()) + HTMLCollection::children(&window, self.upcast(), CanGc::note()) } // https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 4035f32e958..5ce2473585e 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -2616,7 +2616,12 @@ impl ElementMethods for Element { // https://dom.spec.whatwg.org/#dom-element-getelementsbytagname fn GetElementsByTagName(&self, localname: DOMString) -> DomRoot { let window = self.owner_window(); - HTMLCollection::by_qualified_name(&window, self.upcast(), LocalName::from(&*localname)) + HTMLCollection::by_qualified_name( + &window, + self.upcast(), + LocalName::from(&*localname), + CanGc::note(), + ) } // https://dom.spec.whatwg.org/#dom-element-getelementsbytagnamens @@ -2626,13 +2631,13 @@ impl ElementMethods for Element { localname: DOMString, ) -> DomRoot { let window = self.owner_window(); - HTMLCollection::by_tag_name_ns(&window, self.upcast(), localname, maybe_ns) + HTMLCollection::by_tag_name_ns(&window, self.upcast(), localname, maybe_ns, CanGc::note()) } // https://dom.spec.whatwg.org/#dom-element-getelementsbyclassname fn GetElementsByClassName(&self, classes: DOMString) -> DomRoot { let window = self.owner_window(); - HTMLCollection::by_class_name(&window, self.upcast(), classes) + HTMLCollection::by_class_name(&window, self.upcast(), classes, CanGc::note()) } // https://drafts.csswg.org/cssom-view/#dom-element-getclientrects @@ -3112,7 +3117,7 @@ impl ElementMethods for Element { // https://dom.spec.whatwg.org/#dom-parentnode-children fn Children(&self) -> DomRoot { let window = self.owner_window(); - HTMLCollection::children(&window, self.upcast()) + HTMLCollection::children(&window, self.upcast(), CanGc::note()) } // https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index 5558e2a2001..87b956ad623 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -87,7 +87,7 @@ impl HTMLCollection { } /// Returns a collection which is always empty. - pub(crate) fn always_empty(window: &Window, root: &Node) -> DomRoot { + pub(crate) fn always_empty(window: &Window, root: &Node, can_gc: CanGc) -> DomRoot { #[derive(JSTraceable)] struct NoFilter; impl CollectionFilter for NoFilter { @@ -96,7 +96,7 @@ impl HTMLCollection { } } - Self::new(window, root, Box::new(NoFilter), CanGc::note()) + Self::new(window, root, Box::new(NoFilter), can_gc) } #[cfg_attr(crown, allow(crown::unrooted_must_root))] @@ -114,6 +114,7 @@ impl HTMLCollection { window: &Window, root: &Node, filter_function: fn(&Element, &Node) -> bool, + can_gc: CanGc, ) -> DomRoot { #[derive(JSTraceable, MallocSizeOf)] pub(crate) struct StaticFunctionFilter( @@ -132,7 +133,7 @@ impl HTMLCollection { window, root, Box::new(StaticFunctionFilter(filter_function)), - CanGc::note(), + can_gc, ) } @@ -176,6 +177,7 @@ impl HTMLCollection { window: &Window, root: &Node, qualified_name: LocalName, + _can_gc: CanGc, ) -> DomRoot { // case 1 if qualified_name == local_name!("*") { @@ -231,17 +233,19 @@ impl HTMLCollection { root: &Node, tag: DOMString, maybe_ns: Option, + can_gc: CanGc, ) -> DomRoot { let local = LocalName::from(tag); let ns = namespace_from_domstring(maybe_ns); let qname = QualName::new(None, ns, local); - HTMLCollection::by_qual_tag_name(window, root, qname) + HTMLCollection::by_qual_tag_name(window, root, qname, can_gc) } pub(crate) fn by_qual_tag_name( window: &Window, root: &Node, qname: QualName, + _can_gc: CanGc, ) -> DomRoot { #[derive(JSTraceable, MallocSizeOf)] struct TagNameNSFilter { @@ -263,15 +267,17 @@ impl HTMLCollection { window: &Window, root: &Node, classes: DOMString, + can_gc: CanGc, ) -> DomRoot { let class_atoms = split_html_space_chars(&classes).map(Atom::from).collect(); - HTMLCollection::by_atomic_class_name(window, root, class_atoms) + HTMLCollection::by_atomic_class_name(window, root, class_atoms, can_gc) } pub(crate) fn by_atomic_class_name( window: &Window, root: &Node, classes: Vec, + can_gc: CanGc, ) -> DomRoot { #[derive(JSTraceable, MallocSizeOf)] struct ClassNameFilter { @@ -292,17 +298,20 @@ impl HTMLCollection { } if classes.is_empty() { - return HTMLCollection::always_empty(window, root); + return HTMLCollection::always_empty(window, root, can_gc); } let filter = ClassNameFilter { classes }; HTMLCollection::create(window, root, Box::new(filter)) } - pub(crate) fn children(window: &Window, root: &Node) -> DomRoot { - HTMLCollection::new_with_filter_fn(window, root, |element, root| { - root.is_parent_of(element.upcast()) - }) + pub(crate) fn children(window: &Window, root: &Node, can_gc: CanGc) -> DomRoot { + HTMLCollection::new_with_filter_fn( + window, + root, + |element, root| root.is_parent_of(element.upcast()), + can_gc, + ) } pub(crate) fn elements_iter_after<'a>( diff --git a/components/script/dom/htmldatalistelement.rs b/components/script/dom/htmldatalistelement.rs index 51fc9280ad8..a985ba0a927 100644 --- a/components/script/dom/htmldatalistelement.rs +++ b/components/script/dom/htmldatalistelement.rs @@ -54,8 +54,11 @@ impl HTMLDataListElement { impl HTMLDataListElementMethods for HTMLDataListElement { // https://html.spec.whatwg.org/multipage/#dom-datalist-options fn Options(&self) -> DomRoot { - HTMLCollection::new_with_filter_fn(&self.owner_window(), self.upcast(), |element, _| { - element.is::() - }) + HTMLCollection::new_with_filter_fn( + &self.owner_window(), + self.upcast(), + |element, _| element.is::(), + CanGc::note(), + ) } } diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs index d1e4c70f457..66d85eeedad 100644 --- a/components/script/dom/htmlfieldsetelement.rs +++ b/components/script/dom/htmlfieldsetelement.rs @@ -88,11 +88,16 @@ impl HTMLFieldSetElement { impl HTMLFieldSetElementMethods for HTMLFieldSetElement { // https://html.spec.whatwg.org/multipage/#dom-fieldset-elements fn Elements(&self) -> DomRoot { - HTMLCollection::new_with_filter_fn(&self.owner_window(), self.upcast(), |element, _| { - element - .downcast::() - .is_some_and(HTMLElement::is_listed_element) - }) + HTMLCollection::new_with_filter_fn( + &self.owner_window(), + self.upcast(), + |element, _| { + element + .downcast::() + .is_some_and(HTMLElement::is_listed_element) + }, + CanGc::note(), + ) } // https://html.spec.whatwg.org/multipage/#dom-fieldset-disabled diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index b1070a0491a..000816194ee 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -318,6 +318,7 @@ impl HTMLTableElementMethods for HTMLTableElement { element.local_name() == &local_name!("tbody") && element.upcast::().GetParentNode().as_deref() == Some(root) }, + CanGc::note(), ) }) } diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs index fe8a3febf81..a13238ca2e4 100644 --- a/components/script/dom/htmltablerowelement.rs +++ b/components/script/dom/htmltablerowelement.rs @@ -93,6 +93,7 @@ impl HTMLTableRowElementMethods for HTMLTableRowElement { (element.is::()) && element.upcast::().GetParentNode().as_deref() == Some(root) }, + CanGc::note(), ) }) } diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs index b5877a5e43c..d97e7445590 100644 --- a/components/script/dom/htmltablesectionelement.rs +++ b/components/script/dom/htmltablesectionelement.rs @@ -64,10 +64,15 @@ impl HTMLTableSectionElement { impl HTMLTableSectionElementMethods for HTMLTableSectionElement { // https://html.spec.whatwg.org/multipage/#dom-tbody-rows fn Rows(&self) -> DomRoot { - HTMLCollection::new_with_filter_fn(&self.owner_window(), self.upcast(), |element, root| { - element.is::() && - element.upcast::().GetParentNode().as_deref() == Some(root) - }) + HTMLCollection::new_with_filter_fn( + &self.owner_window(), + self.upcast(), + |element, root| { + element.is::() && + element.upcast::().GetParentNode().as_deref() == Some(root) + }, + CanGc::note(), + ) } // https://html.spec.whatwg.org/multipage/#dom-tbody-insertrow diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 3aa858467f6..147b22728dc 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2128,6 +2128,7 @@ impl ScriptThread { pipeline_id, selector, reply, + can_gc, ) }, WebDriverScriptCommand::FindElementsCSS(selector, reply) => { @@ -2153,6 +2154,7 @@ impl ScriptThread { pipeline_id, selector, reply, + can_gc, ) }, WebDriverScriptCommand::FindElementElementCSS(selector, element_id, reply) => { @@ -2184,6 +2186,7 @@ impl ScriptThread { element_id, selector, reply, + can_gc, ) }, WebDriverScriptCommand::FindElementElementsCSS(selector, element_id, reply) => { @@ -2215,6 +2218,7 @@ impl ScriptThread { element_id, selector, reply, + can_gc, ) }, WebDriverScriptCommand::FocusElement(element_id, reply) => { diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 0e942c404b4..ffb04b09e3a 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -551,6 +551,7 @@ pub(crate) fn handle_find_element_tag_name( pipeline: PipelineId, selector: String, reply: IpcSender, ErrorStatus>>, + _can_gc: CanGc, ) { reply .send( @@ -618,6 +619,7 @@ pub(crate) fn handle_find_elements_tag_name( pipeline: PipelineId, selector: String, reply: IpcSender, ErrorStatus>>, + _can_gc: CanGc, ) { reply .send( @@ -675,6 +677,7 @@ pub(crate) fn handle_find_element_element_tag_name( element_id: String, selector: String, reply: IpcSender, ErrorStatus>>, + _can_gc: CanGc, ) { reply .send( @@ -737,6 +740,7 @@ pub(crate) fn handle_find_element_elements_tag_name( element_id: String, selector: String, reply: IpcSender, ErrorStatus>>, + _can_gc: CanGc, ) { reply .send(