mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
style: Get rid of unstyled children only traversals.
They're useless now, provided we remove the hack to not traverse XBL-bound elements on initial styling. Bug: 1418456 Reviewed-by: heycam MozReview-Commit-ID: AvBVdyF1wb6
This commit is contained in:
parent
63bd783c55
commit
b1fecea0aa
4 changed files with 18 additions and 80 deletions
|
@ -557,11 +557,6 @@ pub trait TElement
|
|||
!data.hint.has_animation_hint_or_recascade();
|
||||
}
|
||||
|
||||
if traversal_flags.contains(TraversalFlags::UnstyledOnly) {
|
||||
// We don't process invalidations in UnstyledOnly mode.
|
||||
return data.has_styles();
|
||||
}
|
||||
|
||||
if self.has_snapshot() && !self.handled_snapshot() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -146,13 +146,6 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
) -> PreTraverseToken<E> {
|
||||
let traversal_flags = shared_context.traversal_flags;
|
||||
|
||||
// If this is an unstyled-only traversal, the caller has already verified
|
||||
// that there's something to traverse, and we don't need to do any
|
||||
// invalidation since we're not doing any restyling.
|
||||
if traversal_flags.contains(TraversalFlags::UnstyledOnly) {
|
||||
return PreTraverseToken(Some(root))
|
||||
}
|
||||
|
||||
let mut data = root.mutate_data();
|
||||
let mut data = data.as_mut().map(|d| &mut **d);
|
||||
|
||||
|
@ -208,11 +201,6 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
debug!("element_needs_traversal({:?}, {:?}, {:?})",
|
||||
el, traversal_flags, data);
|
||||
|
||||
if traversal_flags.contains(TraversalFlags::UnstyledOnly) {
|
||||
return data.map_or(true, |d| !d.has_styles()) || el.has_dirty_descendants();
|
||||
}
|
||||
|
||||
|
||||
// In case of animation-only traversal we need to traverse the element
|
||||
// if the element has animation only dirty descendants bit,
|
||||
// animation-only restyle hint or recascade.
|
||||
|
@ -266,7 +254,6 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
&self,
|
||||
context: &mut StyleContext<E>,
|
||||
parent: E,
|
||||
is_initial_style: bool,
|
||||
parent_data: &ElementData,
|
||||
) -> bool {
|
||||
debug_assert!(cfg!(feature = "gecko") ||
|
||||
|
@ -278,33 +265,6 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Gecko-only XBL handling.
|
||||
//
|
||||
// If we're computing initial styles and the parent has a Gecko XBL
|
||||
// binding, that binding may inject anonymous children and remap the
|
||||
// explicit children to an insertion point (or hide them entirely). It
|
||||
// may also specify a scoped stylesheet, which changes the rules that
|
||||
// apply within the subtree. These two effects can invalidate the result
|
||||
// of property inheritance and selector matching (respectively) within
|
||||
// the subtree.
|
||||
//
|
||||
// To avoid wasting work, we defer initial styling of XBL subtrees until
|
||||
// frame construction, which does an explicit traversal of the unstyled
|
||||
// children after shuffling the subtree. That explicit traversal may in
|
||||
// turn find other bound elements, which get handled in the same way.
|
||||
//
|
||||
// We explicitly avoid handling restyles here (explicitly removing or
|
||||
// changing bindings), since that adds complexity and is rarer. If it
|
||||
// happens, we may just end up doing wasted work, since Gecko
|
||||
// recursively drops Servo ElementData when the XBL insertion parent of
|
||||
// an Element is changed.
|
||||
if cfg!(feature = "gecko") && is_initial_style &&
|
||||
parent_data.styles.primary().has_moz_binding()
|
||||
{
|
||||
debug!("Parent {:?} has XBL binding, deferring traversal", parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -424,7 +384,7 @@ where
|
|||
let is_initial_style = !data.has_styles();
|
||||
|
||||
context.thread_local.statistics.elements_traversed += 1;
|
||||
debug_assert!(flags.intersects(TraversalFlags::AnimationOnly | TraversalFlags::UnstyledOnly) ||
|
||||
debug_assert!(flags.intersects(TraversalFlags::AnimationOnly) ||
|
||||
!element.has_snapshot() || element.handled_snapshot(),
|
||||
"Should've handled snapshots here already");
|
||||
|
||||
|
@ -471,15 +431,11 @@ where
|
|||
// those operations and compute the propagated restyle hint (unless we're
|
||||
// not processing invalidations, in which case don't need to propagate it
|
||||
// and must avoid clearing it).
|
||||
let propagated_hint = if flags.contains(TraversalFlags::UnstyledOnly) {
|
||||
RestyleHint::empty()
|
||||
} else {
|
||||
debug_assert!(flags.for_animation_only() ||
|
||||
!data.hint.has_animation_hint(),
|
||||
"animation restyle hint should be handled during \
|
||||
animation-only restyles");
|
||||
data.hint.propagate(&flags)
|
||||
};
|
||||
let propagated_hint = data.hint.propagate(&flags);
|
||||
|
||||
trace!("propagated_hint={:?}, cascade_requirement={:?}, \
|
||||
is_display_none={:?}, implementing_pseudo={:?}",
|
||||
|
@ -518,7 +474,7 @@ where
|
|||
|
||||
traverse_children =
|
||||
traverse_children &&
|
||||
!traversal.should_cull_subtree(context, element, is_initial_style, &data);
|
||||
!traversal.should_cull_subtree(context, element, &data);
|
||||
|
||||
// Examine our children, and enqueue the appropriate ones for traversal.
|
||||
if traverse_children {
|
||||
|
@ -800,12 +756,6 @@ where
|
|||
propagated_hint,
|
||||
child.implemented_pseudo_element());
|
||||
|
||||
// Make sure to not run style invalidation of styled elements in an
|
||||
// unstyled-children-only traversal.
|
||||
if child_data.is_some() && flags.intersects(TraversalFlags::UnstyledOnly) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(ref mut child_data) = child_data {
|
||||
let mut child_hint = propagated_hint;
|
||||
match cascade_requirement {
|
||||
|
|
|
@ -16,9 +16,6 @@ bitflags! {
|
|||
/// Traverse and update all elements with CSS animations since
|
||||
/// @keyframes rules may have changed. Triggered by CSS rule changes.
|
||||
const ForCSSRuleChanges = 1 << 1;
|
||||
/// Styles unstyled elements, but does not handle invalidations on
|
||||
/// already-styled elements.
|
||||
const UnstyledOnly = 1 << 2;
|
||||
/// A forgetful traversal ignores the previous state of the frame tree, and
|
||||
/// thus does not compute damage or maintain other state describing the styles
|
||||
/// pre-traversal. A forgetful traversal is usually the right thing if you
|
||||
|
@ -61,7 +58,6 @@ pub fn assert_traversal_flags_match() {
|
|||
check_traversal_flags! {
|
||||
ServoTraversalFlags_AnimationOnly => TraversalFlags::AnimationOnly,
|
||||
ServoTraversalFlags_ForCSSRuleChanges => TraversalFlags::ForCSSRuleChanges,
|
||||
ServoTraversalFlags_UnstyledOnly => TraversalFlags::UnstyledOnly,
|
||||
ServoTraversalFlags_Forgetful => TraversalFlags::Forgetful,
|
||||
ServoTraversalFlags_ClearDirtyBits => TraversalFlags::ClearDirtyBits,
|
||||
ServoTraversalFlags_ClearAnimationOnlyDirtyDescendants =>
|
||||
|
|
|
@ -294,9 +294,7 @@ pub extern "C" fn Servo_TraverseSubtree(
|
|||
|
||||
debug!("Servo_TraverseSubtree (flags={:?})", traversal_flags);
|
||||
debug!("{:?}", ShowSubtreeData(element.as_node()));
|
||||
// It makes no sense to do an animation restyle when we're styling
|
||||
// newly-inserted content.
|
||||
if !traversal_flags.contains(TraversalFlags::UnstyledOnly) {
|
||||
|
||||
let needs_animation_only_restyle =
|
||||
element.has_animation_only_dirty_descendants() ||
|
||||
element.has_animation_restyle_hints();
|
||||
|
@ -309,7 +307,6 @@ pub extern "C" fn Servo_TraverseSubtree(
|
|||
traversal_flags | TraversalFlags::AnimationOnly,
|
||||
unsafe { &*snapshots });
|
||||
}
|
||||
}
|
||||
|
||||
traverse_subtree(element,
|
||||
raw_data,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue