add CanGc as argument to methods in HTMLCollection, HTMLDataListElement, HTMLDialogElement, HTMLElement, HTMLFieldSetElement, HTMLFormControlsCollection, HTMLFormElement, HTMLIFrameElement (#36495)

add CanGc as argument to methods in HTMLCollection, HTMLDataListElement,
HTMLDialogElement, HTMLElement, HTMLFieldSetElement,
HTMLFormControlsCollection, HTMLFormElement, HTMLIFrameElement

Testing: These changes do not require tests because they are a refactor.
Addresses part of https://github.com/servo/servo/issues/34573.

Signed-off-by: Yerkebulan Tulibergenov <yerkebulan@gmail.com>
This commit is contained in:
Yerkebulan Tulibergenov 2025-04-13 00:10:00 -07:00 committed by GitHub
parent 06f86f88a2
commit 3babf74986
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 69 additions and 60 deletions

View file

@ -209,7 +209,7 @@ pub(crate) fn handle_get_attribute_style(
reply.send(None).unwrap();
return;
};
let style = elem.Style();
let style = elem.Style(can_gc);
let msg = (0..style.Length())
.map(|i| {
@ -467,7 +467,7 @@ pub(crate) fn handle_modify_rule(
let elem = node
.downcast::<HTMLElement>()
.expect("This should be an HTMLElement");
let style = elem.Style();
let style = elem.Style(can_gc);
for modification in modifications {
let _ = style.SetProperty(

View file

@ -5929,6 +5929,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
self.window(),
self.upcast(),
Box::new(DocumentNamedGetter { name }),
CanGc::note(),
);
Some(NamedPropertyValue::HTMLCollection(collection))
}

View file

@ -141,8 +141,9 @@ impl HTMLCollection {
window: &Window,
root: &Node,
filter: Box<dyn CollectionFilter + 'static>,
can_gc: CanGc,
) -> DomRoot<Self> {
Self::new(window, root, filter, CanGc::note())
Self::new(window, root, filter, can_gc)
}
fn validate_cache(&self) {
@ -177,7 +178,7 @@ impl HTMLCollection {
window: &Window,
root: &Node,
qualified_name: LocalName,
_can_gc: CanGc,
can_gc: CanGc,
) -> DomRoot<HTMLCollection> {
// case 1
if qualified_name == local_name!("*") {
@ -188,7 +189,7 @@ impl HTMLCollection {
true
}
}
return HTMLCollection::create(window, root, Box::new(AllFilter));
return HTMLCollection::create(window, root, Box::new(AllFilter), can_gc);
}
#[derive(JSTraceable, MallocSizeOf)]
@ -214,7 +215,7 @@ impl HTMLCollection {
ascii_lower_qualified_name: qualified_name.to_ascii_lowercase(),
qualified_name,
};
HTMLCollection::create(window, root, Box::new(filter))
HTMLCollection::create(window, root, Box::new(filter), can_gc)
}
fn match_element(elem: &Element, qualified_name: &LocalName) -> bool {
@ -245,7 +246,7 @@ impl HTMLCollection {
window: &Window,
root: &Node,
qname: QualName,
_can_gc: CanGc,
can_gc: CanGc,
) -> DomRoot<HTMLCollection> {
#[derive(JSTraceable, MallocSizeOf)]
struct TagNameNSFilter {
@ -260,7 +261,7 @@ impl HTMLCollection {
}
}
let filter = TagNameNSFilter { qname };
HTMLCollection::create(window, root, Box::new(filter))
HTMLCollection::create(window, root, Box::new(filter), can_gc)
}
pub(crate) fn by_class_name(
@ -302,7 +303,7 @@ impl HTMLCollection {
}
let filter = ClassNameFilter { classes };
HTMLCollection::create(window, root, Box::new(filter))
HTMLCollection::create(window, root, Box::new(filter), can_gc)
}
pub(crate) fn children(window: &Window, root: &Node, can_gc: CanGc) -> DomRoot<HTMLCollection> {

View file

@ -53,12 +53,12 @@ impl HTMLDataListElement {
impl HTMLDataListElementMethods<crate::DomTypeHolder> for HTMLDataListElement {
// https://html.spec.whatwg.org/multipage/#dom-datalist-options
fn Options(&self) -> DomRoot<HTMLCollection> {
fn Options(&self, can_gc: CanGc) -> DomRoot<HTMLCollection> {
HTMLCollection::new_with_filter_fn(
&self.owner_window(),
self.upcast(),
|element, _| element.is::<HTMLOptionElement>(),
CanGc::note(),
can_gc,
)
}
}

View file

@ -122,7 +122,7 @@ impl HTMLDetailsElement {
.unwrap();
let fallback_summary =
HTMLElement::new(local_name!("summary"), None, &document, None, CanGc::note());
HTMLElement::new(local_name!("summary"), None, &document, None, can_gc);
fallback_summary
.upcast::<Node>()
.SetTextContent(Some(DEFAULT_SUMMARY.into()), can_gc);
@ -238,7 +238,7 @@ impl VirtualMethods for HTMLDetailsElement {
.attribute_mutated(attr, mutation, can_gc);
if attr.local_name() == &local_name!("open") {
self.update_shadow_tree_styles(CanGc::note());
self.update_shadow_tree_styles(can_gc);
let counter = self.toggle_counter.get() + 1;
self.toggle_counter.set(counter);

View file

@ -99,13 +99,13 @@ impl HTMLDialogElementMethods<crate::DomTypeHolder> for HTMLDialogElement {
}
// https://html.spec.whatwg.org/multipage/#dom-dialog-close
fn Close(&self, return_value: Option<DOMString>) {
fn Close(&self, return_value: Option<DOMString>, can_gc: CanGc) {
let element = self.upcast::<Element>();
let target = self.upcast::<EventTarget>();
// Step 1 & 2
if element
.remove_attribute(&ns!(), &local_name!("open"), CanGc::note())
.remove_attribute(&ns!(), &local_name!("open"), can_gc)
.is_none()
{
return;

View file

@ -138,7 +138,7 @@ impl HTMLElement {
impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
// https://html.spec.whatwg.org/multipage/#the-style-attribute
fn Style(&self) -> DomRoot<CSSStyleDeclaration> {
fn Style(&self, can_gc: CanGc) -> DomRoot<CSSStyleDeclaration> {
self.style_decl.or_init(|| {
let global = self.owner_window();
CSSStyleDeclaration::new(
@ -146,7 +146,7 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
CSSStyleOwner::Element(Dom::from_ref(self.upcast())),
None,
CSSModificationAccess::ReadWrite,
CanGc::note(),
can_gc,
)
})
}
@ -185,9 +185,8 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
document_and_element_event_handlers!();
// https://html.spec.whatwg.org/multipage/#dom-dataset
fn Dataset(&self) -> DomRoot<DOMStringMap> {
self.dataset
.or_init(|| DOMStringMap::new(self, CanGc::note()))
fn Dataset(&self, can_gc: CanGc) -> DomRoot<DOMStringMap> {
self.dataset.or_init(|| DOMStringMap::new(self, can_gc))
}
// https://html.spec.whatwg.org/multipage/#handler-onerror
@ -1145,7 +1144,7 @@ impl VirtualMethods for HTMLElement {
super_type.bind_to_tree(context, can_gc);
}
let element = self.as_element();
element.update_sequentially_focusable_status(CanGc::note());
element.update_sequentially_focusable_status(can_gc);
// Binding to a tree can disable a form control if one of the new
// ancestors is a fieldset.

View file

@ -87,7 +87,7 @@ impl HTMLFieldSetElement {
impl HTMLFieldSetElementMethods<crate::DomTypeHolder> for HTMLFieldSetElement {
// https://html.spec.whatwg.org/multipage/#dom-fieldset-elements
fn Elements(&self) -> DomRoot<HTMLCollection> {
fn Elements(&self, can_gc: CanGc) -> DomRoot<HTMLCollection> {
HTMLCollection::new_with_filter_fn(
&self.owner_window(),
self.upcast(),
@ -96,7 +96,7 @@ impl HTMLFieldSetElementMethods<crate::DomTypeHolder> for HTMLFieldSetElement {
.downcast::<HTMLElement>()
.is_some_and(HTMLElement::is_listed_element)
},
CanGc::note(),
can_gc,
)
}
@ -223,7 +223,7 @@ impl VirtualMethods for HTMLFieldSetElement {
);
}
}
element.update_sequentially_focusable_status(CanGc::note());
element.update_sequentially_focusable_status(can_gc);
}
} else {
for field in fields {
@ -244,10 +244,10 @@ impl VirtualMethods for HTMLFieldSetElement {
);
}
}
element.update_sequentially_focusable_status(CanGc::note());
element.update_sequentially_focusable_status(can_gc);
}
}
element.update_sequentially_focusable_status(CanGc::note());
element.update_sequentially_focusable_status(can_gc);
},
local_name!("form") => {
self.form_attribute_mutated(mutation, can_gc);

View file

@ -64,7 +64,7 @@ impl HTMLFormControlsCollectionMethods<crate::DomTypeHolder> for HTMLFormControl
}
// https://html.spec.whatwg.org/multipage/#dom-htmlformcontrolscollection-nameditem
fn NamedItem(&self, name: DOMString) -> Option<RadioNodeListOrElement> {
fn NamedItem(&self, name: DOMString, can_gc: CanGc) -> Option<RadioNodeListOrElement> {
// Step 1
if name.is_empty() {
return None;
@ -96,10 +96,7 @@ impl HTMLFormControlsCollectionMethods<crate::DomTypeHolder> for HTMLFormControl
// and the collection filter excludes image inputs.
Some(RadioNodeListOrElement::RadioNodeList(
RadioNodeList::new_controls_except_image_inputs(
window,
&self.form,
&name,
CanGc::note(),
window, &self.form, &name, can_gc,
),
))
}
@ -110,8 +107,8 @@ impl HTMLFormControlsCollectionMethods<crate::DomTypeHolder> for HTMLFormControl
}
// https://html.spec.whatwg.org/multipage/#dom-htmlformcontrolscollection-nameditem
fn NamedGetter(&self, name: DOMString) -> Option<RadioNodeListOrElement> {
self.NamedItem(name)
fn NamedGetter(&self, name: DOMString, can_gc: CanGc) -> Option<RadioNodeListOrElement> {
self.NamedItem(name, can_gc)
}
// https://html.spec.whatwg.org/multipage/#the-htmlformcontrolscollection-interface:supported-property-names

View file

@ -359,7 +359,7 @@ impl HTMLFormElementMethods<crate::DomTypeHolder> for HTMLFormElement {
}
// https://html.spec.whatwg.org/multipage/#dom-form-elements
fn Elements(&self) -> DomRoot<HTMLFormControlsCollection> {
fn Elements(&self, can_gc: CanGc) -> DomRoot<HTMLFormControlsCollection> {
#[derive(JSTraceable, MallocSizeOf)]
struct ElementsFilter {
form: DomRoot<HTMLFormElement>,
@ -422,35 +422,35 @@ impl HTMLFormElementMethods<crate::DomTypeHolder> for HTMLFormElement {
form: DomRoot::from_ref(self),
});
let window = self.owner_window();
HTMLFormControlsCollection::new(&window, self, filter, CanGc::note())
HTMLFormControlsCollection::new(&window, self, filter, can_gc)
}))
}
// https://html.spec.whatwg.org/multipage/#dom-form-length
fn Length(&self) -> u32 {
self.Elements().Length()
self.Elements(CanGc::note()).Length()
}
// https://html.spec.whatwg.org/multipage/#dom-form-item
fn IndexedGetter(&self, index: u32) -> Option<DomRoot<Element>> {
let elements = self.Elements();
fn IndexedGetter(&self, index: u32, can_gc: CanGc) -> Option<DomRoot<Element>> {
let elements = self.Elements(can_gc);
elements.IndexedGetter(index)
}
// https://html.spec.whatwg.org/multipage/#the-form-element%3Adetermine-the-value-of-a-named-property
fn NamedGetter(&self, name: DOMString) -> Option<RadioNodeListOrElement> {
fn NamedGetter(&self, name: DOMString, can_gc: CanGc) -> Option<RadioNodeListOrElement> {
let window = self.owner_window();
let name = Atom::from(name);
// Step 1
let mut candidates =
RadioNodeList::new_controls_except_image_inputs(&window, self, &name, CanGc::note());
RadioNodeList::new_controls_except_image_inputs(&window, self, &name, can_gc);
let mut candidates_length = candidates.Length();
// Step 2
if candidates_length == 0 {
candidates = RadioNodeList::new_images(&window, self, &name, CanGc::note());
candidates = RadioNodeList::new_images(&window, self, &name, can_gc);
candidates_length = candidates.Length();
}
@ -497,7 +497,7 @@ impl HTMLFormElementMethods<crate::DomTypeHolder> for HTMLFormElement {
}
// https://html.spec.whatwg.org/multipage/#dom-a-rellist
fn RelList(&self) -> DomRoot<DOMTokenList> {
fn RelList(&self, can_gc: CanGc) -> DomRoot<DOMTokenList> {
self.rel_list.or_init(|| {
DOMTokenList::new(
self.upcast(),
@ -507,7 +507,7 @@ impl HTMLFormElementMethods<crate::DomTypeHolder> for HTMLFormElement {
Atom::from("noreferrer"),
Atom::from("opener"),
]),
CanGc::note(),
can_gc,
)
})
}

View file

@ -590,7 +590,7 @@ impl HTMLIFrameElementMethods<crate::DomTypeHolder> for HTMLIFrameElement {
make_setter!(SetSrcdoc, "srcdoc");
// https://html.spec.whatwg.org/multipage/#dom-iframe-sandbox
fn Sandbox(&self) -> DomRoot<DOMTokenList> {
fn Sandbox(&self, can_gc: CanGc) -> DomRoot<DOMTokenList> {
self.sandbox.or_init(|| {
DOMTokenList::new(
self.upcast::<Element>(),
@ -603,7 +603,7 @@ impl HTMLIFrameElementMethods<crate::DomTypeHolder> for HTMLIFrameElement {
Atom::from("allow-scripts"),
Atom::from("allow-top-navigation"),
]),
CanGc::note(),
can_gc,
)
})
}
@ -718,7 +718,7 @@ impl VirtualMethods for HTMLIFrameElement {
// trigger the processing of iframe attributes whenever "srcdoc" attribute is set, changed or removed
if self.upcast::<Node>().is_connected_with_browsing_context() {
debug!("iframe srcdoc modified while in browsing context.");
self.process_the_iframe_attributes(ProcessingMode::NotFirstTime, CanGc::note());
self.process_the_iframe_attributes(ProcessingMode::NotFirstTime, can_gc);
}
},
local_name!("src") => {
@ -732,7 +732,7 @@ impl VirtualMethods for HTMLIFrameElement {
// the child browsing context to be created.
if self.upcast::<Node>().is_connected_with_browsing_context() {
debug!("iframe src set while in browsing context.");
self.process_the_iframe_attributes(ProcessingMode::NotFirstTime, CanGc::note());
self.process_the_iframe_attributes(ProcessingMode::NotFirstTime, can_gc);
}
},
_ => {},

View file

@ -1746,7 +1746,7 @@ impl VirtualMethods for HTMLImageElement {
fn adopting_steps(&self, old_doc: &Document, can_gc: CanGc) {
self.super_type().unwrap().adopting_steps(old_doc, can_gc);
self.update_the_image_data(CanGc::note());
self.update_the_image_data(can_gc);
}
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) {
@ -1759,7 +1759,7 @@ impl VirtualMethods for HTMLImageElement {
&local_name!("width") |
&local_name!("crossorigin") |
&local_name!("sizes") |
&local_name!("referrerpolicy") => self.update_the_image_data(CanGc::note()),
&local_name!("referrerpolicy") => self.update_the_image_data(can_gc),
_ => {},
}
}
@ -1777,7 +1777,7 @@ impl VirtualMethods for HTMLImageElement {
}
}
fn handle_event(&self, event: &Event, _can_gc: CanGc) {
fn handle_event(&self, event: &Event, can_gc: CanGc) {
if event.type_() != atom!("click") {
return;
}
@ -1798,9 +1798,7 @@ impl VirtualMethods for HTMLImageElement {
mouse_event.ClientX().to_f32().unwrap(),
mouse_event.ClientY().to_f32().unwrap(),
);
let bcr = self
.upcast::<Element>()
.GetBoundingClientRect(CanGc::note());
let bcr = self.upcast::<Element>().GetBoundingClientRect(can_gc);
let bcr_p = Point2D::new(bcr.X() as f32, bcr.Y() as f32);
// Walk HTMLAreaElements
@ -1811,7 +1809,7 @@ impl VirtualMethods for HTMLImageElement {
None => return,
};
if shp.hit_test(&point) {
element.activation_behavior(event, self.upcast(), CanGc::note());
element.activation_behavior(event, self.upcast(), can_gc);
return;
}
}
@ -1830,7 +1828,7 @@ impl VirtualMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#relevant-mutations
if let Some(parent) = self.upcast::<Node>().GetParentElement() {
if parent.is::<HTMLPictureElement>() {
self.update_the_image_data(CanGc::note());
self.update_the_image_data(can_gc);
}
}
}
@ -1843,7 +1841,7 @@ impl VirtualMethods for HTMLImageElement {
// The element is removed from a picture parent element
// https://html.spec.whatwg.org/multipage/#relevant-mutations
if context.parent.is::<HTMLPictureElement>() {
self.update_the_image_data(CanGc::note());
self.update_the_image_data(can_gc);
}
}
}

View file

@ -1626,6 +1626,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
self,
document.upcast(),
Box::new(WindowNamedGetter { name }),
CanGc::note(),
);
Some(NamedPropertyValue::HTMLCollection(collection))
}

View file

@ -338,24 +338,36 @@ DOMInterfaces = {
'canGc': ['CaptureStream', 'GetContext', 'SetHeight', 'SetWidth', 'TransferControlToOffscreen'],
},
'HTMLDataListElement': {
"canGc": ["Options"]
},
'HTMLDialogElement': {
'canGc': ['Show'],
'canGc': ['Close', 'Show'],
},
'HTMLElement': {
'canGc': ['AttachInternals', 'Focus', 'Blur', 'Click', 'SetInnerText', 'SetOuterText', "SetTranslate", 'SetAutofocus', 'GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText', 'GetOnerror', 'GetOnload', 'GetOnblur', 'GetOnfocus', 'GetOnresize', 'GetOnscroll'],
'canGc': ['AttachInternals', 'Focus', 'Blur', 'Click', 'SetInnerText', 'SetOuterText', "SetTranslate", 'SetAutofocus', 'GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText', 'GetOnerror', 'GetOnload', 'GetOnblur', 'GetOnfocus', 'GetOnresize', 'GetOnscroll', 'Style', 'Dataset'],
},
'HTMLFieldSetElement': {
'canGc': ['CheckValidity', 'ReportValidity'],
'canGc': ['CheckValidity', 'Elements', 'ReportValidity'],
},
'HTMLFontElement': {
'canGc': ['SetSize']
},
'HTMLFormControlsCollection': {
'canGc': ['NamedGetter', 'NamedItem'],
},
'HTMLFormElement': {
'canGc': ['CheckValidity', 'RequestSubmit', 'ReportValidity', 'Submit', 'Reset', 'SetRel'],
'canGc': ['CheckValidity', 'Elements', 'IndexedGetter', 'NamedGetter', 'RequestSubmit', 'ReportValidity', 'Submit', 'Reset', 'SetRel', 'RelList'],
},
'HTMLIFrameElement': {
'canGc': ['Sandbox'],
},
'HTMLImageElement': {