style: Avoid cloning inherited CustomPropertiesMap when cascading properties with the same value.

This commit is contained in:
Cameron McCormack 2017-10-12 10:30:03 +08:00
parent dbf0991f8c
commit 51c1fb681d

View file

@ -507,11 +507,15 @@ impl<'a> CustomPropertiesBuilder<'a> {
return; return;
} }
if !self.value_may_affect_style(name, &specified_value) {
return;
}
if self.custom_properties.is_none() { if self.custom_properties.is_none() {
self.custom_properties = Some(match self.inherited { self.custom_properties = Some(match self.inherited {
Some(inherited) => (**inherited).clone(), Some(inherited) => (**inherited).clone(),
None => CustomPropertiesMap::new(), None => CustomPropertiesMap::new(),
}) });
} }
let map = self.custom_properties.as_mut().unwrap(); let map = self.custom_properties.as_mut().unwrap();
@ -525,12 +529,52 @@ impl<'a> CustomPropertiesBuilder<'a> {
CSSWideKeyword::Initial => { CSSWideKeyword::Initial => {
map.remove(name); map.remove(name);
} }
CSSWideKeyword::Unset | // Custom properties are inherited by default. // handled in value_may_affect_style
CSSWideKeyword::Inherit => {} // The inherited value is what we already have. 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. /// Returns the final map of applicable custom properties.
/// ///
/// If there was any specified property, we've created a new map and now we need /// If there was any specified property, we've created a new map and now we need