From 83da63f638b15009b842a1f712fa5116f0e2d466 Mon Sep 17 00:00:00 2001 From: Kunga Derick Abongho Date: Sat, 29 Mar 2025 14:09:56 +0100 Subject: [PATCH] resolve issue #36074 new_js_regex and matches_js_regex need a CanGc argument (#36111) * new_js_regex and matches_js_regex need a CanGc argument Signed-off-by: dericko681 * new_js_regex and matches_js_regex need a CanGc argument Signed-off-by: dericko681 * edit Propagate CanGc arguments through new_js_regex and matches_js_regex Signed-off-by: dericko681 * Propagate CanGc arguments through new_js_regex and matches_js_regex Signed-off-by: dericko681 * Propagate CanGc arguments through new_js_regex and matches_js_regex Signed-off-by: dericko681 * Propagate CanGc arguments through new_js_regex and matches_js_regex Signed-off-by: dericko681 --------- Signed-off-by: dericko681 --- components/script/dom/attr.rs | 11 +- components/script/dom/characterdata.rs | 2 +- .../script/dom/customelementregistry.rs | 2 +- components/script/dom/document.rs | 20 +-- components/script/dom/documenttype.rs | 2 +- components/script/dom/domstringmap.rs | 2 +- components/script/dom/element.rs | 141 +++++++++++------- components/script/dom/elementinternals.rs | 2 +- components/script/dom/event.rs | 2 +- components/script/dom/htmlanchorelement.rs | 10 +- components/script/dom/htmlareaelement.rs | 10 +- components/script/dom/htmlbaseelement.rs | 14 +- components/script/dom/htmlbodyelement.rs | 10 +- components/script/dom/htmlbuttonelement.rs | 22 +-- components/script/dom/htmlcanvaselement.rs | 6 +- components/script/dom/htmldetailselement.rs | 12 +- components/script/dom/htmldialogelement.rs | 2 +- components/script/dom/htmlelement.rs | 31 ++-- components/script/dom/htmlfieldsetelement.rs | 12 +- components/script/dom/htmlformelement.rs | 54 +++---- components/script/dom/htmlheadelement.rs | 4 +- components/script/dom/htmliframeelement.rs | 10 +- components/script/dom/htmlimageelement.rs | 20 +-- components/script/dom/htmlinputelement.rs | 41 ++--- components/script/dom/htmllabelelement.rs | 8 +- components/script/dom/htmllegendelement.rs | 8 +- components/script/dom/htmllinkelement.rs | 14 +- components/script/dom/htmlmediaelement.rs | 20 +-- components/script/dom/htmlmetaelement.rs | 12 +- components/script/dom/htmlmeterelement.rs | 10 +- components/script/dom/htmlobjectelement.rs | 8 +- components/script/dom/htmloptgroupelement.rs | 22 +-- components/script/dom/htmloptionelement.rs | 30 ++-- .../script/dom/htmloptionscollection.rs | 4 +- components/script/dom/htmloutputelement.rs | 8 +- components/script/dom/htmlprogresselement.rs | 10 +- components/script/dom/htmlscriptelement.rs | 9 +- components/script/dom/htmlselectelement.rs | 28 ++-- components/script/dom/htmlslotelement.rs | 14 +- components/script/dom/htmlsourceelement.rs | 14 +- components/script/dom/htmlstyleelement.rs | 12 +- components/script/dom/htmltableelement.rs | 59 +++++--- components/script/dom/htmltablerowelement.rs | 8 +- .../script/dom/htmltablesectionelement.rs | 8 +- components/script/dom/htmltemplateelement.rs | 9 +- components/script/dom/htmltextareaelement.rs | 41 ++--- components/script/dom/htmltitleelement.rs | 4 +- components/script/dom/htmlvideoelement.rs | 6 +- components/script/dom/namednodemap.rs | 4 +- components/script/dom/node.rs | 121 +++++++++------ components/script/dom/range.rs | 8 +- .../script/dom/servoparser/async_html.rs | 2 +- components/script/dom/servoparser/mod.rs | 4 +- components/script/dom/shadowroot.rs | 31 ++-- components/script/dom/svgsvgelement.rs | 6 +- components/script/dom/validation.rs | 6 +- components/script/dom/validitystate.rs | 18 ++- components/script/dom/virtualmethods.rs | 24 +-- components/script/script_thread.rs | 2 +- components/script/webdriver_handlers.rs | 1 + 60 files changed, 600 insertions(+), 435 deletions(-) diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 428f02cece3..a488b11c3c7 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -115,7 +115,7 @@ impl AttrMethods for Attr { fn SetValue(&self, value: DOMString) { if let Some(owner) = self.owner() { let value = owner.parse_attribute(self.namespace(), self.local_name(), value); - self.set_value(value, &owner); + self.set_value(value, &owner, CanGc::note()); } else { *self.value.borrow_mut() = AttrValue::String(value.into()); } @@ -153,7 +153,7 @@ impl AttrMethods for Attr { } impl Attr { - pub(crate) fn set_value(&self, mut value: AttrValue, owner: &Element) { + pub(crate) fn set_value(&self, mut value: AttrValue, owner: &Element, can_gc: CanGc) { let name = self.local_name().clone(); let namespace = self.namespace().clone(); let old_value = DOMString::from(&**self.value()); @@ -180,8 +180,11 @@ impl Attr { owner.will_mutate_attr(self); self.swap_value(&mut value); if *self.namespace() == ns!() { - vtable_for(owner.upcast()) - .attribute_mutated(self, AttributeMutation::Set(Some(&value))); + vtable_for(owner.upcast()).attribute_mutated( + self, + AttributeMutation::Set(Some(&value)), + can_gc, + ); } } diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index f61deba4044..fe677a6b7b2 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -262,7 +262,7 @@ impl CharacterDataMethods for CharacterData { // https://dom.spec.whatwg.org/#dom-childnode-remove fn Remove(&self) { let node = self.upcast::(); - node.remove_self(); + node.remove_self(CanGc::note()); } // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index 8738ce883d2..049e3c482a1 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -878,7 +878,7 @@ pub(crate) fn upgrade_element( // We know this element is is form-associated, so we can use the implementation of // `FormControl` for HTMLElement, which makes that assumption. // Step 9.1: Reset the form owner of element - html_element.reset_form_owner(); + html_element.reset_form_owner(can_gc); if let Some(form) = html_element.form_owner() { // Even though the tree hasn't structurally mutated, // HTMLCollections need to be invalidated. diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 4945892ef60..35635d6e58e 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -920,14 +920,14 @@ impl Document { } /// Remove any existing association between the provided id and any elements in this document. - pub(crate) fn unregister_element_id(&self, to_unregister: &Element, id: Atom) { + pub(crate) fn unregister_element_id(&self, to_unregister: &Element, id: Atom, can_gc: CanGc) { self.document_or_shadow_root .unregister_named_element(&self.id_map, to_unregister, &id); - self.reset_form_owner_for_listeners(&id); + self.reset_form_owner_for_listeners(&id, can_gc); } /// Associate an element present in this document with the provided id. - pub(crate) fn register_element_id(&self, element: &Element, id: Atom) { + pub(crate) fn register_element_id(&self, element: &Element, id: Atom, can_gc: CanGc) { let root = self.GetDocumentElement().expect( "The element is in the document, so there must be a document \ element.", @@ -938,7 +938,7 @@ impl Document { &id, DomRoot::from_ref(root.upcast::()), ); - self.reset_form_owner_for_listeners(&id); + self.reset_form_owner_for_listeners(&id, can_gc); } /// Remove any existing association between the provided name and any elements in this document. @@ -3265,10 +3265,10 @@ impl Document { id } - pub(crate) fn unregister_media_controls(&self, id: &str) { + pub(crate) fn unregister_media_controls(&self, id: &str, can_gc: CanGc) { if let Some(ref media_controls) = self.media_controls.borrow_mut().remove(id) { let media_controls = DomRoot::from_ref(&**media_controls); - media_controls.Host().detach_shadow(); + media_controls.Host().detach_shadow(can_gc); } else { debug_assert!(false, "Trying to unregister unknown media controls"); } @@ -4512,14 +4512,14 @@ impl Document { } } - fn reset_form_owner_for_listeners(&self, id: &Atom) { + fn reset_form_owner_for_listeners(&self, id: &Atom, can_gc: CanGc) { let map = self.form_id_listener_map.borrow(); if let Some(listeners) = map.get(id) { for listener in listeners { listener .as_maybe_form_control() .expect("Element must be a form control") - .reset_form_owner(); + .reset_form_owner(can_gc); } } } @@ -5234,7 +5234,7 @@ impl DocumentMethods for Document { } // Step 3. - Node::adopt(node, self); + Node::adopt(node, self, CanGc::note()); // Step 4. Ok(DomRoot::from_ref(node)) @@ -5945,7 +5945,7 @@ impl DocumentMethods for Document { } // Step 11. Replace all with null within document. - Node::replace_all(None, self.upcast::()); + Node::replace_all(None, self.upcast::(), can_gc); // Specs and tests are in a state of flux about whether // we want to clear the selection when we remove the contents; diff --git a/components/script/dom/documenttype.rs b/components/script/dom/documenttype.rs index a2382e4faa7..bd7471baf3a 100644 --- a/components/script/dom/documenttype.rs +++ b/components/script/dom/documenttype.rs @@ -104,6 +104,6 @@ impl DocumentTypeMethods for DocumentType { // https://dom.spec.whatwg.org/#dom-childnode-remove fn Remove(&self) { - self.upcast::().remove_self(); + self.upcast::().remove_self(CanGc::note()); } } diff --git a/components/script/dom/domstringmap.rs b/components/script/dom/domstringmap.rs index 710a77305d4..c285fa9fd48 100644 --- a/components/script/dom/domstringmap.rs +++ b/components/script/dom/domstringmap.rs @@ -40,7 +40,7 @@ impl DOMStringMap { impl DOMStringMapMethods for DOMStringMap { // https://html.spec.whatwg.org/multipage/#dom-domstringmap-removeitem fn NamedDeleter(&self, name: DOMString) { - self.element.delete_custom_attr(name) + self.element.delete_custom_attr(name, CanGc::note()) } // https://html.spec.whatwg.org/multipage/#dom-domstringmap-setitem diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 99e686eaaa1..4035f32e958 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -566,7 +566,7 @@ impl Element { // Step 4.3.1. Remove all of currentShadowRoot’s children, in tree order. for child in current_shadow_root.upcast::().children() { - child.remove_self(); + child.remove_self(can_gc); } // Step 4.3.2. Set currentShadowRoot’s declarative to false. @@ -621,7 +621,7 @@ impl Element { tree_is_in_a_document_tree: self.upcast::().is_in_a_document_tree(), tree_is_in_a_shadow_tree: true, }; - shadow_root.bind_to_tree(&bind_context); + shadow_root.bind_to_tree(&bind_context, can_gc); let node = self.upcast::(); node.dirty(NodeDamage::OtherNodeDamage); @@ -630,7 +630,7 @@ impl Element { Ok(shadow_root) } - pub(crate) fn detach_shadow(&self) { + pub(crate) fn detach_shadow(&self, can_gc: CanGc) { let Some(ref shadow_root) = self.shadow_root() else { unreachable!("Trying to detach a non-attached shadow root"); }; @@ -639,7 +639,7 @@ impl Element { node.note_dirty_descendants(); node.rev_version(); - shadow_root.detach(); + shadow_root.detach(can_gc); self.ensure_rare_data().shadow_root = None; } @@ -1635,10 +1635,10 @@ impl Element { Some(self), can_gc, ); - self.push_attribute(&attr); + self.push_attribute(&attr, can_gc); } - pub(crate) fn push_attribute(&self, attr: &Attr) { + pub(crate) fn push_attribute(&self, attr: &Attr, can_gc: CanGc) { let name = attr.local_name().clone(); let namespace = attr.namespace().clone(); let mutation = LazyCell::new(|| Mutation::Attribute { @@ -1659,7 +1659,7 @@ impl Element { self.will_mutate_attr(attr); self.attrs.borrow_mut().push(Dom::from_ref(attr)); if attr.namespace() == &ns!() { - vtable_for(self.upcast()).attribute_mutated(attr, AttributeMutation::Set(None)); + vtable_for(self.upcast()).attribute_mutated(attr, AttributeMutation::Set(None), can_gc); } } @@ -1788,7 +1788,7 @@ impl Element { .find(|attr| find(attr)) .map(|js| DomRoot::from_ref(&**js)); if let Some(attr) = attr { - attr.set_value(value, self); + attr.set_value(value, self, can_gc); } else { self.push_new_attribute(local_name, value, name, namespace, prefix, can_gc); }; @@ -1811,17 +1811,23 @@ impl Element { &self, namespace: &Namespace, local_name: &LocalName, + can_gc: CanGc, ) -> Option> { - self.remove_first_matching_attribute(|attr| { - attr.namespace() == namespace && attr.local_name() == local_name - }) + self.remove_first_matching_attribute( + |attr| attr.namespace() == namespace && attr.local_name() == local_name, + can_gc, + ) } - pub(crate) fn remove_attribute_by_name(&self, name: &LocalName) -> Option> { - self.remove_first_matching_attribute(|attr| attr.name() == name) + pub(crate) fn remove_attribute_by_name( + &self, + name: &LocalName, + can_gc: CanGc, + ) -> Option> { + self.remove_first_matching_attribute(|attr| attr.name() == name, can_gc) } - fn remove_first_matching_attribute(&self, find: F) -> Option> + fn remove_first_matching_attribute(&self, find: F, can_gc: CanGc) -> Option> where F: Fn(&Attr) -> bool, { @@ -1850,7 +1856,11 @@ impl Element { self.attrs.borrow_mut().remove(idx); attr.set_owner(None); if attr.namespace() == &ns!() { - vtable_for(self.upcast()).attribute_mutated(&attr, AttributeMutation::Removed); + vtable_for(self.upcast()).attribute_mutated( + &attr, + AttributeMutation::Removed, + can_gc, + ); } attr }) @@ -1892,7 +1902,7 @@ impl Element { if value { self.set_string_attribute(local_name, DOMString::new(), can_gc); } else { - self.remove_attribute(&ns!(), local_name); + self.remove_attribute(&ns!(), local_name, can_gc); } } @@ -1961,7 +1971,7 @@ impl Element { self.set_string_attribute(local_name, val, can_gc); }, None => { - self.remove_attribute(&ns!(), local_name); + self.remove_attribute(&ns!(), local_name, can_gc); }, } } @@ -2056,23 +2066,31 @@ impl Element { &self, where_: AdjacentPosition, node: &Node, + can_gc: CanGc, ) -> Fallible>> { let self_node = self.upcast::(); match where_ { AdjacentPosition::BeforeBegin => { if let Some(parent) = self_node.GetParentNode() { - Node::pre_insert(node, &parent, Some(self_node)).map(Some) + Node::pre_insert(node, &parent, Some(self_node), can_gc).map(Some) } else { Ok(None) } }, - AdjacentPosition::AfterBegin => { - Node::pre_insert(node, self_node, self_node.GetFirstChild().as_deref()).map(Some) + AdjacentPosition::AfterBegin => Node::pre_insert( + node, + self_node, + self_node.GetFirstChild().as_deref(), + can_gc, + ) + .map(Some), + AdjacentPosition::BeforeEnd => { + Node::pre_insert(node, self_node, None, can_gc).map(Some) }, - AdjacentPosition::BeforeEnd => Node::pre_insert(node, self_node, None).map(Some), AdjacentPosition::AfterEnd => { if let Some(parent) = self_node.GetParentNode() { - Node::pre_insert(node, &parent, self_node.GetNextSibling().as_deref()).map(Some) + Node::pre_insert(node, &parent, self_node.GetNextSibling().as_deref(), can_gc) + .map(Some) } else { Ok(None) } @@ -2437,7 +2455,7 @@ impl ElementMethods for Element { Some(_index) => match force { // Step 5. None | Some(false) => { - self.remove_attribute_by_name(&name); + self.remove_attribute_by_name(&name, can_gc); Ok(false) }, // Step 6. @@ -2542,7 +2560,11 @@ impl ElementMethods for Element { self.attrs.borrow_mut()[position] = Dom::from_ref(attr); old_attr.set_owner(None); if attr.namespace() == &ns!() { - vtable.attribute_mutated(attr, AttributeMutation::Set(Some(&old_attr.value()))); + vtable.attribute_mutated( + attr, + AttributeMutation::Set(Some(&old_attr.value())), + CanGc::note(), + ); } // Step 6. @@ -2550,7 +2572,7 @@ impl ElementMethods for Element { } else { // Step 5. attr.set_owner(Some(self)); - self.push_attribute(attr); + self.push_attribute(attr, CanGc::note()); // Step 6. Ok(None) @@ -2565,19 +2587,19 @@ impl ElementMethods for Element { // https://dom.spec.whatwg.org/#dom-element-removeattribute fn RemoveAttribute(&self, name: DOMString) { let name = self.parsed_name(name); - self.remove_attribute_by_name(&name); + self.remove_attribute_by_name(&name, CanGc::note()); } // https://dom.spec.whatwg.org/#dom-element-removeattributens fn RemoveAttributeNS(&self, namespace: Option, local_name: DOMString) { let namespace = namespace_from_domstring(namespace); let local_name = LocalName::from(local_name); - self.remove_attribute(&namespace, &local_name); + self.remove_attribute(&namespace, &local_name, CanGc::note()); } // https://dom.spec.whatwg.org/#dom-element-removeattributenode fn RemoveAttributeNode(&self, attr: &Attr) -> Fallible> { - self.remove_first_matching_attribute(|a| a == attr) + self.remove_first_matching_attribute(|a| a == attr, CanGc::note()) .ok_or(Error::NotFound) } @@ -2951,7 +2973,7 @@ impl ElementMethods for Element { } // Replace all with fragment within target. - Node::replace_all(Some(frag.upcast()), &target); + Node::replace_all(Some(frag.upcast()), &target, can_gc); } /// @@ -3013,7 +3035,7 @@ impl ElementMethods for Element { // Step 1. let frag = self.parse_fragment(value, can_gc)?; - Node::replace_all(Some(frag.upcast()), &target); + Node::replace_all(Some(frag.upcast()), &target, can_gc); Ok(()) } @@ -3155,7 +3177,7 @@ impl ElementMethods for Element { // https://dom.spec.whatwg.org/#dom-childnode-remove fn Remove(&self) { - self.upcast::().remove_self(); + self.upcast::().remove_self(CanGc::note()); } // https://dom.spec.whatwg.org/#dom-element-matches @@ -3213,7 +3235,7 @@ impl ElementMethods for Element { element: &Element, ) -> Fallible>> { let where_ = where_.parse::()?; - let inserted_node = self.insert_adjacent(where_, element.upcast())?; + let inserted_node = self.insert_adjacent(where_, element.upcast(), CanGc::note())?; Ok(inserted_node.map(|node| DomRoot::downcast(node).unwrap())) } @@ -3224,7 +3246,8 @@ impl ElementMethods for Element { // Step 2. let where_ = where_.parse::()?; - self.insert_adjacent(where_, text.upcast()).map(|_| ()) + self.insert_adjacent(where_, text.upcast(), can_gc) + .map(|_| ()) } // https://w3c.github.io/DOM-Parsing/#dom-element-insertadjacenthtml @@ -3263,7 +3286,7 @@ impl ElementMethods for Element { let fragment = context.parse_fragment(text, can_gc)?; // Step 4. - self.insert_adjacent(position, fragment.upcast()) + self.insert_adjacent(position, fragment.upcast(), can_gc) .map(|_| ()) } @@ -3713,8 +3736,10 @@ impl VirtualMethods for Element { .attribute_affects_presentational_hints(attr) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); let node = self.upcast::(); let doc = node.owner_doc(); match attr.local_name() { @@ -3776,25 +3801,25 @@ impl VirtualMethods for Element { if let Some(old_value) = old_value { let old_value = old_value.as_atom().clone(); if let Some(ref shadow_root) = containing_shadow_root { - shadow_root.unregister_element_id(self, old_value); + shadow_root.unregister_element_id(self, old_value, can_gc); } else { - doc.unregister_element_id(self, old_value); + doc.unregister_element_id(self, old_value, can_gc); } } if value != atom!("") { if let Some(ref shadow_root) = containing_shadow_root { - shadow_root.register_element_id(self, value); + shadow_root.register_element_id(self, value, can_gc); } else { - doc.register_element_id(self, value); + doc.register_element_id(self, value, can_gc); } } }, AttributeMutation::Removed => { if value != atom!("") { if let Some(ref shadow_root) = containing_shadow_root { - shadow_root.unregister_element_id(self, value); + shadow_root.unregister_element_id(self, value, can_gc); } else { - doc.unregister_element_id(self, value); + doc.unregister_element_id(self, value, can_gc); } } }, @@ -3873,19 +3898,19 @@ impl VirtualMethods for Element { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } if let Some(f) = self.as_maybe_form_control() { - f.bind_form_control_to_tree(); + f.bind_form_control_to_tree(can_gc); } let doc = self.owner_document(); if let Some(ref shadow_root) = self.shadow_root() { - shadow_root.bind_to_tree(context); + shadow_root.bind_to_tree(context, can_gc); } if !context.is_in_tree() { @@ -3896,9 +3921,9 @@ impl VirtualMethods for Element { if let Some(ref id) = *self.id_attribute.borrow() { if let Some(shadow_root) = self.containing_shadow_root() { - shadow_root.register_element_id(self, id.clone()); + shadow_root.register_element_id(self, id.clone(), can_gc); } else { - doc.register_element_id(self, id.clone()); + doc.register_element_id(self, id.clone(), can_gc); } } if let Some(ref name) = self.name_attribute() { @@ -3911,14 +3936,14 @@ impl VirtualMethods for Element { doc.increment_dom_count(); } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); if let Some(f) = self.as_maybe_form_control() { // TODO: The valid state of ancestors might be wrong if the form control element // has a fieldset ancestor, for instance: `
`, // if `` is unbound, `
` should trigger a call to `update_validity()`. - f.unbind_form_control_from_tree(); + f.unbind_form_control_from_tree(can_gc); } if !context.tree_is_in_a_document_tree && !context.tree_is_in_a_shadow_tree { @@ -3938,10 +3963,10 @@ impl VirtualMethods for Element { // Only unregister the element id if the node was disconnected from it's shadow root // (as opposed to the whole shadow tree being disconnected as a whole) if !self.upcast::().is_in_a_shadow_tree() { - shadow_root.unregister_element_id(self, value.clone()); + shadow_root.unregister_element_id(self, value.clone(), can_gc); } } else { - doc.unregister_element_id(self, value.clone()); + doc.unregister_element_id(self, value.clone(), can_gc); } } if let Some(ref value) = self.name_attribute() { @@ -3980,8 +4005,8 @@ impl VirtualMethods for Element { } } - fn adopting_steps(&self, old_doc: &Document) { - self.super_type().unwrap().adopting_steps(old_doc); + fn adopting_steps(&self, old_doc: &Document, can_gc: CanGc) { + self.super_type().unwrap().adopting_steps(old_doc, can_gc); if self.owner_document().is_html_document() != old_doc.is_html_document() { self.tag_name.clear(); @@ -4426,12 +4451,12 @@ impl Element { element } - pub(crate) fn is_invalid(&self, needs_update: bool) -> bool { + pub(crate) fn is_invalid(&self, needs_update: bool, can_gc: CanGc) -> bool { if let Some(validatable) = self.as_maybe_validatable() { if needs_update { validatable .validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } return validatable.is_instance_validatable() && !validatable.satisfies_constraints(); } @@ -4844,7 +4869,7 @@ pub(crate) fn set_cross_origin_attribute( match value { Some(val) => element.set_string_attribute(&local_name!("crossorigin"), val, can_gc), None => { - element.remove_attribute(&ns!(), &local_name!("crossorigin")); + element.remove_attribute(&ns!(), &local_name!("crossorigin"), can_gc); }, } } diff --git a/components/script/dom/elementinternals.rs b/components/script/dom/elementinternals.rs index 966a4dc1e3e..bb3795b5bab 100644 --- a/components/script/dom/elementinternals.rs +++ b/components/script/dom/elementinternals.rs @@ -253,7 +253,7 @@ impl ElementInternalsMethods for ElementInternals { // Step 4: For each entry `flag` → `value` of `flags`, set element's validity flag with the name // `flag` to `value`. self.validity_state().update_invalid_flags(bits); - self.validity_state().update_pseudo_classes(); + self.validity_state().update_pseudo_classes(CanGc::note()); // Step 5: Set element's validation message to the empty string if message is not given // or all of element's validity flags are false, or to message otherwise. diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index 1347713f489..0ced6c40b16 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -584,7 +584,7 @@ impl Event { if let Some(target) = self.GetTarget() { if let Some(node) = target.downcast::() { let vtable = vtable_for(node); - vtable.handle_event(self); + vtable.handle_event(self, can_gc); } } } diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 2dc968ce049..511d4fe7d95 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -100,8 +100,10 @@ impl VirtualMethods for HTMLAnchorElement { } } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("rel") | local_name!("rev") => { @@ -112,9 +114,9 @@ impl VirtualMethods for HTMLAnchorElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.relations diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs index 95254650174..1d80078b246 100644 --- a/components/script/dom/htmlareaelement.rs +++ b/components/script/dom/htmlareaelement.rs @@ -321,8 +321,10 @@ impl VirtualMethods for HTMLAreaElement { } } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("rel") | local_name!("rev") => { @@ -333,9 +335,9 @@ impl VirtualMethods for HTMLAreaElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.relations diff --git a/components/script/dom/htmlbaseelement.rs b/components/script/dom/htmlbaseelement.rs index abe45ee7110..45a13f83772 100644 --- a/components/script/dom/htmlbaseelement.rs +++ b/components/script/dom/htmlbaseelement.rs @@ -117,20 +117,22 @@ impl VirtualMethods for HTMLBaseElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if *attr.local_name() == local_name!("href") { self.owner_document().refresh_base_element(); } } - fn bind_to_tree(&self, context: &BindContext) { - self.super_type().unwrap().bind_to_tree(context); + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { + self.super_type().unwrap().bind_to_tree(context, can_gc); self.bind_unbind(context.tree_is_in_a_document_tree); } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); self.bind_unbind(context.tree_is_in_a_document_tree); } } diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index 8ff01d220f2..ba3316f889b 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -141,9 +141,9 @@ impl VirtualMethods for HTMLBodyElement { .attribute_affects_presentational_hints(attr) } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } if !context.tree_is_in_a_document_tree { @@ -176,7 +176,7 @@ impl VirtualMethods for HTMLBodyElement { } } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { let do_super_mutate = match (attr.local_name(), mutation) { (name, AttributeMutation::Set(_)) if name.starts_with("on") => { let window = self.owner_window(); @@ -218,7 +218,9 @@ impl VirtualMethods for HTMLBodyElement { }; if do_super_mutate { - self.super_type().unwrap().attribute_mutated(attr, mutation); + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); } } } diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index 24af541f554..6916bef126c 100644 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -242,8 +242,10 @@ impl VirtualMethods for HTMLButtonElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("disabled") => { let el = self.upcast::(); @@ -261,7 +263,7 @@ impl VirtualMethods for HTMLButtonElement { } el.update_sequentially_focusable_status(CanGc::note()); self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); }, local_name!("type") => match mutation { AttributeMutation::Set(_) => { @@ -272,32 +274,32 @@ impl VirtualMethods for HTMLButtonElement { }; self.button_type.set(value); self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); }, AttributeMutation::Removed => { self.button_type.set(ButtonType::Submit); }, }, local_name!("form") => { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); self.validity_state() - .perform_validation_and_update(ValidationFlags::empty()); + .perform_validation_and_update(ValidationFlags::empty(), can_gc); }, _ => {}, } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.upcast::() .check_ancestors_disabled_state_for_form_control(); } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); let node = self.upcast::(); let el = self.upcast::(); diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 37d7aa91f90..7c5a5dd4725 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -698,8 +698,10 @@ impl VirtualMethods for HTMLCanvasElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match attr.local_name() { &local_name!("width") | &local_name!("height") => self.recreate_contexts_after_resize(), _ => (), diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs index 2a0f5b9d0dc..0752da270b8 100644 --- a/components/script/dom/htmldetailselement.rs +++ b/components/script/dom/htmldetailselement.rs @@ -122,7 +122,7 @@ impl HTMLDetailsElement { .unwrap(); let fallback_summary = - HTMLElement::new(local_name!("summary"), None, &document, None, can_gc); + HTMLElement::new(local_name!("summary"), None, &document, None, CanGc::note()); fallback_summary .upcast::() .SetTextContent(Some(DEFAULT_SUMMARY.into()), can_gc); @@ -232,8 +232,10 @@ impl VirtualMethods for HTMLDetailsElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if attr.local_name() == &local_name!("open") { self.update_shadow_tree_styles(CanGc::note()); @@ -261,8 +263,8 @@ impl VirtualMethods for HTMLDetailsElement { self.update_shadow_tree_contents(CanGc::note()); } - fn bind_to_tree(&self, context: &BindContext) { - self.super_type().unwrap().bind_to_tree(context); + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { + self.super_type().unwrap().bind_to_tree(context, can_gc); self.update_shadow_tree_contents(CanGc::note()); self.update_shadow_tree_styles(CanGc::note()); diff --git a/components/script/dom/htmldialogelement.rs b/components/script/dom/htmldialogelement.rs index 949dfef0a53..6974288e4d3 100644 --- a/components/script/dom/htmldialogelement.rs +++ b/components/script/dom/htmldialogelement.rs @@ -105,7 +105,7 @@ impl HTMLDialogElementMethods for HTMLDialogElement { // Step 1 & 2 if element - .remove_attribute(&ns!(), &local_name!("open")) + .remove_attribute(&ns!(), &local_name!("open"), CanGc::note()) .is_none() { return; diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index aa72b536683..5b11b3bae98 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -499,7 +499,7 @@ impl HTMLElementMethods for HTMLElement { let fragment = self.rendered_text_fragment(input, can_gc); // Step 2: Replace all with fragment within element. - Node::replace_all(Some(fragment.upcast()), self.upcast::()); + Node::replace_all(Some(fragment.upcast()), self.upcast::(), can_gc); } /// @@ -542,13 +542,13 @@ impl HTMLElementMethods for HTMLElement { // the next text node given next's previous sibling. if let Some(next_sibling) = next { if let Some(node) = next_sibling.GetPreviousSibling() { - Self::merge_with_the_next_text_node(node); + Self::merge_with_the_next_text_node(node, can_gc); } } // Step 8: If previous is a Text node, then merge with the next text node given previous. if let Some(previous) = previous { - Self::merge_with_the_next_text_node(previous) + Self::merge_with_the_next_text_node(previous, can_gc) } Ok(()) @@ -758,10 +758,11 @@ impl HTMLElement { }) } - pub(crate) fn delete_custom_attr(&self, local_name: DOMString) { + pub(crate) fn delete_custom_attr(&self, local_name: DOMString, can_gc: CanGc) { // FIXME(ajeffrey): Convert directly from DOMString to LocalName let local_name = LocalName::from(to_snake_case(local_name)); - self.as_element().remove_attribute(&ns!(), &local_name); + self.as_element() + .remove_attribute(&ns!(), &local_name, can_gc); } /// @@ -1039,7 +1040,7 @@ impl HTMLElement { /// node. /// /// - fn merge_with_the_next_text_node(node: DomRoot) { + fn merge_with_the_next_text_node(node: DomRoot, can_gc: CanGc) { // Make sure node is a Text node if !node.is::() { return; @@ -1063,7 +1064,7 @@ impl HTMLElement { .expect("Got chars from Text"); // Step 4:Remove next. - next.remove_self(); + next.remove_self(can_gc); } } @@ -1072,8 +1073,10 @@ impl VirtualMethods for HTMLElement { Some(self.as_element() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); let element = self.as_element(); match (attr.local_name(), mutation) { (name, AttributeMutation::Set(_)) if name.starts_with("on") => { @@ -1088,7 +1091,7 @@ impl VirtualMethods for HTMLElement { ); }, (&local_name!("form"), mutation) if self.is_form_associated_custom_element() => { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); }, // Adding a "disabled" attribute disables an enabled form element. (&local_name!("disabled"), AttributeMutation::Set(_)) @@ -1132,9 +1135,9 @@ impl VirtualMethods for HTMLElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(super_type) = self.super_type() { - super_type.bind_to_tree(context); + super_type.bind_to_tree(context, can_gc); } let element = self.as_element(); element.update_sequentially_focusable_status(CanGc::note()); @@ -1153,9 +1156,9 @@ impl VirtualMethods for HTMLElement { } } - fn unbind_from_tree(&self, context: &UnbindContext) { + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { if let Some(super_type) = self.super_type() { - super_type.unbind_from_tree(context); + super_type.unbind_from_tree(context, can_gc); } // Unbinding from a tree might enable a form control, if a diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs index 13e09c4125e..d1e4c70f457 100644 --- a/components/script/dom/htmlfieldsetelement.rs +++ b/components/script/dom/htmlfieldsetelement.rs @@ -71,12 +71,12 @@ impl HTMLFieldSetElement { ) } - pub(crate) fn update_validity(&self) { + pub(crate) fn update_validity(&self, can_gc: CanGc) { let has_invalid_child = self .upcast::() .traverse_preorder(ShadowIncluding::No) .flat_map(DomRoot::downcast::) - .any(|element| element.is_invalid(false)); + .any(|element| element.is_invalid(false, can_gc)); self.upcast::() .set_state(ElementState::VALID, !has_invalid_child); @@ -153,8 +153,10 @@ impl VirtualMethods for HTMLFieldSetElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("disabled") => { let disabled_state = match mutation { @@ -243,7 +245,7 @@ impl VirtualMethods for HTMLFieldSetElement { element.update_sequentially_focusable_status(CanGc::note()); }, local_name!("form") => { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); }, _ => {}, } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index c8431fdf365..8e788f289ec 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -712,9 +712,11 @@ impl HTMLFormElement { result } - pub(crate) fn update_validity(&self) { + pub(crate) fn update_validity(&self, can_gc: CanGc) { let controls = self.controls.borrow(); - let is_any_invalid = controls.iter().any(|control| control.is_invalid(false)); + let is_any_invalid = controls + .iter() + .any(|control| control.is_invalid(false, can_gc)); self.upcast::() .set_state(ElementState::VALID, !is_any_invalid); @@ -1087,7 +1089,7 @@ impl HTMLFormElement { .iter() .filter_map(|field| { if let Some(element) = field.downcast::() { - if element.is_invalid(true) { + if element.is_invalid(true, can_gc) { Some(DomRoot::from_ref(element)) } else { None @@ -1306,17 +1308,17 @@ impl HTMLFormElement { self.marked_for_reset.set(false); } - fn add_control(&self, control: &T) { + fn add_control(&self, control: &T, can_gc: CanGc) { { let root = self.upcast::().root_element(); let root = root.upcast::(); let mut controls = self.controls.borrow_mut(); controls.insert_pre_order(control.to_element(), root); } - self.update_validity(); + self.update_validity(can_gc); } - fn remove_control(&self, control: &T) { + fn remove_control(&self, control: &T, can_gc: CanGc) { { let control = control.to_element(); let mut controls = self.controls.borrow_mut(); @@ -1332,7 +1334,7 @@ impl HTMLFormElement { let mut past_names_map = self.past_names_map.borrow_mut(); past_names_map.0.retain(|_k, v| v.0 != control); } - self.update_validity(); + self.update_validity(can_gc); } } @@ -1518,16 +1520,16 @@ pub(crate) trait FormControl: DomObject { // Part of step 12. // '..suppress the running of the reset the form owner algorithm // when the parser subsequently attempts to insert the element..' - fn set_form_owner_from_parser(&self, form: &HTMLFormElement) { + fn set_form_owner_from_parser(&self, form: &HTMLFormElement, can_gc: CanGc) { let elem = self.to_element(); let node = elem.upcast::(); node.set_flag(NodeFlags::PARSER_ASSOCIATED_FORM_OWNER, true); - form.add_control(self); + form.add_control(self, can_gc); self.set_form_owner(Some(form)); } // https://html.spec.whatwg.org/multipage/#reset-the-form-owner - fn reset_form_owner(&self) { + fn reset_form_owner(&self, can_gc: CanGc) { let elem = self.to_element(); let node = elem.upcast::(); let old_owner = self.form_owner(); @@ -1558,10 +1560,10 @@ pub(crate) trait FormControl: DomObject { if old_owner != new_owner { if let Some(o) = old_owner { - o.remove_control(self); + o.remove_control(self, can_gc); } if let Some(ref new_owner) = new_owner { - new_owner.add_control(self); + new_owner.add_control(self, can_gc); } // https://html.spec.whatwg.org/multipage/#custom-element-reactions:reset-the-form-owner if let Some(html_elem) = elem.downcast::() { @@ -1580,7 +1582,7 @@ pub(crate) trait FormControl: DomObject { } // https://html.spec.whatwg.org/multipage/#association-of-controls-and-forms - fn form_attribute_mutated(&self, mutation: AttributeMutation) { + fn form_attribute_mutated(&self, mutation: AttributeMutation, can_gc: CanGc) { match mutation { AttributeMutation::Set(_) => { self.register_if_necessary(); @@ -1590,7 +1592,7 @@ pub(crate) trait FormControl: DomObject { }, } - self.reset_form_owner(); + self.reset_form_owner(can_gc); } // https://html.spec.whatwg.org/multipage/#association-of-controls-and-forms @@ -1616,7 +1618,7 @@ pub(crate) trait FormControl: DomObject { } // https://html.spec.whatwg.org/multipage/#association-of-controls-and-forms - fn bind_form_control_to_tree(&self) { + fn bind_form_control_to_tree(&self, can_gc: CanGc) { let elem = self.to_element(); let node = elem.upcast::(); @@ -1628,12 +1630,12 @@ pub(crate) trait FormControl: DomObject { node.set_flag(NodeFlags::PARSER_ASSOCIATED_FORM_OWNER, false); if !must_skip_reset { - self.form_attribute_mutated(AttributeMutation::Set(None)); + self.form_attribute_mutated(AttributeMutation::Set(None), can_gc); } } // https://html.spec.whatwg.org/multipage/#association-of-controls-and-forms - fn unbind_form_control_from_tree(&self) { + fn unbind_form_control_from_tree(&self, can_gc: CanGc) { let elem = self.to_element(); let has_form_attr = elem.has_attribute(&local_name!("form")); let same_subtree = self @@ -1648,7 +1650,7 @@ pub(crate) trait FormControl: DomObject { // subtree) if it appears later in the tree order. Hence invoke // reset from here if this control has the form attribute set. if !same_subtree || (self.is_listed() && has_form_attr) { - self.reset_form_owner(); + self.reset_form_owner(can_gc); } } @@ -1698,8 +1700,8 @@ impl VirtualMethods for HTMLFormElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); // Collect the controls to reset because reset_form_owner // will mutably borrow self.controls @@ -1716,7 +1718,7 @@ impl VirtualMethods for HTMLFormElement { control .as_maybe_form_control() .expect("Element must be a form control") - .reset_form_owner(); + .reset_form_owner(can_gc); } } @@ -1730,8 +1732,10 @@ impl VirtualMethods for HTMLFormElement { } } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("rel") | local_name!("rev") => { @@ -1742,9 +1746,9 @@ impl VirtualMethods for HTMLFormElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.relations diff --git a/components/script/dom/htmlheadelement.rs b/components/script/dom/htmlheadelement.rs index bfd092c894f..51b2c025982 100644 --- a/components/script/dom/htmlheadelement.rs +++ b/components/script/dom/htmlheadelement.rs @@ -132,9 +132,9 @@ impl VirtualMethods for HTMLHeadElement { fn super_type(&self) -> Option<&dyn VirtualMethods> { Some(self.upcast::() as &dyn VirtualMethods) } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } load_script(self); } diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 2c0041124cf..dd4277d18cb 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -676,8 +676,10 @@ impl VirtualMethods for HTMLIFrameElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("sandbox") => { self.sandbox_allowance @@ -761,8 +763,8 @@ impl VirtualMethods for HTMLIFrameElement { } } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); let blocker = &self.load_blocker; LoadBlocker::terminate(blocker, CanGc::note()); diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 382b3e439cd..bec3b2018f7 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -1743,13 +1743,15 @@ impl VirtualMethods for HTMLImageElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn adopting_steps(&self, old_doc: &Document) { - self.super_type().unwrap().adopting_steps(old_doc); + 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()); } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match attr.local_name() { &local_name!("src") | &local_name!("srcset") | @@ -1774,7 +1776,7 @@ impl VirtualMethods for HTMLImageElement { } } - fn handle_event(&self, event: &Event) { + fn handle_event(&self, event: &Event, _can_gc: CanGc) { if event.type_() != atom!("click") { return; } @@ -1814,9 +1816,9 @@ impl VirtualMethods for HTMLImageElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } let document = self.owner_document(); if context.tree_connected { @@ -1832,8 +1834,8 @@ impl VirtualMethods for HTMLImageElement { } } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); let document = self.owner_document(); document.unregister_responsive_image(self); diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 401abac60ed..abeb806d54d 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -1340,7 +1340,7 @@ impl HTMLInputElementMethods for HTMLInputElement { } self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); self.upcast::().dirty(NodeDamage::OtherNodeDamage); Ok(()) } @@ -2322,8 +2322,10 @@ impl VirtualMethods for HTMLInputElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("disabled") => { let disabled_state = match mutation { @@ -2513,13 +2515,13 @@ impl VirtualMethods for HTMLInputElement { } }, local_name!("form") => { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); }, _ => {}, } self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { @@ -2540,21 +2542,21 @@ impl VirtualMethods for HTMLInputElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.upcast::() .check_ancestors_disabled_state_for_form_control(); for r in radio_group_iter(self, self.radio_group_name().as_ref()) { r.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); let node = self.upcast::(); let el = self.upcast::(); @@ -2568,7 +2570,7 @@ impl VirtualMethods for HTMLInputElement { } self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } // This represents behavior for which the UIEvents spec and the @@ -2576,9 +2578,9 @@ impl VirtualMethods for HTMLInputElement { // Compare: // https://w3c.github.io/uievents/#default-action // https://dom.spec.whatwg.org/#action-versus-occurance - fn handle_event(&self, event: &Event) { + fn handle_event(&self, event: &Event, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.handle_event(event); + s.handle_event(event, can_gc); } if event.type_() == atom!("click") && !event.DefaultPrevented() { @@ -2679,7 +2681,7 @@ impl VirtualMethods for HTMLInputElement { } self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } // https://html.spec.whatwg.org/multipage/#the-input-element%3Aconcept-node-clone-ext @@ -2688,9 +2690,10 @@ impl VirtualMethods for HTMLInputElement { copy: &Node, maybe_doc: Option<&Document>, clone_children: CloneChildrenFlag, + can_gc: CanGc, ) { if let Some(s) = self.super_type() { - s.cloning_steps(copy, maybe_doc, clone_children); + s.cloning_steps(copy, maybe_doc, clone_children, can_gc); } let elem = copy.downcast::().unwrap(); elem.value_dirty.set(self.value_dirty.get()); @@ -2701,7 +2704,7 @@ impl VirtualMethods for HTMLInputElement { .borrow_mut() .set_content(self.textinput.borrow().get_content()); elem.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } } @@ -2746,7 +2749,11 @@ impl Validatable for HTMLInputElement { } } - fn perform_validation(&self, validate_flags: ValidationFlags) -> ValidationFlags { + fn perform_validation( + &self, + validate_flags: ValidationFlags, + _can_gc: CanGc, + ) -> ValidationFlags { let mut failed_flags = ValidationFlags::empty(); let value = self.Value(); diff --git a/components/script/dom/htmllabelelement.rs b/components/script/dom/htmllabelelement.rs index e9865ea274d..efa386c7cdd 100644 --- a/components/script/dom/htmllabelelement.rs +++ b/components/script/dom/htmllabelelement.rs @@ -157,10 +157,12 @@ impl VirtualMethods for HTMLLabelElement { } } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if *attr.local_name() == local_name!("form") { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); } } } diff --git a/components/script/dom/htmllegendelement.rs b/components/script/dom/htmllegendelement.rs index 62ce3efebe4..35e983a9512 100644 --- a/components/script/dom/htmllegendelement.rs +++ b/components/script/dom/htmllegendelement.rs @@ -61,17 +61,17 @@ impl VirtualMethods for HTMLLegendElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.upcast::() .check_ancestors_disabled_state_for_form_control(); } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); let node = self.upcast::(); let el = self.upcast::(); diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index af5bcd5f6d9..aab9f28b48e 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -216,8 +216,10 @@ impl VirtualMethods for HTMLLinkElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if !self.upcast::().is_connected() || mutation.is_removal() { return; } @@ -265,9 +267,9 @@ impl VirtualMethods for HTMLLinkElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.relations @@ -294,9 +296,9 @@ impl VirtualMethods for HTMLLinkElement { } } - fn unbind_from_tree(&self, context: &UnbindContext) { + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.unbind_from_tree(context); + s.unbind_from_tree(context, can_gc); } if let Some(s) = self.stylesheet.borrow_mut().take() { diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 49de8a3cc68..94c962968dc 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -1956,9 +1956,9 @@ impl HTMLMediaElement { self.upcast::().dirty(NodeDamage::OtherNodeDamage); } - fn remove_controls(&self) { + fn remove_controls(&self, can_gc: CanGc) { if let Some(id) = self.media_controls_id.borrow_mut().take() { - self.owner_document().unregister_media_controls(&id); + self.owner_document().unregister_media_controls(&id, can_gc); } } @@ -2486,8 +2486,10 @@ impl VirtualMethods for HTMLMediaElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("muted") => { @@ -2502,9 +2504,9 @@ impl VirtualMethods for HTMLMediaElement { }, local_name!("controls") => { if mutation.new_value(attr).is_some() { - self.render_controls(CanGc::note()); + self.render_controls(can_gc); } else { - self.remove_controls(); + self.remove_controls(can_gc); } }, _ => (), @@ -2512,10 +2514,10 @@ impl VirtualMethods for HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#playing-the-media-resource:remove-an-element-from-a-document - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); - self.remove_controls(); + self.remove_controls(can_gc); if context.tree_connected { let task = MediaElementMicrotask::PauseIfNotInDocument { diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index 2b71e907f79..16b6a2463d4 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -252,9 +252,9 @@ impl VirtualMethods for HTMLMetaElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } if context.tree_connected { @@ -262,17 +262,17 @@ impl VirtualMethods for HTMLMetaElement { } } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.attribute_mutated(attr, mutation); + s.attribute_mutated(attr, mutation, can_gc); } self.process_referrer_attribute(); } - fn unbind_from_tree(&self, context: &UnbindContext) { + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.unbind_from_tree(context); + s.unbind_from_tree(context, can_gc); } if context.tree_connected { diff --git a/components/script/dom/htmlmeterelement.rs b/components/script/dom/htmlmeterelement.rs index 2a72972a5b3..103ab9c0131 100644 --- a/components/script/dom/htmlmeterelement.rs +++ b/components/script/dom/htmlmeterelement.rs @@ -331,8 +331,10 @@ impl VirtualMethods for HTMLMeterElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); let is_important_attribute = matches!( attr.local_name(), @@ -354,8 +356,8 @@ impl VirtualMethods for HTMLMeterElement { self.update_state(CanGc::note()); } - fn bind_to_tree(&self, context: &BindContext) { - self.super_type().unwrap().bind_to_tree(context); + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { + self.super_type().unwrap().bind_to_tree(context, can_gc); self.update_state(CanGc::note()); } diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs index e50669a3ad9..a6941461e5d 100644 --- a/components/script/dom/htmlobjectelement.rs +++ b/components/script/dom/htmlobjectelement.rs @@ -153,8 +153,10 @@ impl VirtualMethods for HTMLObjectElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("data") => { if let AttributeMutation::Set(_) = mutation { @@ -162,7 +164,7 @@ impl VirtualMethods for HTMLObjectElement { } }, local_name!("form") => { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); }, _ => {}, } diff --git a/components/script/dom/htmloptgroupelement.rs b/components/script/dom/htmloptgroupelement.rs index 67abe7a49e4..55ffa92257b 100644 --- a/components/script/dom/htmloptgroupelement.rs +++ b/components/script/dom/htmloptgroupelement.rs @@ -64,11 +64,11 @@ impl HTMLOptGroupElement { ) } - fn update_select_validity(&self) { + fn update_select_validity(&self, can_gc: CanGc) { if let Some(select) = self.owner_select_element() { select .validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } } @@ -98,8 +98,10 @@ impl VirtualMethods for HTMLOptGroupElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if attr.local_name() == &local_name!("disabled") { let disabled_state = match mutation { AttributeMutation::Set(None) => true, @@ -132,21 +134,21 @@ impl VirtualMethods for HTMLOptGroupElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } - self.update_select_validity(); + self.update_select_validity(can_gc); } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); if let Some(select) = context.parent.downcast::() { select .validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } } } diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs index d6428532f00..e8471f408d2 100644 --- a/components/script/dom/htmloptionelement.rs +++ b/components/script/dom/htmloptionelement.rs @@ -141,7 +141,7 @@ impl HTMLOptionElement { } } - fn update_select_validity(&self) { + fn update_select_validity(&self, can_gc: CanGc) { if let Some(select) = self .upcast::() .ancestors() @@ -150,7 +150,7 @@ impl HTMLOptionElement { { select .validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } } } @@ -207,7 +207,7 @@ impl HTMLOptionElementMethods for HTMLOptionElement { option.SetDefaultSelected(default_selected); option.set_selectedness(selected); - option.update_select_validity(); + option.update_select_validity(can_gc); Ok(option) } @@ -286,7 +286,7 @@ impl HTMLOptionElementMethods for HTMLOptionElement { self.dirtiness.set(true); self.selectedness.set(selected); self.pick_if_selected_and_reset(); - self.update_select_validity(); + self.update_select_validity(CanGc::note()); } // https://html.spec.whatwg.org/multipage/#dom-option-index @@ -300,8 +300,10 @@ impl VirtualMethods for HTMLOptionElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("disabled") => { let el = self.upcast::(); @@ -316,7 +318,7 @@ impl VirtualMethods for HTMLOptionElement { el.check_parent_disabled_state_for_option(); }, } - self.update_select_validity(); + self.update_select_validity(can_gc); }, local_name!("selected") => { match mutation { @@ -333,26 +335,26 @@ impl VirtualMethods for HTMLOptionElement { } }, } - self.update_select_validity(); + self.update_select_validity(can_gc); }, _ => {}, } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.upcast::() .check_parent_disabled_state_for_option(); self.pick_if_selected_and_reset(); - self.update_select_validity(); + self.update_select_validity(can_gc); } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); if let Some(select) = context .parent @@ -362,7 +364,7 @@ impl VirtualMethods for HTMLOptionElement { { select .validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); select.ask_for_reset(); } diff --git a/components/script/dom/htmloptionscollection.rs b/components/script/dom/htmloptionscollection.rs index 8f1d95d43d4..1b31ea4bfcc 100644 --- a/components/script/dom/htmloptionscollection.rs +++ b/components/script/dom/htmloptionscollection.rs @@ -117,7 +117,7 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollectio let node = value.upcast::(); let root = self.upcast().root_node(); if n >= 0 { - Node::pre_insert(node, &root, None).map(|_| ()) + Node::pre_insert(node, &root, None, can_gc).map(|_| ()) } else { let child = self.upcast().IndexedGetter(index).unwrap(); let child_node = child.upcast::(); @@ -220,7 +220,7 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollectio }; // Step 6 - Node::pre_insert(node, &parent, reference_node.as_deref()).map(|_| ()) + Node::pre_insert(node, &parent, reference_node.as_deref(), CanGc::note()).map(|_| ()) } /// diff --git a/components/script/dom/htmloutputelement.rs b/components/script/dom/htmloutputelement.rs index f26de72ba9c..9e702d1eb6e 100644 --- a/components/script/dom/htmloutputelement.rs +++ b/components/script/dom/htmloutputelement.rs @@ -159,10 +159,12 @@ impl VirtualMethods for HTMLOutputElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if attr.local_name() == &local_name!("form") { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); } } } diff --git a/components/script/dom/htmlprogresselement.rs b/components/script/dom/htmlprogresselement.rs index 1dfd1111ce6..30106c479d0 100644 --- a/components/script/dom/htmlprogresselement.rs +++ b/components/script/dom/htmlprogresselement.rs @@ -227,8 +227,10 @@ impl VirtualMethods for HTMLProgressElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); let is_important_attribute = matches!( attr.local_name(), @@ -239,8 +241,8 @@ impl VirtualMethods for HTMLProgressElement { } } - fn bind_to_tree(&self, context: &BindContext) { - self.super_type().unwrap().bind_to_tree(context); + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { + self.super_type().unwrap().bind_to_tree(context, can_gc); self.update_state(CanGc::note()); } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 17c601d3706..61047817594 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -1242,8 +1242,10 @@ impl VirtualMethods for HTMLScriptElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if *attr.local_name() == local_name!("src") { if let AttributeMutation::Set(_) = mutation { if !self.parser_inserted.get() && self.upcast::().is_connected() { @@ -1288,9 +1290,10 @@ impl VirtualMethods for HTMLScriptElement { copy: &Node, maybe_doc: Option<&Document>, clone_children: CloneChildrenFlag, + can_gc: CanGc, ) { if let Some(s) = self.super_type() { - s.cloning_steps(copy, maybe_doc, clone_children); + s.cloning_steps(copy, maybe_doc, clone_children, can_gc); } // https://html.spec.whatwg.org/multipage/#already-started diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index 445b1058018..3804f5a3bfe 100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -356,7 +356,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement { } self.validity_state() - .perform_validation_and_update(ValidationFlags::VALUE_MISSING); + .perform_validation_and_update(ValidationFlags::VALUE_MISSING, CanGc::note()); } // https://html.spec.whatwg.org/multipage/#dom-select-selectedindex @@ -421,12 +421,14 @@ impl VirtualMethods for HTMLSelectElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("required") => { self.validity_state() - .perform_validation_and_update(ValidationFlags::VALUE_MISSING); + .perform_validation_and_update(ValidationFlags::VALUE_MISSING, can_gc); }, local_name!("disabled") => { let el = self.upcast::(); @@ -443,26 +445,26 @@ impl VirtualMethods for HTMLSelectElement { } self.validity_state() - .perform_validation_and_update(ValidationFlags::VALUE_MISSING); + .perform_validation_and_update(ValidationFlags::VALUE_MISSING, can_gc); }, local_name!("form") => { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); }, _ => {}, } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.upcast::() .check_ancestors_disabled_state_for_form_control(); } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); let node = self.upcast::(); let el = self.upcast::(); @@ -517,7 +519,11 @@ impl Validatable for HTMLSelectElement { !self.upcast::().disabled_state() && !is_barred_by_datalist_ancestor(self.upcast()) } - fn perform_validation(&self, validate_flags: ValidationFlags) -> ValidationFlags { + fn perform_validation( + &self, + validate_flags: ValidationFlags, + _can_gc: CanGc, + ) -> ValidationFlags { let mut failed_flags = ValidationFlags::empty(); // https://html.spec.whatwg.org/multipage/#suffering-from-being-missing diff --git a/components/script/dom/htmlslotelement.rs b/components/script/dom/htmlslotelement.rs index 6d4d03f518a..2deb6b068e4 100644 --- a/components/script/dom/htmlslotelement.rs +++ b/components/script/dom/htmlslotelement.rs @@ -461,8 +461,10 @@ impl VirtualMethods for HTMLSlotElement { } /// - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if attr.local_name() == &local_name!("name") && attr.namespace() == &ns!() { if let Some(shadow_root) = self.containing_shadow_root() { @@ -486,9 +488,9 @@ impl VirtualMethods for HTMLSlotElement { } } - fn bind_to_tree(&self, context: &super::node::BindContext) { + fn bind_to_tree(&self, context: &super::node::BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } if !context.tree_is_in_a_shadow_tree { @@ -500,9 +502,9 @@ impl VirtualMethods for HTMLSlotElement { .register_slot(self); } - fn unbind_from_tree(&self, context: &super::node::UnbindContext) { + fn unbind_from_tree(&self, context: &super::node::UnbindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.unbind_from_tree(context); + s.unbind_from_tree(context, can_gc); } if let Some(shadow_root) = self.containing_shadow_root() { diff --git a/components/script/dom/htmlsourceelement.rs b/components/script/dom/htmlsourceelement.rs index 147a0a696a7..45772e4bac5 100644 --- a/components/script/dom/htmlsourceelement.rs +++ b/components/script/dom/htmlsourceelement.rs @@ -72,8 +72,10 @@ impl VirtualMethods for HTMLSourceElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match attr.local_name() { &local_name!("srcset") | &local_name!("sizes") | @@ -90,8 +92,8 @@ impl VirtualMethods for HTMLSourceElement { } /// - fn bind_to_tree(&self, context: &BindContext) { - self.super_type().unwrap().bind_to_tree(context); + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { + self.super_type().unwrap().bind_to_tree(context, can_gc); let parent = self.upcast::().GetParentNode().unwrap(); if let Some(media) = parent.downcast::() { media.handle_source_child_insertion(CanGc::note()); @@ -103,8 +105,8 @@ impl VirtualMethods for HTMLSourceElement { ); } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); if let Some(next_sibling) = context.next_sibling { let next_sibling_iterator = next_sibling.inclusively_following_siblings(); HTMLSourceElement::iterate_next_html_image_element_siblings( diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 0fbd8d10066..2e26803be96 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -220,8 +220,8 @@ impl VirtualMethods for HTMLStyleElement { } } - fn bind_to_tree(&self, context: &BindContext) { - self.super_type().unwrap().bind_to_tree(context); + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { + self.super_type().unwrap().bind_to_tree(context, can_gc); // https://html.spec.whatwg.org/multipage/#update-a-style-block // Handles the case when: @@ -244,9 +244,9 @@ impl VirtualMethods for HTMLStyleElement { } } - fn unbind_from_tree(&self, context: &UnbindContext) { + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.unbind_from_tree(context); + s.unbind_from_tree(context, can_gc); } if context.tree_connected { @@ -254,9 +254,9 @@ impl VirtualMethods for HTMLStyleElement { } } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.attribute_mutated(attr, mutation); + s.attribute_mutated(attr, mutation, can_gc); } let node = self.upcast::(); diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index b0e6adeb8d3..b1070a0491a 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -114,6 +114,7 @@ impl HTMLTableElement { atom: &LocalName, section: Option<&HTMLTableSectionElement>, reference_predicate: P, + can_gc: CanGc, ) -> ErrorResult where P: FnMut(&DomRoot) -> bool, @@ -124,7 +125,7 @@ impl HTMLTableElement { } } - self.delete_first_section_of_type(atom); + self.delete_first_section_of_type(atom, can_gc); let node = self.upcast::(); @@ -163,9 +164,9 @@ impl HTMLTableElement { // https://html.spec.whatwg.org/multipage/#dom-table-deletethead // https://html.spec.whatwg.org/multipage/#dom-table-deletetfoot - fn delete_first_section_of_type(&self, atom: &LocalName) { + fn delete_first_section_of_type(&self, atom: &LocalName, can_gc: CanGc) { if let Some(thead) = self.get_first_section_of_type(atom) { - thead.upcast::().remove_self(); + thead.upcast::().remove_self(can_gc); } } @@ -206,7 +207,7 @@ impl HTMLTableElementMethods for HTMLTableElement { // https://html.spec.whatwg.org/multipage/#dom-table-caption fn SetCaption(&self, new_caption: Option<&HTMLTableCaptionElement>) -> Fallible<()> { if let Some(ref caption) = self.GetCaption() { - caption.upcast::().remove_self(); + caption.upcast::().remove_self(CanGc::note()); } if let Some(caption) = new_caption { @@ -239,7 +240,7 @@ impl HTMLTableElementMethods for HTMLTableElement { // https://html.spec.whatwg.org/multipage/#dom-table-deletecaption fn DeleteCaption(&self) { if let Some(caption) = self.GetCaption() { - caption.upcast::().remove_self(); + caption.upcast::().remove_self(CanGc::note()); } } @@ -250,9 +251,12 @@ impl HTMLTableElementMethods for HTMLTableElement { // https://html.spec.whatwg.org/multipage/#dom-table-thead fn SetTHead(&self, thead: Option<&HTMLTableSectionElement>) -> ErrorResult { - self.set_first_section_of_type(&local_name!("thead"), thead, |n| { - !n.is::() && !n.is::() - }) + self.set_first_section_of_type( + &local_name!("thead"), + thead, + |n| !n.is::() && !n.is::(), + CanGc::note(), + ) } // https://html.spec.whatwg.org/multipage/#dom-table-createthead @@ -262,7 +266,7 @@ impl HTMLTableElementMethods for HTMLTableElement { // https://html.spec.whatwg.org/multipage/#dom-table-deletethead fn DeleteTHead(&self) { - self.delete_first_section_of_type(&local_name!("thead")) + self.delete_first_section_of_type(&local_name!("thead"), CanGc::note()) } // https://html.spec.whatwg.org/multipage/#dom-table-tfoot @@ -272,20 +276,25 @@ impl HTMLTableElementMethods for HTMLTableElement { // https://html.spec.whatwg.org/multipage/#dom-table-tfoot fn SetTFoot(&self, tfoot: Option<&HTMLTableSectionElement>) -> ErrorResult { - self.set_first_section_of_type(&local_name!("tfoot"), tfoot, |n| { - if n.is::() || n.is::() { - return false; - } - - if n.is::() { - let name = n.local_name(); - if name == &local_name!("thead") || name == &local_name!("tbody") { + self.set_first_section_of_type( + &local_name!("tfoot"), + tfoot, + |n| { + if n.is::() || n.is::() { return false; } - } - true - }) + if n.is::() { + let name = n.local_name(); + if name == &local_name!("thead") || name == &local_name!("tbody") { + return false; + } + } + + true + }, + CanGc::note(), + ) } // https://html.spec.whatwg.org/multipage/#dom-table-createtfoot @@ -295,7 +304,7 @@ impl HTMLTableElementMethods for HTMLTableElement { // https://html.spec.whatwg.org/multipage/#dom-table-deletetfoot fn DeleteTFoot(&self) { - self.delete_first_section_of_type(&local_name!("tfoot")) + self.delete_first_section_of_type(&local_name!("tfoot"), CanGc::note()) } // https://html.spec.whatwg.org/multipage/#dom-table-tbodies @@ -434,7 +443,7 @@ impl HTMLTableElementMethods for HTMLTableElement { } // Step 3: Otherwise, remove the indexth element in the rows collection from its parent. - DomRoot::upcast::(rows.Item(index as u32).unwrap()).remove_self(); + DomRoot::upcast::(rows.Item(index as u32).unwrap()).remove_self(CanGc::note()); Ok(()) } @@ -503,8 +512,10 @@ impl VirtualMethods for HTMLTableElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("border") => { // According to HTML5 § 14.3.9, invalid values map to 1px. diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs index 326c8867df0..fe8a3febf81 100644 --- a/components/script/dom/htmltablerowelement.rs +++ b/components/script/dom/htmltablerowelement.rs @@ -104,13 +104,19 @@ impl HTMLTableRowElementMethods for HTMLTableRowElement { index, || self.Cells(), || HTMLTableCellElement::new(local_name!("td"), None, &node.owner_doc(), None, can_gc), + can_gc, ) } // https://html.spec.whatwg.org/multipage/#dom-tr-deletecell fn DeleteCell(&self, index: i32) -> ErrorResult { let node = self.upcast::(); - node.delete_cell_or_row(index, || self.Cells(), |n| n.is::()) + node.delete_cell_or_row( + index, + || self.Cells(), + |n| n.is::(), + CanGc::note(), + ) } // https://html.spec.whatwg.org/multipage/#dom-tr-rowindex diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs index 4c17e86fa75..b5877a5e43c 100644 --- a/components/script/dom/htmltablesectionelement.rs +++ b/components/script/dom/htmltablesectionelement.rs @@ -77,13 +77,19 @@ impl HTMLTableSectionElementMethods for HTMLTableSectionEl index, || self.Rows(), || HTMLTableRowElement::new(local_name!("tr"), None, &node.owner_doc(), None, can_gc), + can_gc, ) } // https://html.spec.whatwg.org/multipage/#dom-tbody-deleterow fn DeleteRow(&self, index: i32) -> ErrorResult { let node = self.upcast::(); - node.delete_cell_or_row(index, || self.Rows(), |n| n.is::()) + node.delete_cell_or_row( + index, + || self.Rows(), + |n| n.is::(), + CanGc::note(), + ) } } diff --git a/components/script/dom/htmltemplateelement.rs b/components/script/dom/htmltemplateelement.rs index ef577504090..93897f4710f 100644 --- a/components/script/dom/htmltemplateelement.rs +++ b/components/script/dom/htmltemplateelement.rs @@ -113,14 +113,14 @@ impl VirtualMethods for HTMLTemplateElement { } /// - fn adopting_steps(&self, old_doc: &Document) { - self.super_type().unwrap().adopting_steps(old_doc); + fn adopting_steps(&self, old_doc: &Document, can_gc: CanGc) { + self.super_type().unwrap().adopting_steps(old_doc, can_gc); // Step 1. let doc = self .owner_document() .appropriate_template_contents_owner_document(CanGc::note()); // Step 2. - Node::adopt(self.Content(CanGc::note()).upcast(), &doc); + Node::adopt(self.Content(CanGc::note()).upcast(), &doc, can_gc); } /// @@ -129,10 +129,11 @@ impl VirtualMethods for HTMLTemplateElement { copy: &Node, maybe_doc: Option<&Document>, clone_children: CloneChildrenFlag, + can_gc: CanGc, ) { self.super_type() .unwrap() - .cloning_steps(copy, maybe_doc, clone_children); + .cloning_steps(copy, maybe_doc, clone_children, can_gc); if clone_children == CloneChildrenFlag::DoNotCloneChildren { // Step 1. return; diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 315ac01ef9a..7f47ee5a90a 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -347,7 +347,7 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement { } self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), CanGc::note()); self.upcast::().dirty(NodeDamage::OtherNodeDamage); } @@ -468,8 +468,10 @@ impl VirtualMethods for HTMLTextAreaElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); match *attr.local_name() { local_name!("disabled") => { let el = self.upcast::(); @@ -538,25 +540,25 @@ impl VirtualMethods for HTMLTextAreaElement { } }, local_name!("form") => { - self.form_attribute_mutated(mutation); + self.form_attribute_mutated(mutation, can_gc); }, _ => {}, } self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } self.upcast::() .check_ancestors_disabled_state_for_form_control(); self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { @@ -576,8 +578,8 @@ impl VirtualMethods for HTMLTextAreaElement { } } - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); let node = self.upcast::(); let el = self.upcast::(); @@ -591,7 +593,7 @@ impl VirtualMethods for HTMLTextAreaElement { } self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } // The cloning steps for textarea elements must propagate the raw value @@ -601,9 +603,10 @@ impl VirtualMethods for HTMLTextAreaElement { copy: &Node, maybe_doc: Option<&Document>, clone_children: CloneChildrenFlag, + can_gc: CanGc, ) { if let Some(s) = self.super_type() { - s.cloning_steps(copy, maybe_doc, clone_children); + s.cloning_steps(copy, maybe_doc, clone_children, can_gc); } let el = copy.downcast::().unwrap(); el.value_dirty.set(self.value_dirty.get()); @@ -612,7 +615,7 @@ impl VirtualMethods for HTMLTextAreaElement { textinput.set_content(self.textinput.borrow().get_content()); } el.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } fn children_changed(&self, mutation: &ChildrenMutation) { @@ -625,9 +628,9 @@ impl VirtualMethods for HTMLTextAreaElement { } // copied and modified from htmlinputelement.rs - fn handle_event(&self, event: &Event) { + fn handle_event(&self, event: &Event, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.handle_event(event); + s.handle_event(event, can_gc); } if event.type_() == atom!("click") && !event.DefaultPrevented() { @@ -691,7 +694,7 @@ impl VirtualMethods for HTMLTextAreaElement { } self.validity_state() - .perform_validation_and_update(ValidationFlags::all()); + .perform_validation_and_update(ValidationFlags::all(), can_gc); } fn pop(&self) { @@ -735,7 +738,11 @@ impl Validatable for HTMLTextAreaElement { !is_barred_by_datalist_ancestor(self.upcast()) } - fn perform_validation(&self, validate_flags: ValidationFlags) -> ValidationFlags { + fn perform_validation( + &self, + validate_flags: ValidationFlags, + _can_gc: CanGc, + ) -> ValidationFlags { let mut failed_flags = ValidationFlags::empty(); let textinput = self.textinput.borrow(); diff --git a/components/script/dom/htmltitleelement.rs b/components/script/dom/htmltitleelement.rs index 6b6b3504e13..33ce749ab6d 100644 --- a/components/script/dom/htmltitleelement.rs +++ b/components/script/dom/htmltitleelement.rs @@ -92,9 +92,9 @@ impl VirtualMethods for HTMLTitleElement { } } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } let node = self.upcast::(); if context.tree_is_in_a_document_tree { diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs index 21a2a11888b..49f81f78d8d 100644 --- a/components/script/dom/htmlvideoelement.rs +++ b/components/script/dom/htmlvideoelement.rs @@ -305,8 +305,10 @@ impl VirtualMethods for HTMLVideoElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); if attr.local_name() == &local_name!("poster") { if let Some(new_value) = mutation.new_value(attr) { diff --git a/components/script/dom/namednodemap.rs b/components/script/dom/namednodemap.rs index 354f598226f..a96b63326b3 100644 --- a/components/script/dom/namednodemap.rs +++ b/components/script/dom/namednodemap.rs @@ -79,7 +79,7 @@ impl NamedNodeMapMethods for NamedNodeMap { fn RemoveNamedItem(&self, name: DOMString) -> Fallible> { let name = self.owner.parsed_name(name); self.owner - .remove_attribute_by_name(&name) + .remove_attribute_by_name(&name, CanGc::note()) .ok_or(Error::NotFound) } @@ -91,7 +91,7 @@ impl NamedNodeMapMethods for NamedNodeMap { ) -> Fallible> { let ns = namespace_from_domstring(namespace); self.owner - .remove_attribute(&ns, &LocalName::from(local_name)) + .remove_attribute(&ns, &LocalName::from(local_name), CanGc::note()) .ok_or(Error::NotFound) } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index ee76fdf3b08..5cbcbb6f43c 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -248,7 +248,7 @@ impl Node { /// Adds a new child to the end of this node's list of children. /// /// Fails unless `new_child` is disconnected from the tree. - fn add_child(&self, new_child: &Node, before: Option<&Node>) { + fn add_child(&self, new_child: &Node, before: Option<&Node>, can_gc: CanGc) { assert!(new_child.parent_node.get().is_none()); assert!(new_child.prev_sibling.get().is_none()); assert!(new_child.next_sibling.get().is_none()); @@ -307,11 +307,14 @@ impl Node { // Out-of-document elements never have the descendants flag set. debug_assert!(!node.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS)); - vtable_for(&node).bind_to_tree(&BindContext { - tree_connected: parent_is_connected, - tree_is_in_a_document_tree: parent_is_in_a_document_tree, - tree_is_in_a_shadow_tree: parent_in_shadow_tree, - }); + vtable_for(&node).bind_to_tree( + &BindContext { + tree_connected: parent_is_connected, + tree_is_in_a_document_tree: parent_is_in_a_document_tree, + tree_is_in_a_shadow_tree: parent_in_shadow_tree, + }, + can_gc, + ); } } @@ -323,7 +326,7 @@ impl Node { /// Clean up flags and runs steps 11-14 of remove a node. /// - pub(crate) fn complete_remove_subtree(root: &Node, context: &UnbindContext) { + pub(crate) fn complete_remove_subtree(root: &Node, context: &UnbindContext, can_gc: CanGc) { // Flags that reset when a node is disconnected const RESET_FLAGS: NodeFlags = NodeFlags::IS_IN_A_DOCUMENT_TREE .union(NodeFlags::IS_CONNECTED) @@ -356,7 +359,7 @@ impl Node { // This needs to be in its own loop, because unbind_from_tree may // rely on the state of IS_IN_DOC of the context node's descendants, // e.g. when removing a . - vtable_for(&node).unbind_from_tree(context); + vtable_for(&node).unbind_from_tree(context, can_gc); // Step 12 & 14.2. Enqueue disconnected custom element reactions. if is_parent_connected { @@ -374,7 +377,7 @@ impl Node { /// Removes the given child from this node's list of children. /// /// Fails unless `child` is a child of this node. - fn remove_child(&self, child: &Node, cached_index: Option) { + fn remove_child(&self, child: &Node, cached_index: Option, can_gc: CanGc) { assert!(child.parent_node.get().as_deref() == Some(self)); self.note_dirty_descendants(); @@ -413,7 +416,7 @@ impl Node { child.parent_node.set(None); self.children_count.set(self.children_count.get() - 1); - Self::complete_remove_subtree(child, &context); + Self::complete_remove_subtree(child, &context, can_gc); } pub(crate) fn to_untrusted_node_address(&self) -> UntrustedNodeAddress { @@ -958,7 +961,7 @@ impl Node { }; // Step 6. - Node::pre_insert(&node, &parent, viable_previous_sibling.as_deref())?; + Node::pre_insert(&node, &parent, viable_previous_sibling.as_deref(), can_gc)?; Ok(()) } @@ -983,7 +986,7 @@ impl Node { .node_from_nodes_and_strings(nodes, can_gc)?; // Step 5. - Node::pre_insert(&node, &parent, viable_next_sibling.as_deref())?; + Node::pre_insert(&node, &parent, viable_next_sibling.as_deref(), can_gc)?; Ok(()) } @@ -1008,7 +1011,7 @@ impl Node { parent.ReplaceChild(&node, self)?; } else { // Step 6. - Node::pre_insert(&node, &parent, viable_next_sibling.as_deref())?; + Node::pre_insert(&node, &parent, viable_next_sibling.as_deref(), can_gc)?; } Ok(()) } @@ -1020,7 +1023,7 @@ impl Node { let node = doc.node_from_nodes_and_strings(nodes, can_gc)?; // Step 2. let first_child = self.first_child.get(); - Node::pre_insert(&node, self, first_child.as_deref()).map(|_| ()) + Node::pre_insert(&node, self, first_child.as_deref(), can_gc).map(|_| ()) } /// @@ -1040,7 +1043,7 @@ impl Node { // Step 2. Node::ensure_pre_insertion_validity(&node, self, None)?; // Step 3. - Node::replace_all(Some(&node), self); + Node::replace_all(Some(&node), self, can_gc); Ok(()) } @@ -1185,9 +1188,9 @@ impl Node { .peekable() } - pub(crate) fn remove_self(&self) { + pub(crate) fn remove_self(&self, can_gc: CanGc) { if let Some(ref parent) = self.GetParentNode() { - Node::remove(self, parent, SuppressObserver::Unsuppressed); + Node::remove(self, parent, SuppressObserver::Unsuppressed, can_gc); } } @@ -1264,6 +1267,7 @@ impl Node { index: i32, get_items: F, new_child: G, + _can_gc: CanGc, ) -> Fallible> where F: Fn() -> DomRoot, @@ -1305,6 +1309,7 @@ impl Node { index: i32, get_items: F, is_delete_type: G, + can_gc: CanGc, ) -> ErrorResult where F: Fn() -> DomRoot, @@ -1329,7 +1334,7 @@ impl Node { }, }; - element.upcast::().remove_self(); + element.upcast::().remove_self(can_gc); Ok(()) } @@ -2046,7 +2051,7 @@ impl Node { } /// - pub(crate) fn adopt(node: &Node, document: &Document) { + pub(crate) fn adopt(node: &Node, document: &Document, can_gc: CanGc) { document.add_script_and_layout_blocker(); // Step 1. Let oldDocument be node’s node document. @@ -2054,7 +2059,7 @@ impl Node { old_doc.add_script_and_layout_blocker(); // Step 2. If node’s parent is non-null, then remove node. - node.remove_self(); + node.remove_self(can_gc); // Step 3. If document is not oldDocument: if &*old_doc != document { @@ -2089,7 +2094,7 @@ impl Node { // Step 3.3 For each inclusiveDescendant in node’s shadow-including inclusive descendants, // in shadow-including tree order, run the adopting steps with inclusiveDescendant and oldDocument. for descendant in node.traverse_preorder(ShadowIncluding::Yes) { - vtable_for(&descendant).adopting_steps(&old_doc); + vtable_for(&descendant).adopting_steps(&old_doc, can_gc); } } @@ -2220,6 +2225,7 @@ impl Node { node: &Node, parent: &Node, child: Option<&Node>, + can_gc: CanGc, ) -> Fallible> { // Step 1. Node::ensure_pre_insertion_validity(node, parent, child)?; @@ -2235,7 +2241,7 @@ impl Node { }; // Step 4. - Node::adopt(node, &parent.owner_document()); + Node::adopt(node, &parent.owner_document(), can_gc); // Step 5. Node::insert( @@ -2243,6 +2249,7 @@ impl Node { parent, reference_child, SuppressObserver::Unsuppressed, + CanGc::note(), ); // Step 6. @@ -2255,6 +2262,7 @@ impl Node { parent: &Node, child: Option<&Node>, suppress_observers: SuppressObserver, + can_gc: CanGc, ) { node.owner_doc().add_script_and_layout_blocker(); debug_assert!(*node.owner_doc() == *parent.owner_doc()); @@ -2280,7 +2288,7 @@ impl Node { new_nodes.extend(node.children().map(|kid| Dom::from_ref(&*kid))); // Step 4. for kid in &*new_nodes { - Node::remove(kid, node, SuppressObserver::Suppressed); + Node::remove(kid, node, SuppressObserver::Suppressed, can_gc); } // Step 5. vtable_for(node).children_changed(&ChildrenMutation::replace_all(new_nodes.r(), &[])); @@ -2309,7 +2317,7 @@ impl Node { // Step 7. for kid in new_nodes { // Step 7.1. - parent.add_child(kid, child); + parent.add_child(kid, child, can_gc); // Step 7.4 If parent is a shadow host whose shadow root’s slot assignment is "named" // and node is a slottable, then assign a slot for node. @@ -2407,11 +2415,11 @@ impl Node { } /// - pub(crate) fn replace_all(node: Option<&Node>, parent: &Node) { + pub(crate) fn replace_all(node: Option<&Node>, parent: &Node, can_gc: CanGc) { parent.owner_doc().add_script_and_layout_blocker(); // Step 1. if let Some(node) = node { - Node::adopt(node, &parent.owner_doc()); + Node::adopt(node, &parent.owner_doc(), can_gc); } // Step 2. rooted_vec!(let removed_nodes <- parent.children().map(|c| DomRoot::as_traced(&c))); @@ -2429,11 +2437,11 @@ impl Node { }; // Step 4. for child in &*removed_nodes { - Node::remove(child, parent, SuppressObserver::Suppressed); + Node::remove(child, parent, SuppressObserver::Suppressed, can_gc); } // Step 5. if let Some(node) = node { - Node::insert(node, parent, None, SuppressObserver::Suppressed); + Node::insert(node, parent, None, SuppressObserver::Suppressed, can_gc); } // Step 6. vtable_for(parent).children_changed(&ChildrenMutation::replace_all( @@ -2456,15 +2464,15 @@ impl Node { /// pub(crate) fn string_replace_all(string: DOMString, parent: &Node, can_gc: CanGc) { if string.len() == 0 { - Node::replace_all(None, parent); + Node::replace_all(None, parent, can_gc); } else { let text = Text::new(string, &parent.owner_document(), can_gc); - Node::replace_all(Some(text.upcast::()), parent); + Node::replace_all(Some(text.upcast::()), parent, can_gc); }; } /// - fn pre_remove(child: &Node, parent: &Node) -> Fallible> { + fn pre_remove(child: &Node, parent: &Node, can_gc: CanGc) -> Fallible> { // Step 1. match child.GetParentNode() { Some(ref node) if &**node != parent => return Err(Error::NotFound), @@ -2473,14 +2481,14 @@ impl Node { } // Step 2. - Node::remove(child, parent, SuppressObserver::Unsuppressed); + Node::remove(child, parent, SuppressObserver::Unsuppressed, can_gc); // Step 3. Ok(DomRoot::from_ref(child)) } /// - fn remove(node: &Node, parent: &Node, suppress_observers: SuppressObserver) { + fn remove(node: &Node, parent: &Node, suppress_observers: SuppressObserver, can_gc: CanGc) { parent.owner_doc().add_script_and_layout_blocker(); // Step 2. @@ -2517,7 +2525,7 @@ impl Node { // Step 7. Remove node from its parent's children. // Step 11-14. Run removing steps and enqueue disconnected custom element reactions for the subtree. - parent.remove_child(node, cached_index); + parent.remove_child(node, cached_index, can_gc); // Step 8. If node is assigned, then run assign slottables for node’s assigned slot. if let Some(slot) = node.assigned_slot() { @@ -2707,14 +2715,14 @@ impl Node { // Step 5: Run any cloning steps defined for node in other applicable specifications and pass copy, // node, document, and the clone children flag if set, as parameters. - vtable_for(node).cloning_steps(©, maybe_doc, clone_children); + vtable_for(node).cloning_steps(©, maybe_doc, clone_children, can_gc); // Step 6. If the clone children flag is set, then for each child child of node, in tree order: append the // result of cloning child with document and the clone children flag set, to copy. if clone_children == CloneChildrenFlag::CloneChildren { for child in node.children() { let child_copy = Node::clone(&child, Some(&document), clone_children, can_gc); - let _inserted_node = Node::pre_insert(&child_copy, ©, None); + let _inserted_node = Node::pre_insert(&child_copy, ©, None, can_gc); } } @@ -2757,8 +2765,12 @@ impl Node { ); // TODO: Should we handle the error case here and in step 6? - let _inserted_node = - Node::pre_insert(&child_copy, copy_shadow_root.upcast::(), None); + let _inserted_node = Node::pre_insert( + &child_copy, + copy_shadow_root.upcast::(), + None, + can_gc, + ); } } } @@ -3115,7 +3127,7 @@ impl NodeMethods for Node { }; // Step 3. - Node::replace_all(node.as_deref(), self); + Node::replace_all(node.as_deref(), self, can_gc); }, NodeTypeId::Attr => { let attr = self.downcast::().unwrap(); @@ -3131,12 +3143,12 @@ impl NodeMethods for Node { /// fn InsertBefore(&self, node: &Node, child: Option<&Node>) -> Fallible> { - Node::pre_insert(node, self, child) + Node::pre_insert(node, self, child, CanGc::note()) } /// fn AppendChild(&self, node: &Node) -> Fallible> { - Node::pre_insert(node, self, None) + Node::pre_insert(node, self, None, CanGc::note()) } /// @@ -3238,11 +3250,11 @@ impl NodeMethods for Node { // Step 10. let document = self.owner_document(); - Node::adopt(node, &document); + Node::adopt(node, &document, CanGc::note()); let removed_child = if node != child { // Step 11. - Node::remove(child, self, SuppressObserver::Suppressed); + Node::remove(child, self, SuppressObserver::Suppressed, CanGc::note()); Some(child) } else { None @@ -3261,7 +3273,13 @@ impl NodeMethods for Node { }; // Step 13. - Node::insert(node, self, reference_child, SuppressObserver::Suppressed); + Node::insert( + node, + self, + reference_child, + SuppressObserver::Suppressed, + CanGc::note(), + ); // Step 14. vtable_for(self).children_changed(&ChildrenMutation::replace( @@ -3286,7 +3304,7 @@ impl NodeMethods for Node { /// fn RemoveChild(&self, node: &Node) -> Fallible> { - Node::pre_remove(node, self) + Node::pre_remove(node, self, CanGc::note()) } /// @@ -3297,7 +3315,7 @@ impl NodeMethods for Node { let cdata = text.upcast::(); let mut length = cdata.Length(); if length == 0 { - Node::remove(&node, self, SuppressObserver::Unsuppressed); + Node::remove(&node, self, SuppressObserver::Unsuppressed, CanGc::note()); continue; } while children @@ -3313,7 +3331,12 @@ impl NodeMethods for Node { let sibling_cdata = sibling.downcast::().unwrap(); length += sibling_cdata.Length(); cdata.append_data(&sibling_cdata.data()); - Node::remove(&sibling, self, SuppressObserver::Unsuppressed); + Node::remove( + &sibling, + self, + SuppressObserver::Unsuppressed, + CanGc::note(), + ); } } else { node.Normalize(); @@ -3726,8 +3749,8 @@ impl VirtualMethods for Node { // This handles the ranges mentioned in steps 2-3 when removing a node. /// - fn unbind_from_tree(&self, context: &UnbindContext) { - self.super_type().unwrap().unbind_from_tree(context); + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { + self.super_type().unwrap().unbind_from_tree(context, can_gc); if !self.ranges_is_empty() { self.ranges().drain_to_parent(context, self); } diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index 7eb022635fb..f76703098f4 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -884,7 +884,7 @@ impl RangeMethods for Range { }; // Step 9. - node.remove_self(); + node.remove_self(can_gc); // Step 10. let new_offset = reference_node @@ -900,7 +900,7 @@ impl RangeMethods for Range { }; // Step 12. - Node::pre_insert(node, &parent, reference_node.as_deref())?; + Node::pre_insert(node, &parent, reference_node.as_deref(), can_gc)?; // Step 13. if self.collapsed() { @@ -980,7 +980,7 @@ impl RangeMethods for Range { // Step 8. for child in &*contained_children { - child.remove_self(); + child.remove_self(CanGc::note()); } // Step 9. @@ -1023,7 +1023,7 @@ impl RangeMethods for Range { let fragment = self.ExtractContents(can_gc)?; // Step 4. - Node::replace_all(None, new_parent); + Node::replace_all(None, new_parent, can_gc); // Step 5. self.InsertNode(new_parent, can_gc)?; diff --git a/components/script/dom/servoparser/async_html.rs b/components/script/dom/servoparser/async_html.rs index 83d3dddfc54..269756505d2 100644 --- a/components/script/dom/servoparser/async_html.rs +++ b/components/script/dom/servoparser/async_html.rs @@ -546,7 +546,7 @@ impl Tokenizer { let control = elem.and_then(|e| e.as_maybe_form_control()); if let Some(control) = control { - control.set_form_owner_from_parser(&form); + control.set_form_owner_from_parser(&form, can_gc); } }, ParseOperation::Pop { node } => { diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index 0c5c40c31da..0551200728f 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -713,7 +713,7 @@ where fn next(&mut self) -> Option> { let next = self.inner.next()?; - next.remove_self(); + next.remove_self(CanGc::note()); Some(next) } @@ -1264,7 +1264,7 @@ impl TreeSink for Sink { let control = elem.and_then(|e| e.as_maybe_form_control()); if let Some(control) = control { - control.set_form_owner_from_parser(&form); + control.set_form_owner_from_parser(&form, CanGc::note()); } } diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index 57ec0303188..72b074ed6f4 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -153,11 +153,11 @@ impl ShadowRoot { ) } - pub(crate) fn detach(&self) { + pub(crate) fn detach(&self, can_gc: CanGc) { self.document.unregister_shadow_root(self); let node = self.upcast::(); node.set_containing_shadow_root(None); - Node::complete_remove_subtree(node, &UnbindContext::new(node, None, None, None)); + Node::complete_remove_subtree(node, &UnbindContext::new(node, None, None, None), can_gc); self.host.set(None); } @@ -221,7 +221,7 @@ impl ShadowRoot { /// Remove any existing association between the provided id and any elements /// in this shadow tree. - pub(crate) fn unregister_element_id(&self, to_unregister: &Element, id: Atom) { + pub(crate) fn unregister_element_id(&self, to_unregister: &Element, id: Atom, _can_gc: CanGc) { self.document_or_shadow_root.unregister_named_element( self.document_fragment.id_map(), to_unregister, @@ -230,7 +230,7 @@ impl ShadowRoot { } /// Associate an element present in this shadow tree with the provided id. - pub(crate) fn register_element_id(&self, element: &Element, id: Atom) { + pub(crate) fn register_element_id(&self, element: &Element, id: Atom, _can_gc: CanGc) { let root = self .upcast::() .inclusive_ancestors(ShadowIncluding::No) @@ -445,7 +445,7 @@ impl ShadowRootMethods for ShadowRoot { }; // Step 4. Replace all with fragment within this. - Node::replace_all(Some(frag.upcast()), self.upcast()); + Node::replace_all(Some(frag.upcast()), self.upcast(), can_gc); } /// @@ -462,9 +462,9 @@ impl VirtualMethods for ShadowRoot { Some(self.upcast::() as &dyn VirtualMethods) } - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } if context.tree_connected { @@ -482,17 +482,20 @@ impl VirtualMethods for ShadowRoot { // Out-of-document elements never have the descendants flag set debug_assert!(!node.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS)); - vtable_for(&node).bind_to_tree(&BindContext { - tree_connected: context.tree_connected, - tree_is_in_a_document_tree: false, - tree_is_in_a_shadow_tree: true, - }); + vtable_for(&node).bind_to_tree( + &BindContext { + tree_connected: context.tree_connected, + tree_is_in_a_document_tree: false, + tree_is_in_a_shadow_tree: true, + }, + can_gc, + ); } } - fn unbind_from_tree(&self, context: &UnbindContext) { + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.unbind_from_tree(context); + s.unbind_from_tree(context, can_gc); } if context.tree_connected { diff --git a/components/script/dom/svgsvgelement.rs b/components/script/dom/svgsvgelement.rs index 0a6e7605aad..61b90a5ef39 100644 --- a/components/script/dom/svgsvgelement.rs +++ b/components/script/dom/svgsvgelement.rs @@ -79,8 +79,10 @@ impl VirtualMethods for SVGSVGElement { Some(self.upcast::() as &dyn VirtualMethods) } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { - self.super_type().unwrap().attribute_mutated(attr, mutation); + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { + self.super_type() + .unwrap() + .attribute_mutated(attr, mutation, can_gc); } fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { diff --git a/components/script/dom/validation.rs b/components/script/dom/validation.rs index 666eac6dcee..6a0c88c56ce 100755 --- a/components/script/dom/validation.rs +++ b/components/script/dom/validation.rs @@ -25,7 +25,11 @@ pub(crate) trait Validatable { fn is_instance_validatable(&self) -> bool; // Check if element satisfies its constraints, excluding custom errors - fn perform_validation(&self, _validate_flags: ValidationFlags) -> ValidationFlags { + fn perform_validation( + &self, + _validate_flags: ValidationFlags, + _can_gc: CanGc, + ) -> ValidationFlags { ValidationFlags::empty() } diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs index 0d3297f38d8..dd258b80e5f 100755 --- a/components/script/dom/validitystate.rs +++ b/components/script/dom/validitystate.rs @@ -107,7 +107,7 @@ impl ValidityState { // https://html.spec.whatwg.org/multipage/#custom-validity-error-message pub(crate) fn set_custom_error_message(&self, error: DOMString) { *self.custom_error_message.borrow_mut() = error; - self.perform_validation_and_update(ValidationFlags::CUSTOM_ERROR); + self.perform_validation_and_update(ValidationFlags::CUSTOM_ERROR, CanGc::note()); } /// Given a set of [ValidationFlags], recalculate their value by performing @@ -115,12 +115,16 @@ impl ValidityState { /// if [ValidationFlags::CUSTOM_ERROR] is in `update_flags` and a custom /// error has been set on this [ValidityState], the state will be updated /// to reflect the existance of a custom error. - pub(crate) fn perform_validation_and_update(&self, update_flags: ValidationFlags) { + pub(crate) fn perform_validation_and_update( + &self, + update_flags: ValidationFlags, + can_gc: CanGc, + ) { let mut invalid_flags = self.invalid_flags.get(); invalid_flags.remove(update_flags); if let Some(validatable) = self.element.as_maybe_validatable() { - let new_flags = validatable.perform_validation(update_flags); + let new_flags = validatable.perform_validation(update_flags, can_gc); invalid_flags.insert(new_flags); } @@ -132,7 +136,7 @@ impl ValidityState { } self.invalid_flags.set(invalid_flags); - self.update_pseudo_classes(); + self.update_pseudo_classes(can_gc); } pub(crate) fn update_invalid_flags(&self, update_flags: ValidationFlags) { @@ -143,7 +147,7 @@ impl ValidityState { self.invalid_flags.get() } - pub(crate) fn update_pseudo_classes(&self) { + pub(crate) fn update_pseudo_classes(&self, can_gc: CanGc) { if self.element.is_instance_validatable() { let is_valid = self.invalid_flags.get().is_empty(); self.element.set_state(ElementState::VALID, is_valid); @@ -155,7 +159,7 @@ impl ValidityState { if let Some(form_control) = self.element.as_maybe_form_control() { if let Some(form_owner) = form_control.form_owner() { - form_owner.update_validity(); + form_owner.update_validity(can_gc); } } @@ -166,7 +170,7 @@ impl ValidityState { .filter_map(DomRoot::downcast::) .next() { - fieldset.update_validity(); + fieldset.update_validity(can_gc); } } } diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index 900ed5d0607..57ecba7b172 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use html5ever::LocalName; +use script_bindings::script_runtime::CanGc; use style::attr::AttrValue; use crate::dom::attr::Attr; @@ -72,9 +73,9 @@ pub(crate) trait VirtualMethods { /// Called when attributes of a node are mutated. /// /// - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.attribute_mutated(attr, mutation); + s.attribute_mutated(attr, mutation, can_gc); } } @@ -107,9 +108,9 @@ pub(crate) trait VirtualMethods { /// Called when a Node is appended to a tree, where 'tree_connected' indicates /// whether the tree is part of a Document. - fn bind_to_tree(&self, context: &BindContext) { + fn bind_to_tree(&self, context: &BindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.bind_to_tree(context); + s.bind_to_tree(context, can_gc); } } @@ -117,9 +118,9 @@ pub(crate) trait VirtualMethods { /// indicates whether the tree is part of a Document. /// Implements removing steps: /// - fn unbind_from_tree(&self, context: &UnbindContext) { + fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.unbind_from_tree(context); + s.unbind_from_tree(context, can_gc); } } @@ -131,16 +132,16 @@ pub(crate) trait VirtualMethods { } /// Called during event dispatch after the bubbling phase completes. - fn handle_event(&self, event: &Event) { + fn handle_event(&self, event: &Event, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.handle_event(event); + s.handle_event(event, can_gc); } } /// - fn adopting_steps(&self, old_doc: &Document) { + fn adopting_steps(&self, old_doc: &Document, can_gc: CanGc) { if let Some(s) = self.super_type() { - s.adopting_steps(old_doc); + s.adopting_steps(old_doc, can_gc); } } @@ -150,9 +151,10 @@ pub(crate) trait VirtualMethods { copy: &Node, maybe_doc: Option<&Document>, clone_children: CloneChildrenFlag, + can_gc: CanGc, ) { if let Some(s) = self.super_type() { - s.cloning_steps(copy, maybe_doc, clone_children); + s.cloning_steps(copy, maybe_doc, clone_children, can_gc); } } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 0ed9e80910e..3aa858467f6 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2311,7 +2311,7 @@ impl ScriptThread { ) }, WebDriverScriptCommand::GetUrl(reply) => { - webdriver_handlers::handle_get_url(&documents, pipeline_id, reply) + webdriver_handlers::handle_get_url(&documents, pipeline_id, reply, can_gc) }, WebDriverScriptCommand::IsEnabled(element_id, reply) => { webdriver_handlers::handle_is_enabled(&documents, pipeline_id, element_id, reply) diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 9427784342e..0e942c404b4 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -1148,6 +1148,7 @@ pub(crate) fn handle_get_url( documents: &DocumentCollection, pipeline: PipelineId, reply: IpcSender, + _can_gc: CanGc, ) { reply .send(