Auto merge of #17782 - emilio:needs-traversal, r=heycam

style: Unify needs_traversal logic.

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17782)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-07-19 04:57:23 -07:00 committed by GitHub
commit 9b060cf4bf

View file

@ -227,27 +227,24 @@ pub trait DomTraversal<E: TElement> : Sync {
} }
let flags = shared_context.traversal_flags; let flags = shared_context.traversal_flags;
let data = root.mutate_data(); let mut data = root.mutate_data();
let should_traverse = if data.as_ref().map_or(true, |d| !d.has_styles()) { let mut data = data.as_mut().map(|d| &mut **d);
!flags.for_animation_only()
} else {
let mut data = data.unwrap();
// Look at whether there has been any attribute or state change, and
// invalidate our style, and the one of our siblings and descendants as
// needed.
if !flags.for_animation_only() {
data.invalidate_style_if_needed(root, shared_context);
}
let parent = root.traversal_parent(); if let Some(ref mut data) = data {
let parent_data = match parent { // Invalidate our style, and the one of our siblings and descendants
None => None, // as needed.
Some(ref x) => Some(x.borrow_data().unwrap()) data.invalidate_style_if_needed(root, shared_context);
};
let parent_data_borrow = parent_data.as_ref().map(|x| &**x);
Self::element_needs_traversal(root, flags, &*data, parent_data_borrow)
}; };
let parent = root.traversal_parent();
let parent_data = parent.as_ref().and_then(|p| p.borrow_data());
let should_traverse = Self::element_needs_traversal(
root,
flags,
data.map(|d| &*d),
parent_data.as_ref().map(|d| &**d)
);
PreTraverseToken { PreTraverseToken {
traverse: should_traverse, traverse: should_traverse,
unstyled_children_only: false, unstyled_children_only: false,
@ -269,10 +266,15 @@ pub trait DomTraversal<E: TElement> : Sync {
fn element_needs_traversal( fn element_needs_traversal(
el: E, el: E,
traversal_flags: TraversalFlags, traversal_flags: TraversalFlags,
data: &ElementData, data: Option<&ElementData>,
parent_data: Option<&ElementData>, parent_data: Option<&ElementData>,
) -> bool { ) -> bool {
debug_assert!(data.has_styles(), "Caller should check this"); debug!("element_needs_traversal({:?}, {:?}, {:?}, {:?})",
el, traversal_flags, data, parent_data);
let data = match data {
Some(d) if d.has_styles() => d,
_ => return !traversal_flags.for_animation_only(),
};
// Non-incremental layout visits every node. // Non-incremental layout visits every node.
if is_servo_nonincremental_layout() { if is_servo_nonincremental_layout() {
@ -773,6 +775,7 @@ where
{ {
trace!("note_children: {:?}", element); trace!("note_children: {:?}", element);
let flags = context.shared.traversal_flags; let flags = context.shared.traversal_flags;
let is_initial_style = context.thread_local.is_initial_style();
// Loop over all the traversal children. // Loop over all the traversal children.
for child_node in element.as_node().traversal_children() { for child_node in element.as_node().traversal_children() {
@ -787,37 +790,31 @@ where
}, },
}; };
let child_data = child.mutate_data(); let mut child_data = child.mutate_data();
if child_data.as_ref().map_or(true, |d| !d.has_styles()) { let mut child_data = child_data.as_mut().map(|d| &mut **d);
if !flags.for_animation_only() {
note_child(child_node);
}
continue;
}
let mut child_data = child_data.unwrap();
trace!(" > {:?} -> {:?} + {:?}, pseudo: {:?}", trace!(" > {:?} -> {:?} + {:?}, pseudo: {:?}",
child, child,
child_data.restyle.hint, child_data.as_ref().map(|d| d.restyle.hint),
propagated_hint, propagated_hint,
child.implemented_pseudo_element()); child.implemented_pseudo_element());
// Propagate the parent restyle hint, that may make us restyle the whole if let Some(ref mut child_data) = child_data {
// subtree. // Propagate the parent restyle hint, that may make us restyle the whole
if reconstructed_ancestor { // subtree.
child_data.restyle.set_reconstructed_ancestor(); if reconstructed_ancestor {
} child_data.restyle.set_reconstructed_ancestor();
child_data.restyle.hint.insert(propagated_hint); }
// Handle element snapshots and invalidation of descendants and siblings child_data.restyle.hint.insert(propagated_hint);
// as needed.
// // Handle element snapshots and invalidation of descendants and siblings
// NB: This will be a no-op if there's no snapshot. // as needed.
if !flags.for_animation_only() { //
// NB: This will be a no-op if there's no snapshot.
child_data.invalidate_style_if_needed(child, &context.shared); child_data.invalidate_style_if_needed(child, &context.shared);
} }
if D::element_needs_traversal(child, flags, &*child_data, Some(data)) { if D::element_needs_traversal(child, flags, child_data.map(|d| &*d), Some(data)) {
note_child(child_node); note_child(child_node);
// Set the dirty descendants bit on the parent as needed, so that we // Set the dirty descendants bit on the parent as needed, so that we
@ -826,8 +823,8 @@ where
// If we are in a restyle for reconstruction, there is no need to // If we are in a restyle for reconstruction, there is no need to
// perform a post-traversal, so we don't need to set the dirty // perform a post-traversal, so we don't need to set the dirty
// descendants bit on the parent. // descendants bit on the parent.
if !context.shared.traversal_flags.for_reconstruct() { if !flags.for_reconstruct() && !is_initial_style {
if context.shared.traversal_flags.for_animation_only() { if flags.for_animation_only() {
unsafe { element.set_animation_only_dirty_descendants(); } unsafe { element.set_animation_only_dirty_descendants(); }
} else { } else {
unsafe { element.set_dirty_descendants(); } unsafe { element.set_dirty_descendants(); }