mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Don't run scripts while DOM tree is undergoing mutations (#34505)
* script: Implement node insertion post-connection hook. Ensure script elements only run scripts when the DOM has stabilized. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Make iframe element use post-connection steps when handling initial document insertion. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Use a delayed task when running post-connection steps. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Add explanatory comment. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Tidy. Signed-off-by: Josh Matthews <josh@joshmatthews.net> --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
20d67bdc44
commit
981616f918
10 changed files with 117 additions and 51 deletions
|
@ -55,7 +55,7 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::htmlelement::HTMLElement;
|
||||
use crate::dom::node::{
|
||||
document_from_node, window_from_node, BindContext, ChildrenMutation, CloneChildrenFlag, Node,
|
||||
document_from_node, window_from_node, ChildrenMutation, CloneChildrenFlag, Node,
|
||||
};
|
||||
use crate::dom::performanceresourcetiming::InitiatorType;
|
||||
use crate::dom::virtualmethods::VirtualMethods;
|
||||
|
@ -1188,25 +1188,32 @@ impl VirtualMethods for HTMLScriptElement {
|
|||
}
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#script-processing-model:the-script-element-26>
|
||||
fn children_changed(&self, mutation: &ChildrenMutation) {
|
||||
if let Some(s) = self.super_type() {
|
||||
s.children_changed(mutation);
|
||||
}
|
||||
if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() {
|
||||
self.prepare(CanGc::note());
|
||||
|
||||
if self.upcast::<Node>().is_connected() && !self.parser_inserted.get() {
|
||||
let script = Trusted::new(self);
|
||||
// This method can be invoked while there are script/layout blockers present
|
||||
// as DOM mutations have not yet settled. We use a delayed task to avoid
|
||||
// running any scripts until the DOM tree is safe for interactions.
|
||||
document_from_node(self).add_delayed_task(task!(ScriptPrepare: move || {
|
||||
let this = script.root();
|
||||
this.prepare(CanGc::note());
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, context: &BindContext) {
|
||||
/// <https://html.spec.whatwg.org/multipage/#script-processing-model:the-script-element-20>
|
||||
fn post_connection_steps(&self) {
|
||||
if let Some(s) = self.super_type() {
|
||||
s.bind_to_tree(context);
|
||||
s.post_connection_steps();
|
||||
}
|
||||
|
||||
if context.tree_connected && !self.parser_inserted.get() {
|
||||
let script = Trusted::new(self);
|
||||
document_from_node(self).add_delayed_task(task!(ScriptDelayedInitialize: move || {
|
||||
script.root().prepare(CanGc::note());
|
||||
}));
|
||||
if self.upcast::<Node>().is_connected() && !self.parser_inserted.get() {
|
||||
self.prepare(CanGc::note());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue