Bug 1317016 - Basic infrastructure for RestyleHint-driven traversal.

MozReview-Commit-ID: 7wH5XcILVmX
This commit is contained in:
Bobby Holley 2016-11-01 23:11:24 -07:00
parent e1eff691f8
commit 992f7dddf4
35 changed files with 1465 additions and 901 deletions

View file

@ -112,15 +112,11 @@ impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
construct_flows_at(&self.context, self.root, node);
}
fn should_traverse_child(parent: N::ConcreteElement, child: N) -> bool {
// If the parent is display:none, we don't need to do anything.
if parent.is_display_none() {
return false;
}
fn should_traverse_child(child: N, restyled_previous_sibling_element: bool) -> bool {
match child.as_element() {
// Elements should be traversed if they need styling or flow construction.
Some(el) => el.styling_mode() != StylingMode::Stop ||
Some(el) => restyled_previous_sibling_element ||
el.styling_mode() != StylingMode::Stop ||
el.as_node().to_threadsafe().restyle_damage() != RestyleDamage::empty(),
// Text nodes never need styling. However, there are two cases they may need
@ -128,7 +124,7 @@ impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
// (1) They child doesn't yet have layout data (preorder traversal initializes it).
// (2) The parent element has restyle damage (so the text flow also needs fixup).
None => child.get_raw_data().is_none() ||
parent.as_node().to_threadsafe().restyle_damage() != RestyleDamage::empty(),
child.parent_node().unwrap().to_threadsafe().restyle_damage() != RestyleDamage::empty(),
}
}
@ -156,6 +152,8 @@ pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayo
#[inline]
#[allow(unsafe_code)]
fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: OpaqueNode, node: N) {
debug!("construct_flows_at: {:?}", node);
// Construct flows for this node.
{
let tnode = node.to_threadsafe();
@ -167,16 +165,18 @@ fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: O
let mut flow_constructor = FlowConstructor::new(context);
if nonincremental_layout || !flow_constructor.repair_if_possible(&tnode) {
flow_constructor.process(&tnode);
debug!("Constructed flow for {:x}: {:x}",
tnode.debug_id(),
debug!("Constructed flow for {:?}: {:x}",
tnode,
tnode.flow_debug_id());
}
}
tnode.clear_restyle_damage();
}
unsafe { node.clear_dirty_bits(); }
if let Some(el) = node.as_element() {
el.mutate_data().unwrap().persist();
unsafe { el.unset_dirty_descendants(); }
}
remove_from_bloom_filter(context, root, node);
}