mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
* new_js_regex and matches_js_regex need a CanGc argument Signed-off-by: dericko681 <abonghoderick@gmail.com> * new_js_regex and matches_js_regex need a CanGc argument Signed-off-by: dericko681 <abonghoderick@gmail.com> * edit Propagate CanGc arguments through new_js_regex and matches_js_regex Signed-off-by: dericko681 <abonghoderick@gmail.com> * Propagate CanGc arguments through new_js_regex and matches_js_regex Signed-off-by: dericko681 <abonghoderick@gmail.com> * Propagate CanGc arguments through new_js_regex and matches_js_regex Signed-off-by: dericko681 <abonghoderick@gmail.com> * Propagate CanGc arguments through new_js_regex and matches_js_regex Signed-off-by: dericko681 <abonghoderick@gmail.com> --------- Signed-off-by: dericko681 <abonghoderick@gmail.com>
This commit is contained in:
parent
b5c8164e99
commit
83da63f638
60 changed files with 600 additions and 435 deletions
|
@ -115,7 +115,7 @@ impl AttrMethods<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ impl CharacterDataMethods<crate::DomTypeHolder> for CharacterData {
|
|||
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
||||
fn Remove(&self) {
|
||||
let node = self.upcast::<Node>();
|
||||
node.remove_self();
|
||||
node.remove_self(CanGc::note());
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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::<Node>()),
|
||||
);
|
||||
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<crate::DomTypeHolder> 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<crate::DomTypeHolder> for Document {
|
|||
}
|
||||
|
||||
// Step 11. Replace all with null within document.
|
||||
Node::replace_all(None, self.upcast::<Node>());
|
||||
Node::replace_all(None, self.upcast::<Node>(), can_gc);
|
||||
|
||||
// Specs and tests are in a state of flux about whether
|
||||
// we want to clear the selection when we remove the contents;
|
||||
|
|
|
@ -104,6 +104,6 @@ impl DocumentTypeMethods<crate::DomTypeHolder> for DocumentType {
|
|||
|
||||
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
||||
fn Remove(&self) {
|
||||
self.upcast::<Node>().remove_self();
|
||||
self.upcast::<Node>().remove_self(CanGc::note());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ impl DOMStringMap {
|
|||
impl DOMStringMapMethods<crate::DomTypeHolder> 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
|
||||
|
|
|
@ -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::<Node>().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::<Node>().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>();
|
||||
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<DomRoot<Attr>> {
|
||||
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<DomRoot<Attr>> {
|
||||
self.remove_first_matching_attribute(|attr| attr.name() == name)
|
||||
pub(crate) fn remove_attribute_by_name(
|
||||
&self,
|
||||
name: &LocalName,
|
||||
can_gc: CanGc,
|
||||
) -> Option<DomRoot<Attr>> {
|
||||
self.remove_first_matching_attribute(|attr| attr.name() == name, can_gc)
|
||||
}
|
||||
|
||||
fn remove_first_matching_attribute<F>(&self, find: F) -> Option<DomRoot<Attr>>
|
||||
fn remove_first_matching_attribute<F>(&self, find: F, can_gc: CanGc) -> Option<DomRoot<Attr>>
|
||||
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<Option<DomRoot<Node>>> {
|
||||
let self_node = self.upcast::<Node>();
|
||||
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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<DOMString>, 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<DomRoot<Attr>> {
|
||||
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<crate::DomTypeHolder> for Element {
|
|||
}
|
||||
|
||||
// Replace all with fragment within target.
|
||||
Node::replace_all(Some(frag.upcast()), &target);
|
||||
Node::replace_all(Some(frag.upcast()), &target, can_gc);
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-element-gethtml>
|
||||
|
@ -3013,7 +3035,7 @@ impl ElementMethods<crate::DomTypeHolder> 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<crate::DomTypeHolder> for Element {
|
|||
|
||||
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
||||
fn Remove(&self) {
|
||||
self.upcast::<Node>().remove_self();
|
||||
self.upcast::<Node>().remove_self(CanGc::note());
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-element-matches
|
||||
|
@ -3213,7 +3235,7 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
|
|||
element: &Element,
|
||||
) -> Fallible<Option<DomRoot<Element>>> {
|
||||
let where_ = where_.parse::<AdjacentPosition>()?;
|
||||
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<crate::DomTypeHolder> for Element {
|
|||
|
||||
// Step 2.
|
||||
let where_ = where_.parse::<AdjacentPosition>()?;
|
||||
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<crate::DomTypeHolder> 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::<Node>();
|
||||
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: `<form><fieldset><input>`,
|
||||
// if `<input>` is unbound, `<form><fieldset>` 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::<Node>().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);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ impl ElementInternalsMethods<crate::DomTypeHolder> 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.
|
||||
|
|
|
@ -584,7 +584,7 @@ impl Event {
|
|||
if let Some(target) = self.GetTarget() {
|
||||
if let Some(node) = target.downcast::<Node>() {
|
||||
let vtable = vtable_for(node);
|
||||
vtable.handle_event(self);
|
||||
vtable.handle_event(self, can_gc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -117,20 +117,22 @@ impl VirtualMethods for HTMLBaseElement {
|
|||
Some(self.upcast::<HTMLElement>() 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,8 +242,10 @@ impl VirtualMethods for HTMLButtonElement {
|
|||
Some(self.upcast::<HTMLElement>() 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::<Element>();
|
||||
|
@ -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::<Element>()
|
||||
.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::<Node>();
|
||||
let el = self.upcast::<Element>();
|
||||
|
|
|
@ -698,8 +698,10 @@ impl VirtualMethods for HTMLCanvasElement {
|
|||
Some(self.upcast::<HTMLElement>() 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(),
|
||||
_ => (),
|
||||
|
|
|
@ -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::<Node>()
|
||||
.SetTextContent(Some(DEFAULT_SUMMARY.into()), can_gc);
|
||||
|
@ -232,8 +232,10 @@ impl VirtualMethods for HTMLDetailsElement {
|
|||
Some(self.upcast::<HTMLElement>() 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());
|
||||
|
|
|
@ -105,7 +105,7 @@ impl HTMLDialogElementMethods<crate::DomTypeHolder> for HTMLDialogElement {
|
|||
|
||||
// Step 1 & 2
|
||||
if element
|
||||
.remove_attribute(&ns!(), &local_name!("open"))
|
||||
.remove_attribute(&ns!(), &local_name!("open"), CanGc::note())
|
||||
.is_none()
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -499,7 +499,7 @@ impl HTMLElementMethods<crate::DomTypeHolder> 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>());
|
||||
Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>(), can_gc);
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-outertext>
|
||||
|
@ -542,13 +542,13 @@ impl HTMLElementMethods<crate::DomTypeHolder> 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);
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#category-label>
|
||||
|
@ -1039,7 +1040,7 @@ impl HTMLElement {
|
|||
/// node.
|
||||
///
|
||||
/// <https://html.spec.whatwg.org/multipage/#merge-with-the-next-text-node>
|
||||
fn merge_with_the_next_text_node(node: DomRoot<Node>) {
|
||||
fn merge_with_the_next_text_node(node: DomRoot<Node>, can_gc: CanGc) {
|
||||
// Make sure node is a Text node
|
||||
if !node.is::<Text>() {
|
||||
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
|
||||
|
|
|
@ -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::<Node>()
|
||||
.traverse_preorder(ShadowIncluding::No)
|
||||
.flat_map(DomRoot::downcast::<Element>)
|
||||
.any(|element| element.is_invalid(false));
|
||||
.any(|element| element.is_invalid(false, can_gc));
|
||||
|
||||
self.upcast::<Element>()
|
||||
.set_state(ElementState::VALID, !has_invalid_child);
|
||||
|
@ -153,8 +153,10 @@ impl VirtualMethods for HTMLFieldSetElement {
|
|||
Some(self.upcast::<HTMLElement>() 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);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
|
|
@ -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::<Element>()
|
||||
.set_state(ElementState::VALID, !is_any_invalid);
|
||||
|
@ -1087,7 +1089,7 @@ impl HTMLFormElement {
|
|||
.iter()
|
||||
.filter_map(|field| {
|
||||
if let Some(element) = field.downcast::<Element>() {
|
||||
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<T: ?Sized + FormControl>(&self, control: &T) {
|
||||
fn add_control<T: ?Sized + FormControl>(&self, control: &T, can_gc: CanGc) {
|
||||
{
|
||||
let root = self.upcast::<Element>().root_element();
|
||||
let root = root.upcast::<Node>();
|
||||
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<T: ?Sized + FormControl>(&self, control: &T) {
|
||||
fn remove_control<T: ?Sized + FormControl>(&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>();
|
||||
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::<Node>();
|
||||
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::<HTMLElement>() {
|
||||
|
@ -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::<Node>();
|
||||
|
||||
|
@ -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::<HTMLElement>() 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
|
||||
|
|
|
@ -132,9 +132,9 @@ impl VirtualMethods for HTMLHeadElement {
|
|||
fn super_type(&self) -> Option<&dyn VirtualMethods> {
|
||||
Some(self.upcast::<HTMLElement>() 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);
|
||||
}
|
||||
|
|
|
@ -676,8 +676,10 @@ impl VirtualMethods for HTMLIFrameElement {
|
|||
Some(self.upcast::<HTMLElement>() 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());
|
||||
|
|
|
@ -1743,13 +1743,15 @@ impl VirtualMethods for HTMLImageElement {
|
|||
Some(self.upcast::<HTMLElement>() 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);
|
||||
|
||||
|
|
|
@ -1340,7 +1340,7 @@ impl HTMLInputElementMethods<crate::DomTypeHolder> for HTMLInputElement {
|
|||
}
|
||||
|
||||
self.validity_state()
|
||||
.perform_validation_and_update(ValidationFlags::all());
|
||||
.perform_validation_and_update(ValidationFlags::all(), can_gc);
|
||||
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2322,8 +2322,10 @@ impl VirtualMethods for HTMLInputElement {
|
|||
Some(self.upcast::<HTMLElement>() 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::<Element>()
|
||||
.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::<Node>();
|
||||
let el = self.upcast::<Element>();
|
||||
|
@ -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::<HTMLInputElement>().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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,17 +61,17 @@ impl VirtualMethods for HTMLLegendElement {
|
|||
Some(self.upcast::<HTMLElement>() 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::<Element>()
|
||||
.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::<Node>();
|
||||
let el = self.upcast::<Element>();
|
||||
|
|
|
@ -216,8 +216,10 @@ impl VirtualMethods for HTMLLinkElement {
|
|||
Some(self.upcast::<HTMLElement>() 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::<Node>().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() {
|
||||
|
|
|
@ -1956,9 +1956,9 @@ impl HTMLMediaElement {
|
|||
self.upcast::<Node>().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::<HTMLElement>() 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 {
|
||||
|
|
|
@ -252,9 +252,9 @@ impl VirtualMethods for HTMLMetaElement {
|
|||
Some(self.upcast::<HTMLElement>() 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 {
|
||||
|
|
|
@ -331,8 +331,10 @@ impl VirtualMethods for HTMLMeterElement {
|
|||
Some(self.upcast::<HTMLElement>() 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());
|
||||
}
|
||||
|
|
|
@ -153,8 +153,10 @@ impl VirtualMethods for HTMLObjectElement {
|
|||
Some(self.upcast::<HTMLElement>() 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);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
|
|
@ -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::<HTMLElement>() 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::<HTMLSelectElement>() {
|
||||
select
|
||||
.validity_state()
|
||||
.perform_validation_and_update(ValidationFlags::all());
|
||||
.perform_validation_and_update(ValidationFlags::all(), can_gc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<Node>()
|
||||
.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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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::<HTMLElement>() 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::<Element>();
|
||||
|
@ -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::<Element>()
|
||||
.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();
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ impl HTMLOptionsCollectionMethods<crate::DomTypeHolder> for HTMLOptionsCollectio
|
|||
let node = value.upcast::<Node>();
|
||||
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::<Node>();
|
||||
|
@ -220,7 +220,7 @@ impl HTMLOptionsCollectionMethods<crate::DomTypeHolder> 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(|_| ())
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-htmloptionscollection-remove>
|
||||
|
|
|
@ -159,10 +159,12 @@ impl VirtualMethods for HTMLOutputElement {
|
|||
Some(self.upcast::<HTMLElement>() 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,8 +227,10 @@ impl VirtualMethods for HTMLProgressElement {
|
|||
Some(self.upcast::<HTMLElement>() 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());
|
||||
}
|
||||
|
|
|
@ -1242,8 +1242,10 @@ impl VirtualMethods for HTMLScriptElement {
|
|||
Some(self.upcast::<HTMLElement>() 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::<Node>().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
|
||||
|
|
|
@ -356,7 +356,7 @@ impl HTMLSelectElementMethods<crate::DomTypeHolder> 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::<HTMLElement>() 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::<Element>();
|
||||
|
@ -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::<Element>()
|
||||
.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::<Node>();
|
||||
let el = self.upcast::<Element>();
|
||||
|
@ -517,7 +519,11 @@ impl Validatable for HTMLSelectElement {
|
|||
!self.upcast::<Element>().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
|
||||
|
|
|
@ -461,8 +461,10 @@ impl VirtualMethods for HTMLSlotElement {
|
|||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#shadow-tree-slots>
|
||||
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() {
|
||||
|
|
|
@ -72,8 +72,10 @@ impl VirtualMethods for HTMLSourceElement {
|
|||
Some(self.upcast::<HTMLElement>() 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 {
|
|||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#the-source-element:nodes-are-inserted>
|
||||
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::<Node>().GetParentNode().unwrap();
|
||||
if let Some(media) = parent.downcast::<HTMLMediaElement>() {
|
||||
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(
|
||||
|
|
|
@ -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::<Node>();
|
||||
|
|
|
@ -114,6 +114,7 @@ impl HTMLTableElement {
|
|||
atom: &LocalName,
|
||||
section: Option<&HTMLTableSectionElement>,
|
||||
reference_predicate: P,
|
||||
can_gc: CanGc,
|
||||
) -> ErrorResult
|
||||
where
|
||||
P: FnMut(&DomRoot<Element>) -> 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::<Node>();
|
||||
|
||||
|
@ -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::<Node>().remove_self();
|
||||
thead.upcast::<Node>().remove_self(can_gc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,7 +207,7 @@ impl HTMLTableElementMethods<crate::DomTypeHolder> 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::<Node>().remove_self();
|
||||
caption.upcast::<Node>().remove_self(CanGc::note());
|
||||
}
|
||||
|
||||
if let Some(caption) = new_caption {
|
||||
|
@ -239,7 +240,7 @@ impl HTMLTableElementMethods<crate::DomTypeHolder> for HTMLTableElement {
|
|||
// https://html.spec.whatwg.org/multipage/#dom-table-deletecaption
|
||||
fn DeleteCaption(&self) {
|
||||
if let Some(caption) = self.GetCaption() {
|
||||
caption.upcast::<Node>().remove_self();
|
||||
caption.upcast::<Node>().remove_self(CanGc::note());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,9 +251,12 @@ impl HTMLTableElementMethods<crate::DomTypeHolder> 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::<HTMLTableCaptionElement>() && !n.is::<HTMLTableColElement>()
|
||||
})
|
||||
self.set_first_section_of_type(
|
||||
&local_name!("thead"),
|
||||
thead,
|
||||
|n| !n.is::<HTMLTableCaptionElement>() && !n.is::<HTMLTableColElement>(),
|
||||
CanGc::note(),
|
||||
)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-table-createthead
|
||||
|
@ -262,7 +266,7 @@ impl HTMLTableElementMethods<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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::<HTMLTableCaptionElement>() || n.is::<HTMLTableColElement>() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if n.is::<HTMLTableSectionElement>() {
|
||||
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::<HTMLTableCaptionElement>() || n.is::<HTMLTableColElement>() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
if n.is::<HTMLTableSectionElement>() {
|
||||
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<crate::DomTypeHolder> 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<crate::DomTypeHolder> for HTMLTableElement {
|
|||
}
|
||||
|
||||
// Step 3: Otherwise, remove the indexth element in the rows collection from its parent.
|
||||
DomRoot::upcast::<Node>(rows.Item(index as u32).unwrap()).remove_self();
|
||||
DomRoot::upcast::<Node>(rows.Item(index as u32).unwrap()).remove_self(CanGc::note());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -503,8 +512,10 @@ impl VirtualMethods for HTMLTableElement {
|
|||
Some(self.upcast::<HTMLElement>() 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.
|
||||
|
|
|
@ -104,13 +104,19 @@ impl HTMLTableRowElementMethods<crate::DomTypeHolder> 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>();
|
||||
node.delete_cell_or_row(index, || self.Cells(), |n| n.is::<HTMLTableCellElement>())
|
||||
node.delete_cell_or_row(
|
||||
index,
|
||||
|| self.Cells(),
|
||||
|n| n.is::<HTMLTableCellElement>(),
|
||||
CanGc::note(),
|
||||
)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-tr-rowindex
|
||||
|
|
|
@ -77,13 +77,19 @@ impl HTMLTableSectionElementMethods<crate::DomTypeHolder> 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>();
|
||||
node.delete_cell_or_row(index, || self.Rows(), |n| n.is::<HTMLTableRowElement>())
|
||||
node.delete_cell_or_row(
|
||||
index,
|
||||
|| self.Rows(),
|
||||
|n| n.is::<HTMLTableRowElement>(),
|
||||
CanGc::note(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,14 +113,14 @@ impl VirtualMethods for HTMLTemplateElement {
|
|||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#template-adopting-steps>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#the-template-element:concept-node-clone-ext>
|
||||
|
@ -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;
|
||||
|
|
|
@ -347,7 +347,7 @@ impl HTMLTextAreaElementMethods<crate::DomTypeHolder> for HTMLTextAreaElement {
|
|||
}
|
||||
|
||||
self.validity_state()
|
||||
.perform_validation_and_update(ValidationFlags::all());
|
||||
.perform_validation_and_update(ValidationFlags::all(), CanGc::note());
|
||||
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
||||
}
|
||||
|
||||
|
@ -468,8 +468,10 @@ impl VirtualMethods for HTMLTextAreaElement {
|
|||
Some(self.upcast::<HTMLElement>() 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::<Element>();
|
||||
|
@ -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::<Element>()
|
||||
.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::<Node>();
|
||||
let el = self.upcast::<Element>();
|
||||
|
@ -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::<HTMLTextAreaElement>().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();
|
||||
|
|
|
@ -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::<Node>();
|
||||
if context.tree_is_in_a_document_tree {
|
||||
|
|
|
@ -305,8 +305,10 @@ impl VirtualMethods for HTMLVideoElement {
|
|||
Some(self.upcast::<HTMLMediaElement>() 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) {
|
||||
|
|
|
@ -79,7 +79,7 @@ impl NamedNodeMapMethods<crate::DomTypeHolder> for NamedNodeMap {
|
|||
fn RemoveNamedItem(&self, name: DOMString) -> Fallible<DomRoot<Attr>> {
|
||||
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<crate::DomTypeHolder> for NamedNodeMap {
|
|||
) -> Fallible<DomRoot<Attr>> {
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-remove>
|
||||
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 <form>.
|
||||
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<u32>) {
|
||||
fn remove_child(&self, child: &Node, cached_index: Option<u32>, 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(|_| ())
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-parentnode-append>
|
||||
|
@ -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<DomRoot<HTMLElement>>
|
||||
where
|
||||
F: Fn() -> DomRoot<HTMLCollection>,
|
||||
|
@ -1305,6 +1309,7 @@ impl Node {
|
|||
index: i32,
|
||||
get_items: F,
|
||||
is_delete_type: G,
|
||||
can_gc: CanGc,
|
||||
) -> ErrorResult
|
||||
where
|
||||
F: Fn() -> DomRoot<HTMLCollection>,
|
||||
|
@ -1329,7 +1334,7 @@ impl Node {
|
|||
},
|
||||
};
|
||||
|
||||
element.upcast::<Node>().remove_self();
|
||||
element.upcast::<Node>().remove_self(can_gc);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -2046,7 +2051,7 @@ impl Node {
|
|||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-adopt>
|
||||
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<DomRoot<Node>> {
|
||||
// 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 {
|
|||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-replace-all>
|
||||
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 {
|
|||
/// <https://dom.spec.whatwg.org/multipage/#string-replace-all>
|
||||
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::<Node>()), parent);
|
||||
Node::replace_all(Some(text.upcast::<Node>()), parent, can_gc);
|
||||
};
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-pre-remove>
|
||||
fn pre_remove(child: &Node, parent: &Node) -> Fallible<DomRoot<Node>> {
|
||||
fn pre_remove(child: &Node, parent: &Node, can_gc: CanGc) -> Fallible<DomRoot<Node>> {
|
||||
// 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))
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-remove>
|
||||
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::<Node>(), None);
|
||||
let _inserted_node = Node::pre_insert(
|
||||
&child_copy,
|
||||
copy_shadow_root.upcast::<Node>(),
|
||||
None,
|
||||
can_gc,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3115,7 +3127,7 @@ impl NodeMethods<crate::DomTypeHolder> 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::<Attr>().unwrap();
|
||||
|
@ -3131,12 +3143,12 @@ impl NodeMethods<crate::DomTypeHolder> for Node {
|
|||
|
||||
/// <https://dom.spec.whatwg.org/#dom-node-insertbefore>
|
||||
fn InsertBefore(&self, node: &Node, child: Option<&Node>) -> Fallible<DomRoot<Node>> {
|
||||
Node::pre_insert(node, self, child)
|
||||
Node::pre_insert(node, self, child, CanGc::note())
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-node-appendchild>
|
||||
fn AppendChild(&self, node: &Node) -> Fallible<DomRoot<Node>> {
|
||||
Node::pre_insert(node, self, None)
|
||||
Node::pre_insert(node, self, None, CanGc::note())
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-replace>
|
||||
|
@ -3238,11 +3250,11 @@ impl NodeMethods<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<crate::DomTypeHolder> for Node {
|
|||
|
||||
/// <https://dom.spec.whatwg.org/#dom-node-removechild>
|
||||
fn RemoveChild(&self, node: &Node) -> Fallible<DomRoot<Node>> {
|
||||
Node::pre_remove(node, self)
|
||||
Node::pre_remove(node, self, CanGc::note())
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-node-normalize>
|
||||
|
@ -3297,7 +3315,7 @@ impl NodeMethods<crate::DomTypeHolder> for Node {
|
|||
let cdata = text.upcast::<CharacterData>();
|
||||
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<crate::DomTypeHolder> for Node {
|
|||
let sibling_cdata = sibling.downcast::<CharacterData>().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.
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-remove>
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -884,7 +884,7 @@ impl RangeMethods<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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)?;
|
||||
|
|
|
@ -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 } => {
|
||||
|
|
|
@ -713,7 +713,7 @@ where
|
|||
|
||||
fn next(&mut self) -> Option<DomRoot<Node>> {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>();
|
||||
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::<Node>()
|
||||
.inclusive_ancestors(ShadowIncluding::No)
|
||||
|
@ -445,7 +445,7 @@ impl ShadowRootMethods<crate::DomTypeHolder> 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);
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-shadowroot-slotassignment>
|
||||
|
@ -462,9 +462,9 @@ impl VirtualMethods for ShadowRoot {
|
|||
Some(self.upcast::<DocumentFragment>() 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 {
|
||||
|
|
|
@ -79,8 +79,10 @@ impl VirtualMethods for SVGSVGElement {
|
|||
Some(self.upcast::<SVGGraphicsElement>() 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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<HTMLFieldSetElement>)
|
||||
.next()
|
||||
{
|
||||
fieldset.update_validity();
|
||||
fieldset.update_validity(can_gc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
/// <https://dom.spec.whatwg.org/#attribute-is-set>
|
||||
/// <https://dom.spec.whatwg.org/#attribute-is-removed>
|
||||
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:
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-remove-ext>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-adopt-ext>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1148,6 +1148,7 @@ pub(crate) fn handle_get_url(
|
|||
documents: &DocumentCollection,
|
||||
pipeline: PipelineId,
|
||||
reply: IpcSender<ServoUrl>,
|
||||
_can_gc: CanGc,
|
||||
) {
|
||||
reply
|
||||
.send(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue