From 5200ded17c2c5e7f5f5dd92d302350d0b5b396c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 10 Nov 2017 01:29:41 +0100 Subject: [PATCH] script: Fix Servo relying on descendants being visited when there's a reframe. --- components/script/dom/document.rs | 10 ++++++++-- components/script/dom/node.rs | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 5214ea4da66..3c93f9a4a09 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -573,8 +573,14 @@ impl Document { self.encoding.set(encoding); } - pub fn content_and_heritage_changed(&self, node: &Node, damage: NodeDamage) { - node.dirty(damage); + pub fn content_and_heritage_changed(&self, node: &Node) { + if node.is_in_doc() { + node.note_dirty_descendants(); + } + + // FIXME(emilio): This is very inefficient, ideally the flag above would + // be enough and incremental layout could figure out from there. + node.dirty(NodeDamage::OtherNodeDamage); } /// Reflows and disarms the timer if the reflow timer has expired. diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index ff69e2ae2b3..b0f85b1ccfa 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -483,6 +483,19 @@ impl Node { self.flags.set(flags); } + // FIXME(emilio): This and the function below should move to Element. + pub fn note_dirty_descendants(&self) { + debug_assert!(self.is_in_doc()); + + for ancestor in self.inclusive_ancestors() { + if ancestor.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS) { + return; + } + + ancestor.set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, true); + } + } + pub fn has_dirty_descendants(&self) -> bool { self.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS) } @@ -2499,7 +2512,7 @@ impl VirtualMethods for Node { if let Some(list) = self.child_list.get() { list.as_children_list().children_changed(mutation); } - self.owner_doc().content_and_heritage_changed(self, NodeDamage::OtherNodeDamage); + self.owner_doc().content_and_heritage_changed(self); } // This handles the ranges mentioned in steps 2-3 when removing a node.