diff --git a/components/style/matching.rs b/components/style/matching.rs index d71bf828ac7..103cf24da25 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -13,6 +13,7 @@ use data::ElementData; use dom::TElement; use invalidation::element::restyle_hints::RestyleHint; use properties::ComputedValues; +use properties::longhands::display::computed_value as display; use rule_tree::{CascadeLevel, StrongRuleNode}; use selector_parser::{PseudoElement, RestyleDamage}; use selectors::matching::ElementSelectorFlags; @@ -142,8 +143,6 @@ trait PrivateMatchMethods: TElement { old_values: Option<&Arc>, new_values: &ComputedValues, ) -> bool { - use properties::longhands::display::computed_value as display; - let new_box_style = new_values.get_box(); let has_new_animation_style = new_box_style.specifies_animations(); let has_animations = self.has_css_animations(); @@ -182,7 +181,6 @@ trait PrivateMatchMethods: TElement { restyle_hints: RestyleHint ) { use context::PostAnimationTasks; - use properties::longhands::display::computed_value as display; if !restyle_hints.intersects(RestyleHint::RESTYLE_SMIL) { return; @@ -365,6 +363,16 @@ trait PrivateMatchMethods: TElement { let old_display = old_values.get_box().clone_display(); let new_display = new_values.get_box().clone_display(); + // If we used to be a display: none element, and no longer are, + // our children need to be restyled because they're unstyled. + // + // NOTE(emilio): Gecko has the special-case of -moz-binding, but + // that gets handled on the frame constructor when processing + // the reframe, so no need to handle that here. + if old_display == display::T::none && old_display != new_display { + return ChildCascadeRequirement::MustCascadeChildren + } + // Blockification of children may depend on our display value, // so we need to actually do the recascade. We could potentially // do better, but it doesn't seem worth it. diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 8b0943a58c8..88c02f51b3e 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -508,23 +508,20 @@ where // Before examining each child individually, try to prove that our children // don't need style processing. They need processing if any of the following // conditions hold: - // * We have the dirty descendants bit. - // * We're propagating a hint. - // * This is the initial style. - // * We generated a reconstruct hint on self (which could mean that we - // switched from display:none to something else, which means the children - // need initial styling). - // * This is a servo non-incremental traversal. + // + // * We have the dirty descendants bit. + // * We're propagating a restyle hint. + // * We can't skip the cascade. + // * This is a servo non-incremental traversal. // // Additionally, there are a few scenarios where we avoid traversing the // subtree even if descendant styles are out of date. These cases are // enumerated in should_cull_subtree(). - let mut traverse_children = has_dirty_descendants_for_this_restyle || - !propagated_hint.is_empty() || - !child_cascade_requirement.can_skip_cascade() || - context.thread_local.is_initial_style() || - data.reconstructed_self() || - is_servo_nonincremental_layout(); + let mut traverse_children = + has_dirty_descendants_for_this_restyle || + !propagated_hint.is_empty() || + !child_cascade_requirement.can_skip_cascade() || + is_servo_nonincremental_layout(); traverse_children = traverse_children &&