diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 1362f1cb7b2..b1087e945d7 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -77,7 +77,9 @@ impl<'lc, N> DomTraversalContext for RecalcStyleAndConstructFlows<'lc> recalc_style_at(&self.context, self.root, node); } - fn process_postorder(&self, node: N) { construct_flows_at(&self.context, self.root, node); } + fn process_postorder(&self, node: N) { + construct_flows_at(&self.context, self.root, node); + } } /// A bottom-up, parallelizable traversal. @@ -96,7 +98,7 @@ fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: O // Always reconstruct if incremental layout is turned off. let nonincremental_layout = opts::get().nonincremental_layout; - if nonincremental_layout || node.has_dirty_descendants() { + if nonincremental_layout || node.is_dirty() || node.has_dirty_descendants() { let mut flow_constructor = FlowConstructor::new(context); if nonincremental_layout || !flow_constructor.repair_if_possible(&tnode) { flow_constructor.process(&tnode); diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 37495be3ba3..0e5e360c6e1 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -479,19 +479,7 @@ impl Node { return } - // 2. Dirty descendants. - fn dirty_subtree(node: &Node) { - // Stop if this subtree is already dirty. - if node.is_dirty() { return } - - node.set_flag(IS_DIRTY | HAS_DIRTY_DESCENDANTS, true); - - for kid in node.children() { - dirty_subtree(kid.r()); - } - } - - dirty_subtree(self); + self.set_flag(IS_DIRTY, true); // 4. Dirty ancestors. for ancestor in self.ancestors() { diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 69521c1557a..c0d197896af 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -153,10 +153,24 @@ pub trait DomTraversalContext { /// /// Note that this is true unconditionally for servo, since it requires to /// bubble the widths bottom-up for all the DOM. - fn should_process(&self, _node: N) -> bool { true } + fn should_process(&self, node: N) -> bool { + node.is_dirty() || node.has_dirty_descendants() + } /// Do an action over the child before pushing him to the work queue. - fn pre_process_child_hook(&self, _parent: N, _kid: N) {} + /// + /// By default, propagate the IS_DIRTY flag down the tree. + #[allow(unsafe_code)] + fn pre_process_child_hook(&self, parent: N, kid: N) { + // NOTE: At this point is completely safe to modify either the parent or + // the child, since we have exclusive access to both of them. + if parent.is_dirty() { + unsafe { + kid.set_dirty(true); + parent.set_dirty_descendants(true); + } + } + } } /// Calculates the style for a single node. diff --git a/ports/geckolib/traversal.rs b/ports/geckolib/traversal.rs index 562153baf07..87b63e83e15 100644 --- a/ports/geckolib/traversal.rs +++ b/ports/geckolib/traversal.rs @@ -6,7 +6,6 @@ use context::StandaloneStyleContext; use std::mem; use style::context::SharedStyleContext; use style::dom::OpaqueNode; -use style::dom::TNode; use style::traversal::{DomTraversalContext, recalc_style_at}; use wrapper::GeckoNode; @@ -37,21 +36,4 @@ impl<'lc, 'ln> DomTraversalContext> for RecalcStyleOnly<'lc> { } fn process_postorder(&self, _: GeckoNode<'ln>) {} - - /// In Gecko we use this traversal just for restyling, so we can stop once - /// we know there aren't more dirty nodes under ourselves. - fn should_process(&self, node: GeckoNode<'ln>) -> bool { - node.is_dirty() || node.has_dirty_descendants() - } - - fn pre_process_child_hook(&self, parent: GeckoNode<'ln>, kid: GeckoNode<'ln>) { - // NOTE: At this point is completely safe to modify either the parent or - // the child, since we have exclusive access to them. - if parent.is_dirty() { - unsafe { - kid.set_dirty(true); - parent.set_dirty_descendants(true); - } - } - } }