script: Improve dirty propagation and fix script-layout synchronization.

This fixes race conditions whereby layout and script could be running
simultaneously.
This commit is contained in:
Patrick Walton 2014-10-28 19:49:17 -07:00
parent 1bc2c8a639
commit d101c1dd91
8 changed files with 220 additions and 257 deletions

View file

@ -49,7 +49,7 @@ use dom::mouseevent::MouseEvent;
use dom::keyboardevent::KeyboardEvent;
use dom::messageevent::MessageEvent;
use dom::node::{Node, ElementNodeTypeId, DocumentNodeTypeId, NodeHelpers};
use dom::node::{CloneChildren, DoNotCloneChildren};
use dom::node::{CloneChildren, DoNotCloneChildren, NodeDamage, OtherNodeDamage};
use dom::nodelist::NodeList;
use dom::text::Text;
use dom::processinginstruction::ProcessingInstruction;
@ -176,10 +176,8 @@ pub trait DocumentHelpers<'a> {
fn set_quirks_mode(self, mode: QuirksMode);
fn set_last_modified(self, value: DOMString);
fn set_encoding_name(self, name: DOMString);
fn content_changed(self, node: JSRef<Node>);
fn content_and_heritage_changed(self, node: JSRef<Node>);
fn reflow(self);
fn wait_until_safe_to_modify_dom(self);
fn content_changed(self, node: JSRef<Node>, damage: NodeDamage);
fn content_and_heritage_changed(self, node: JSRef<Node>, damage: NodeDamage);
fn unregister_named_element(self, to_unregister: JSRef<Element>, id: Atom);
fn register_named_element(self, element: JSRef<Element>, id: Atom);
fn load_anchor_href(self, href: DOMString);
@ -190,6 +188,7 @@ pub trait DocumentHelpers<'a> {
fn request_focus(self, elem: JSRef<Element>);
fn commit_focus_transaction(self);
fn send_title_to_compositor(self);
fn dirty_all_nodes(self);
}
impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
@ -228,24 +227,14 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
*self.encoding_name.borrow_mut() = name;
}
fn content_changed(self, node: JSRef<Node>) {
debug!("content_changed on {}", node.debug_str());
node.dirty();
self.reflow();
fn content_changed(self, node: JSRef<Node>, damage: NodeDamage) {
node.dirty(damage);
}
fn content_and_heritage_changed(self, node: JSRef<Node>) {
fn content_and_heritage_changed(self, node: JSRef<Node>, damage: NodeDamage) {
debug!("content_and_heritage_changed on {}", node.debug_str());
node.force_dirty_ancestors();
self.reflow();
}
fn reflow(self) {
self.window.root().reflow();
}
fn wait_until_safe_to_modify_dom(self) {
self.window.root().wait_until_safe_to_modify_dom();
node.force_dirty_ancestors(damage);
node.dirty(damage);
}
/// Remove any existing association between the provided id and any elements in this document.
@ -376,6 +365,13 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
let window = self.window().root();
window.page().send_title_to_compositor();
}
fn dirty_all_nodes(self) {
let root: JSRef<Node> = NodeCast::from_ref(self);
for node in root.traverse_preorder() {
node.dirty(OtherNodeDamage)
}
}
}
#[deriving(PartialEq)]