diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-07-25 00:51:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-25 00:51:27 -0700 |
commit | 3eeb0e5e48fcb045100ed26b396ad85226be9af0 (patch) | |
tree | 5e8943aee81acfc36cd87bed32f19bee27bfc7d2 | |
parent | bf16b146e8edbf3e3513188fe495354546160988 (diff) | |
parent | e36b4340e1220e666e325dfa982ec74ce9c75602 (diff) | |
download | servo-3eeb0e5e48fcb045100ed26b396ad85226be9af0.tar.gz servo-3eeb0e5e48fcb045100ed26b396ad85226be9af0.zip |
Auto merge of #17849 - heycam:binding-display-none, r=emilio
style: Ensure we generate a ReconstructFrame hint when -moz-binding changes on a display:none root.
From https://bugzilla.mozilla.org/show_bug.cgi?id=1375383.
-rw-r--r-- | components/style/gecko/restyle_damage.rs | 30 | ||||
-rw-r--r-- | components/style/matching.rs | 7 | ||||
-rw-r--r-- | components/style/servo/restyle_damage.rs | 11 |
3 files changed, 45 insertions, 3 deletions
diff --git a/components/style/gecko/restyle_damage.rs b/components/style/gecko/restyle_damage.rs index 7d0c29c232f..b0f60663067 100644 --- a/components/style/gecko/restyle_damage.rs +++ b/components/style/gecko/restyle_damage.rs @@ -6,7 +6,7 @@ use gecko_bindings::bindings; use gecko_bindings::structs; -use gecko_bindings::structs::{nsChangeHint, nsStyleContext}; +use gecko_bindings::structs::{nsChangeHint, nsStyleContext, nsStyleStructID}; use matching::{StyleChange, StyleDifference}; use properties::ComputedValues; use servo_arc::Arc; @@ -62,6 +62,34 @@ impl GeckoRestyleDamage { StyleDifference::new(GeckoRestyleDamage(hint), change) } + /// Computes the `StyleDifference` between the two `ComputedValues` objects + /// for the case where the old and new style are both `display: none`. + /// + /// In general we don't need to generate damage for such elements, but we + /// do need to generate a frame reconstruction for `-moz-binding` changes, + /// so that we can start loading the new binding. + pub fn compute_undisplayed_style_difference( + old_style: &ComputedValues, + new_style: &ComputedValues, + ) -> StyleDifference { + let mut any_style_changed: bool = false; + + // Just compute the Display struct's difference. + let display_struct_bit = 1 << (nsStyleStructID::eStyleStruct_Display as u32); + let hint = unsafe { + bindings::Gecko_CalcStyleDifference(old_style, + new_style, + display_struct_bit, + &mut any_style_changed) + }; + + // Only pay attention to a reconstruct change hint. + let damage = GeckoRestyleDamage(hint) & Self::reconstruct(); + + let change = if damage.is_empty() { StyleChange::Changed } else { StyleChange::Unchanged }; + StyleDifference::new(damage, change) + } + /// Returns true if this restyle damage contains all the damage of |other|. pub fn contains(self, other: Self) -> bool { self & other == other diff --git a/components/style/matching.rs b/components/style/matching.rs index 01c1fb53d1b..24e16cff235 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -783,8 +783,11 @@ pub trait MatchMethods : TElement { // This happens with display:none elements, and not-yet-existing // pseudo-elements. if new_style_is_display_none && old_style_is_display_none { - // The style remains display:none. No need for damage. - return StyleDifference::new(RestyleDamage::empty(), StyleChange::Unchanged) + // The style remains display:none. The only case we need to care + // about is if -moz-binding changed, and to generate a reconstruct + // so that we can start the binding load. Otherwise, there is no + // need for damage. + return RestyleDamage::compute_undisplayed_style_difference(old_values, new_values); } if pseudo.map_or(false, |p| p.is_before_or_after()) { diff --git a/components/style/servo/restyle_damage.rs b/components/style/servo/restyle_damage.rs index f85e8b6b13c..0be480a2424 100644 --- a/components/style/servo/restyle_damage.rs +++ b/components/style/servo/restyle_damage.rs @@ -69,6 +69,17 @@ impl ServoRestyleDamage { StyleDifference::new(damage, change) } + /// Computes the `StyleDifference` between the two `ComputedValues` objects + /// for the case where the old and new style are both `display: none`. + /// + /// For Servo we never need to generate any damage for such elements. + pub fn compute_undisplayed_style_difference( + _old_style: &ComputedValues, + _new_style: &ComputedValues, + ) -> StyleDifference { + StyleDifference::new(Self::empty(), StyleChange::Unchanged) + } + /// Returns a bitmask that represents a flow that needs to be rebuilt and /// reflowed. /// |