script: delay Mutation initialization (#35291)

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
Euclid Ye 2025-02-05 14:28:10 +08:00 committed by GitHub
parent 503bb10c5b
commit 789736590b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 31 additions and 23 deletions

View file

@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::cell::LazyCell;
use std::mem; use std::mem;
use devtools_traits::AttrInfo; use devtools_traits::AttrInfo;
@ -157,11 +158,11 @@ impl Attr {
let namespace = self.namespace().clone(); let namespace = self.namespace().clone();
let old_value = DOMString::from(&**self.value()); let old_value = DOMString::from(&**self.value());
let new_value = DOMString::from(&*value); let new_value = DOMString::from(&*value);
let mutation = Mutation::Attribute { let mutation = LazyCell::new(|| Mutation::Attribute {
name: name.clone(), name: name.clone(),
namespace: namespace.clone(), namespace: namespace.clone(),
old_value: Some(old_value.clone()), old_value: Some(old_value.clone()),
}; });
MutationObserver::queue_a_mutation_record(owner.upcast::<Node>(), mutation); MutationObserver::queue_a_mutation_record(owner.upcast::<Node>(), mutation);

View file

@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! DOM bindings for `CharacterData`. //! DOM bindings for `CharacterData`.
use std::cell::LazyCell;
use dom_struct::dom_struct; use dom_struct::dom_struct;
@ -100,9 +101,9 @@ impl CharacterData {
// Queue a MutationObserver record before changing the content. // Queue a MutationObserver record before changing the content.
fn queue_mutation_record(&self) { fn queue_mutation_record(&self) {
let mutation = Mutation::CharacterData { let mutation = LazyCell::new(|| Mutation::CharacterData {
old_value: self.data.borrow().clone(), old_value: self.data.borrow().clone(),
}; });
MutationObserver::queue_a_mutation_record(self.upcast::<Node>(), mutation); MutationObserver::queue_a_mutation_record(self.upcast::<Node>(), mutation);
} }
} }

View file

@ -5,7 +5,7 @@
//! Element nodes. //! Element nodes.
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::Cell; use std::cell::{Cell, LazyCell};
use std::default::Default; use std::default::Default;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
@ -1557,11 +1557,11 @@ impl Element {
pub(crate) fn push_attribute(&self, attr: &Attr) { pub(crate) fn push_attribute(&self, attr: &Attr) {
let name = attr.local_name().clone(); let name = attr.local_name().clone();
let namespace = attr.namespace().clone(); let namespace = attr.namespace().clone();
let mutation = Mutation::Attribute { let mutation = LazyCell::new(|| Mutation::Attribute {
name: name.clone(), name: name.clone(),
namespace: namespace.clone(), namespace: namespace.clone(),
old_value: None, old_value: None,
}; });
MutationObserver::queue_a_mutation_record(&self.node, mutation); MutationObserver::queue_a_mutation_record(&self.node, mutation);
@ -1749,11 +1749,11 @@ impl Element {
let name = attr.local_name().clone(); let name = attr.local_name().clone();
let namespace = attr.namespace().clone(); let namespace = attr.namespace().clone();
let old_value = DOMString::from(&**attr.value()); let old_value = DOMString::from(&**attr.value());
let mutation = Mutation::Attribute { let mutation = LazyCell::new(|| Mutation::Attribute {
name: name.clone(), name: name.clone(),
namespace: namespace.clone(), namespace: namespace.clone(),
old_value: Some(old_value.clone()), old_value: Some(old_value.clone()),
}; });
MutationObserver::queue_a_mutation_record(&self.node, mutation); MutationObserver::queue_a_mutation_record(&self.node, mutation);

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::LazyCell;
use std::rc::Rc; use std::rc::Rc;
use dom_struct::dom_struct; use dom_struct::dom_struct;
@ -146,7 +147,12 @@ impl MutationObserver {
} }
/// <https://dom.spec.whatwg.org/#queueing-a-mutation-record> /// <https://dom.spec.whatwg.org/#queueing-a-mutation-record>
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<Mutation<'a>, F>,
) where
F: FnOnce() -> Mutation<'a>,
{
if !target.global().as_window().get_exists_mut_observer() { if !target.global().as_window().get_exists_mut_observer() {
return; return;
} }
@ -165,7 +171,7 @@ impl MutationObserver {
continue; continue;
} }
match attr_type { match *attr_type {
Mutation::Attribute { Mutation::Attribute {
ref name, ref name,
ref namespace, ref namespace,
@ -239,7 +245,7 @@ impl MutationObserver {
// Step 4 // Step 4
for (observer, paired_string) in interested_observers { for (observer, paired_string) in interested_observers {
// Steps 4.1-4.7 // Steps 4.1-4.7
let record = match attr_type { let record = match *attr_type {
Mutation::Attribute { Mutation::Attribute {
ref name, ref name,
ref namespace, ref namespace,

View file

@ -5,7 +5,7 @@
//! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements. //! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements.
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::{Cell, UnsafeCell}; use std::cell::{Cell, LazyCell, UnsafeCell};
use std::default::Default; use std::default::Default;
use std::ops::Range; use std::ops::Range;
use std::slice::from_ref; use std::slice::from_ref;
@ -2130,12 +2130,12 @@ impl Node {
// Step 5. // Step 5.
vtable_for(node).children_changed(&ChildrenMutation::replace_all(new_nodes.r(), &[])); vtable_for(node).children_changed(&ChildrenMutation::replace_all(new_nodes.r(), &[]));
let mutation = Mutation::ChildList { let mutation = LazyCell::new(|| Mutation::ChildList {
added: None, added: None,
removed: Some(new_nodes.r()), removed: Some(new_nodes.r()),
prev: None, prev: None,
next: None, next: None,
}; });
MutationObserver::queue_a_mutation_record(node, mutation); MutationObserver::queue_a_mutation_record(node, mutation);
new_nodes.r() new_nodes.r()
@ -2208,12 +2208,12 @@ impl Node {
child, child,
)); ));
let mutation = Mutation::ChildList { let mutation = LazyCell::new(|| Mutation::ChildList {
added: Some(new_nodes), added: Some(new_nodes),
removed: None, removed: None,
prev: previous_sibling.as_deref(), prev: previous_sibling.as_deref(),
next: child, next: child,
}; });
MutationObserver::queue_a_mutation_record(parent, mutation); MutationObserver::queue_a_mutation_record(parent, mutation);
} }
@ -2287,12 +2287,12 @@ impl Node {
)); ));
if !removed_nodes.is_empty() || !added_nodes.is_empty() { if !removed_nodes.is_empty() || !added_nodes.is_empty() {
let mutation = Mutation::ChildList { let mutation = LazyCell::new(|| Mutation::ChildList {
added: Some(added_nodes), added: Some(added_nodes),
removed: Some(removed_nodes.r()), removed: Some(removed_nodes.r()),
prev: None, prev: None,
next: None, next: None,
}; });
MutationObserver::queue_a_mutation_record(parent, mutation); MutationObserver::queue_a_mutation_record(parent, mutation);
} }
parent.owner_doc().remove_script_and_layout_blocker(); parent.owner_doc().remove_script_and_layout_blocker();
@ -2405,12 +2405,12 @@ impl Node {
)); ));
let removed = [node]; let removed = [node];
let mutation = Mutation::ChildList { let mutation = LazyCell::new(|| Mutation::ChildList {
added: None, added: None,
removed: Some(&removed), removed: Some(&removed),
prev: old_previous_sibling.as_deref(), prev: old_previous_sibling.as_deref(),
next: old_next_sibling.as_deref(), next: old_next_sibling.as_deref(),
}; });
MutationObserver::queue_a_mutation_record(parent, mutation); MutationObserver::queue_a_mutation_record(parent, mutation);
} }
parent.owner_doc().remove_script_and_layout_blocker(); parent.owner_doc().remove_script_and_layout_blocker();
@ -3072,12 +3072,12 @@ impl NodeMethods<crate::DomTypeHolder> for Node {
reference_child, reference_child,
)); ));
let removed = removed_child.map(|r| [r]); let removed = removed_child.map(|r| [r]);
let mutation = Mutation::ChildList { let mutation = LazyCell::new(|| Mutation::ChildList {
added: Some(nodes), added: Some(nodes),
removed: removed.as_ref().map(|r| &r[..]), removed: removed.as_ref().map(|r| &r[..]),
prev: previous_sibling.as_deref(), prev: previous_sibling.as_deref(),
next: reference_child, next: reference_child,
}; });
MutationObserver::queue_a_mutation_record(self, mutation); MutationObserver::queue_a_mutation_record(self, mutation);