diff options
author | Cameron McCormack <cam@mcc.id.au> | 2017-10-12 10:30:03 +0800 |
---|---|---|
committer | Cameron McCormack <cam@mcc.id.au> | 2017-10-12 10:33:34 +0800 |
commit | 51c1fb681d7535a55c68f20b222e887f37d1ef1b (patch) | |
tree | e7d6f25b16901252f58bf9bc8c70f68474802989 /components/style/custom_properties.rs | |
parent | dbf0991f8cab54516c5b0211e1818a16cfbf9e19 (diff) | |
download | servo-51c1fb681d7535a55c68f20b222e887f37d1ef1b.tar.gz servo-51c1fb681d7535a55c68f20b222e887f37d1ef1b.zip |
style: Avoid cloning inherited CustomPropertiesMap when cascading properties with the same value.
Diffstat (limited to 'components/style/custom_properties.rs')
-rw-r--r-- | components/style/custom_properties.rs | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/components/style/custom_properties.rs b/components/style/custom_properties.rs index 86dd6063114..07392b768f6 100644 --- a/components/style/custom_properties.rs +++ b/components/style/custom_properties.rs @@ -507,11 +507,15 @@ impl<'a> CustomPropertiesBuilder<'a> { return; } + if !self.value_may_affect_style(name, &specified_value) { + return; + } + if self.custom_properties.is_none() { self.custom_properties = Some(match self.inherited { Some(inherited) => (**inherited).clone(), None => CustomPropertiesMap::new(), - }) + }); } let map = self.custom_properties.as_mut().unwrap(); @@ -525,10 +529,50 @@ impl<'a> CustomPropertiesBuilder<'a> { CSSWideKeyword::Initial => { map.remove(name); } - CSSWideKeyword::Unset | // Custom properties are inherited by default. - CSSWideKeyword::Inherit => {} // The inherited value is what we already have. + // handled in value_may_affect_style + CSSWideKeyword::Unset | + CSSWideKeyword::Inherit => unreachable!(), + } + } + } + + fn value_may_affect_style( + &self, + name: &Name, + value: &DeclaredValue<Arc<SpecifiedValue>> + ) -> bool { + match *value { + DeclaredValue::CSSWideKeyword(CSSWideKeyword::Unset) | + DeclaredValue::CSSWideKeyword(CSSWideKeyword::Inherit) => { + // Custom properties are inherited by default. So + // explicit 'inherit' or 'unset' means we can just use + // any existing value in the inherited CustomPropertiesMap. + return false; } + _ => {} } + + let existing_value = + self.custom_properties.as_ref().and_then(|m| m.get(name)) + .or_else(|| self.inherited.and_then(|m| m.get(name))); + + match (existing_value, value) { + (None, &DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial)) => { + // The initial value of a custom property is the same as it + // not existing in the map. + return false; + } + (Some(existing_value), &DeclaredValue::Value(specified_value)) => { + // Don't bother overwriting an existing inherited value with + // the same specified value. + if existing_value == specified_value { + return false; + } + } + _ => {} + } + + true } /// Returns the final map of applicable custom properties. |