diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 63c1e635dad..b6593196d5f 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::borrow::ToOwned; +use std::cell::LazyCell; use std::mem; use devtools_traits::AttrInfo; @@ -157,11 +158,11 @@ impl Attr { let namespace = self.namespace().clone(); let old_value = DOMString::from(&**self.value()); let new_value = DOMString::from(&*value); - let mutation = Mutation::Attribute { + let mutation = LazyCell::new(|| Mutation::Attribute { name: name.clone(), namespace: namespace.clone(), old_value: Some(old_value.clone()), - }; + }); MutationObserver::queue_a_mutation_record(owner.upcast::(), mutation); diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index 381f7e4e59b..3c33a7c5010 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! DOM bindings for `CharacterData`. +use std::cell::LazyCell; use dom_struct::dom_struct; @@ -100,9 +101,9 @@ impl CharacterData { // Queue a MutationObserver record before changing the content. fn queue_mutation_record(&self) { - let mutation = Mutation::CharacterData { + let mutation = LazyCell::new(|| Mutation::CharacterData { old_value: self.data.borrow().clone(), - }; + }); MutationObserver::queue_a_mutation_record(self.upcast::(), mutation); } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 4ed92704d60..24e760d510c 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -5,7 +5,7 @@ //! Element nodes. use std::borrow::Cow; -use std::cell::Cell; +use std::cell::{Cell, LazyCell}; use std::default::Default; use std::ops::Deref; use std::rc::Rc; @@ -1557,11 +1557,11 @@ impl Element { pub(crate) fn push_attribute(&self, attr: &Attr) { let name = attr.local_name().clone(); let namespace = attr.namespace().clone(); - let mutation = Mutation::Attribute { + let mutation = LazyCell::new(|| Mutation::Attribute { name: name.clone(), namespace: namespace.clone(), old_value: None, - }; + }); MutationObserver::queue_a_mutation_record(&self.node, mutation); @@ -1749,11 +1749,11 @@ impl Element { let name = attr.local_name().clone(); let namespace = attr.namespace().clone(); let old_value = DOMString::from(&**attr.value()); - let mutation = Mutation::Attribute { + let mutation = LazyCell::new(|| Mutation::Attribute { name: name.clone(), namespace: namespace.clone(), old_value: Some(old_value.clone()), - }; + }); MutationObserver::queue_a_mutation_record(&self.node, mutation); diff --git a/components/script/dom/mutationobserver.rs b/components/script/dom/mutationobserver.rs index cde780aa122..0f8ecc24e65 100644 --- a/components/script/dom/mutationobserver.rs +++ b/components/script/dom/mutationobserver.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::cell::LazyCell; use std::rc::Rc; use dom_struct::dom_struct; @@ -146,7 +147,12 @@ impl MutationObserver { } /// - pub(crate) fn queue_a_mutation_record(target: &Node, attr_type: Mutation) { + pub(crate) fn queue_a_mutation_record<'a, F>( + target: &Node, + attr_type: LazyCell, F>, + ) where + F: FnOnce() -> Mutation<'a>, + { if !target.global().as_window().get_exists_mut_observer() { return; } @@ -165,7 +171,7 @@ impl MutationObserver { continue; } - match attr_type { + match *attr_type { Mutation::Attribute { ref name, ref namespace, @@ -239,7 +245,7 @@ impl MutationObserver { // Step 4 for (observer, paired_string) in interested_observers { // Steps 4.1-4.7 - let record = match attr_type { + let record = match *attr_type { Mutation::Attribute { ref name, ref namespace, diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 3491a8ed20e..935e7f0d746 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -5,7 +5,7 @@ //! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements. use std::borrow::Cow; -use std::cell::{Cell, UnsafeCell}; +use std::cell::{Cell, LazyCell, UnsafeCell}; use std::default::Default; use std::ops::Range; use std::slice::from_ref; @@ -2130,12 +2130,12 @@ impl Node { // Step 5. vtable_for(node).children_changed(&ChildrenMutation::replace_all(new_nodes.r(), &[])); - let mutation = Mutation::ChildList { + let mutation = LazyCell::new(|| Mutation::ChildList { added: None, removed: Some(new_nodes.r()), prev: None, next: None, - }; + }); MutationObserver::queue_a_mutation_record(node, mutation); new_nodes.r() @@ -2208,12 +2208,12 @@ impl Node { child, )); - let mutation = Mutation::ChildList { + let mutation = LazyCell::new(|| Mutation::ChildList { added: Some(new_nodes), removed: None, prev: previous_sibling.as_deref(), next: child, - }; + }); MutationObserver::queue_a_mutation_record(parent, mutation); } @@ -2287,12 +2287,12 @@ impl Node { )); if !removed_nodes.is_empty() || !added_nodes.is_empty() { - let mutation = Mutation::ChildList { + let mutation = LazyCell::new(|| Mutation::ChildList { added: Some(added_nodes), removed: Some(removed_nodes.r()), prev: None, next: None, - }; + }); MutationObserver::queue_a_mutation_record(parent, mutation); } parent.owner_doc().remove_script_and_layout_blocker(); @@ -2405,12 +2405,12 @@ impl Node { )); let removed = [node]; - let mutation = Mutation::ChildList { + let mutation = LazyCell::new(|| Mutation::ChildList { added: None, removed: Some(&removed), prev: old_previous_sibling.as_deref(), next: old_next_sibling.as_deref(), - }; + }); MutationObserver::queue_a_mutation_record(parent, mutation); } parent.owner_doc().remove_script_and_layout_blocker(); @@ -3072,12 +3072,12 @@ impl NodeMethods for Node { reference_child, )); let removed = removed_child.map(|r| [r]); - let mutation = Mutation::ChildList { + let mutation = LazyCell::new(|| Mutation::ChildList { added: Some(nodes), removed: removed.as_ref().map(|r| &r[..]), prev: previous_sibling.as_deref(), next: reference_child, - }; + }); MutationObserver::queue_a_mutation_record(self, mutation);