diff --git a/components/style/gecko/restyle_damage.rs b/components/style/gecko/restyle_damage.rs index a97098363cb..4749daea183 100644 --- a/components/style/gecko/restyle_damage.rs +++ b/components/style/gecko/restyle_damage.rs @@ -57,7 +57,7 @@ impl GeckoRestyleDamage { &mut reset_only, ) }; - if reset_only && old_style.custom_properties() != new_style.custom_properties() { + if reset_only && !old_style.custom_properties_equal(new_style) { // The Gecko_CalcStyleDifference call only checks the non-custom // property structs, so we check the custom properties here. Since // they generate no damage themselves, we can skip this check if we diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index e0e0fe4cb03..9f204a3c36d 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2975,6 +2975,27 @@ impl ComputedValues { self.custom_properties.as_ref() } + /// Returns whether we have the same custom properties as another style. + /// + /// This should effectively be just: + /// + /// self.custom_properties() == other.custom_properties() + /// + /// But that's not really the case because IndexMap equality doesn't + /// consider ordering, which we have to account for. Also, for the same + /// reason, IndexMap equality comparisons are slower than needed. + /// + /// See https://github.com/bluss/indexmap/issues/153 + pub fn custom_properties_equal(&self, other: &Self) -> bool { + match (self.custom_properties(), other.custom_properties()) { + (Some(l), Some(r)) => { + l.len() == r.len() && l.iter().zip(r.iter()).all(|((k1, v1), (k2, v2))| k1 == k2 && v1 == v2) + }, + (None, None) => true, + _ => false, + } + } + % for prop in data.longhands: /// Gets the computed value of a given property. #[inline(always)] diff --git a/components/style/servo/restyle_damage.rs b/components/style/servo/restyle_damage.rs index cee0e486f3f..fe17fa6198b 100644 --- a/components/style/servo/restyle_damage.rs +++ b/components/style/servo/restyle_damage.rs @@ -254,7 +254,7 @@ fn compute_damage(old: &ComputedValues, new: &ComputedValues) -> ServoRestyleDam // Paint worklets may depend on custom properties, // so if they have changed we should repaint. - if old.custom_properties() != new.custom_properties() { + if !old.custom_properties_equal(new) { damage.insert(ServoRestyleDamage::REPAINT); }