Trigger a reflow when nodes are appended and removed from the document. Fixes #907.

This commit is contained in:
Josh Matthews 2013-09-11 21:03:56 -07:00
parent 2372a84149
commit 4ec428b9d6
3 changed files with 50 additions and 5 deletions

View file

@ -33,6 +33,7 @@ pub trait WrappableDocument {
fn init_wrapper(@mut self, cx: *JSContext); fn init_wrapper(@mut self, cx: *JSContext);
} }
#[deriving(Eq)]
pub struct AbstractDocument { pub struct AbstractDocument {
document: *Document document: *Document
} }

View file

@ -414,6 +414,7 @@ impl Node<ScriptView> {
} }
pub fn add_to_doc(&mut self, doc: AbstractDocument) { pub fn add_to_doc(&mut self, doc: AbstractDocument) {
let old_doc = self.owner_doc;
self.owner_doc = Some(doc); self.owner_doc = Some(doc);
let mut cur_node = self.first_child; let mut cur_node = self.first_child;
while cur_node.is_some() { while cur_node.is_some() {
@ -424,6 +425,42 @@ impl Node<ScriptView> {
}; };
cur_node = cur_node.unwrap().next_sibling(); cur_node = cur_node.unwrap().next_sibling();
} }
// Signal the old document that it needs to update its display
match old_doc {
Some(old_doc) if old_doc != doc => do old_doc.with_base |old_doc| {
old_doc.content_changed();
},
_ => ()
}
// Signal the new document that it needs to update its display
do doc.with_base |doc| {
doc.content_changed();
}
}
pub fn remove_from_doc(&mut self) {
let old_doc = self.owner_doc;
self.owner_doc = None;
let mut cur_node = self.first_child;
while cur_node.is_some() {
for node in cur_node.unwrap().traverse_preorder() {
do node.with_mut_base |node_base| {
node_base.owner_doc = None;
}
};
cur_node = cur_node.unwrap().next_sibling();
}
// Signal the old document that it needs to update its display
match old_doc {
Some(doc) => do doc.with_base |doc| {
doc.content_changed();
},
None => ()
}
} }
pub fn new(type_id: NodeTypeId) -> Node<ScriptView> { pub fn new(type_id: NodeTypeId) -> Node<ScriptView> {
@ -592,6 +629,12 @@ impl Node<ScriptView> {
// If the node already exists it is removed from current parent node. // If the node already exists it is removed from current parent node.
node.parent_node().map(|parent| parent.remove_child(node)); node.parent_node().map(|parent| parent.remove_child(node));
abstract_self.add_child(node); abstract_self.add_child(node);
match self.owner_doc {
Some(doc) => do node.with_mut_base |node| {
node.add_to_doc(doc);
},
None => ()
}
} }
node node
} }
@ -617,6 +660,7 @@ impl Node<ScriptView> {
} }
if rv.is_ok() { if rv.is_ok() {
abstract_self.remove_child(node); abstract_self.remove_child(node);
self.remove_from_doc();
} }
node node
} }

View file

@ -611,11 +611,6 @@ impl ScriptTask {
let document = HTMLDocument::new(root, Some(window)); let document = HTMLDocument::new(root, Some(window));
// Tie the root into the document.
do root.with_mut_base |base| {
base.add_to_doc(document)
}
// Create the root frame. // Create the root frame.
page.frame = Some(Frame { page.frame = Some(Frame {
document: document, document: document,
@ -623,6 +618,11 @@ impl ScriptTask {
}); });
page.url = Some((url.clone(), true)); page.url = Some((url.clone(), true));
// Tie the root into the document.
do root.with_mut_base |base| {
base.add_to_doc(document)
}
// Send style sheets over to layout. // Send style sheets over to layout.
// //
// FIXME: These should be streamed to layout as they're parsed. We don't need to stop here // FIXME: These should be streamed to layout as they're parsed. We don't need to stop here