aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/custom_properties.rs70
-rw-r--r--components/style/properties/declaration_block.rs18
-rw-r--r--components/style/properties/properties.mako.rs30
-rw-r--r--tests/unit/style/custom_properties.rs16
4 files changed, 72 insertions, 62 deletions
diff --git a/components/style/custom_properties.rs b/components/style/custom_properties.rs
index 7fd74f83c1b..ca6e820335b 100644
--- a/components/style/custom_properties.rs
+++ b/components/style/custom_properties.rs
@@ -457,9 +457,59 @@ fn parse_var_function<'i, 't>(
Ok(())
}
+/// A struct that takes care of encapsulating the cascade process for custom
+/// properties.
+pub struct CustomPropertiesBuilder<'a> {
+ seen: PrecomputedHashSet<&'a Name>,
+ custom_properties: Option<OrderedMap<&'a Name, BorrowedSpecifiedValue<'a>>>,
+ inherited: Option<&'a Arc<CustomPropertiesMap>>,
+}
+
+impl<'a> CustomPropertiesBuilder<'a> {
+ /// Create a new builder, inheriting from a given custom properties map.
+ pub fn new(inherited: Option<&'a Arc<CustomPropertiesMap>>) -> Self {
+ Self {
+ seen: PrecomputedHashSet::default(),
+ custom_properties: None,
+ inherited,
+ }
+ }
+
+ /// Cascade a given custom property declaration.
+ pub fn cascade(
+ &mut self,
+ name: &'a Name,
+ specified_value: DeclaredValue<'a, Box<SpecifiedValue>>,
+ ) {
+ cascade(
+ &mut self.custom_properties,
+ self.inherited,
+ &mut self.seen,
+ name,
+ specified_value,
+ )
+ }
+
+ /// Returns the final map of applicable custom properties.
+ ///
+ /// If there was any specified property, we've created a new map and now we need
+ /// to remove any potential cycles, and wrap it in an arc.
+ ///
+ /// Otherwise, just use the inherited custom properties map.
+ pub fn build(mut self) -> Option<Arc<CustomPropertiesMap>> {
+ let mut map = match self.custom_properties.take() {
+ Some(map) => map,
+ None => return self.inherited.cloned(),
+ };
+
+ remove_cycles(&mut map);
+ Some(Arc::new(substitute_all(map)))
+ }
+}
+
/// Add one custom property declaration to a map, unless another with the same
/// name was already there.
-pub fn cascade<'a>(
+fn cascade<'a>(
custom_properties: &mut Option<OrderedMap<&'a Name, BorrowedSpecifiedValue<'a>>>,
inherited: Option<&'a Arc<CustomPropertiesMap>>,
seen: &mut PrecomputedHashSet<&'a Name>,
@@ -509,24 +559,6 @@ pub fn cascade<'a>(
}
}
-/// Returns the final map of applicable custom properties.
-///
-/// If there was any specified property, we've created a new map and now we need
-/// to remove any potential cycles, and wrap it in an arc.
-///
-/// Otherwise, just use the inherited custom properties map.
-pub fn finish_cascade(
- specified_values_map: Option<OrderedMap<&Name, BorrowedSpecifiedValue>>,
- inherited: Option<&Arc<CustomPropertiesMap>>,
-) -> Option<Arc<CustomPropertiesMap>> {
- if let Some(mut map) = specified_values_map {
- remove_cycles(&mut map);
- Some(Arc::new(substitute_all(map)))
- } else {
- inherited.cloned()
- }
-}
-
/// https://drafts.csswg.org/css-variables/#cycles
///
/// The initial value of a custom property is represented by this property not
diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs
index b1c7d547bbb..df4840f0dda 100644
--- a/components/style/properties/declaration_block.rs
+++ b/components/style/properties/declaration_block.rs
@@ -9,6 +9,7 @@
use context::QuirksMode;
use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError};
+use custom_properties::CustomPropertiesBuilder;
use error_reporting::{ParseErrorReporter, ContextualParseError};
use parser::{ParserContext, ParserErrorContext};
use properties::animated_properties::AnimationValue;
@@ -691,24 +692,15 @@ impl PropertyDeclarationBlock {
&self,
inherited_custom_properties: Option<&Arc<::custom_properties::CustomPropertiesMap>>,
) -> Option<Arc<::custom_properties::CustomPropertiesMap>> {
- let mut custom_properties = None;
- let mut seen_custom = PrecomputedHashSet::default();
+ let mut builder = CustomPropertiesBuilder::new(inherited_custom_properties);
for declaration in self.normal_declaration_iter() {
if let PropertyDeclaration::Custom(ref name, ref value) = *declaration {
- ::custom_properties::cascade(
- &mut custom_properties,
- inherited_custom_properties,
- &mut seen_custom,
- name,
- value.borrow(),
- );
+ builder.cascade(name, value.borrow());
}
}
- ::custom_properties::finish_cascade(
- custom_properties,
- inherited_custom_properties,
- )
+
+ builder.build()
}
}
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index 031bd1e580b..d18bacbb631 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -12,6 +12,7 @@
#[cfg(feature = "servo")]
use app_units::Au;
+use custom_properties::CustomPropertiesBuilder;
use servo_arc::{Arc, UniqueArc};
use smallbitvec::SmallBitVec;
use std::borrow::Cow;
@@ -33,7 +34,6 @@ use media_queries::Device;
use parser::ParserContext;
#[cfg(feature = "gecko")] use properties::longhands::system_font::SystemFont;
use rule_cache::{RuleCache, RuleCacheConditions};
-use selector_map::PrecomputedHashSet;
use selector_parser::PseudoElement;
use selectors::parser::SelectorParseError;
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
@@ -3228,26 +3228,18 @@ where
}
};
- let inherited_custom_properties = inherited_style.custom_properties();
- let mut custom_properties = None;
- let mut seen_custom = PrecomputedHashSet::default();
- for (declaration, _cascade_level) in iter_declarations() {
- if let PropertyDeclaration::Custom(ref name, ref value) = *declaration {
- ::custom_properties::cascade(
- &mut custom_properties,
- inherited_custom_properties,
- &mut seen_custom,
- name,
- value.borrow(),
- );
+ let custom_properties = {
+ let mut builder =
+ CustomPropertiesBuilder::new(inherited_style.custom_properties());
+
+ for (declaration, _cascade_level) in iter_declarations() {
+ if let PropertyDeclaration::Custom(ref name, ref value) = *declaration {
+ builder.cascade(name, value.borrow());
+ }
}
- }
- let custom_properties =
- ::custom_properties::finish_cascade(
- custom_properties,
- inherited_custom_properties,
- );
+ builder.build()
+ };
let mut context = computed::Context {
is_root_element: flags.contains(IS_ROOT_ELEMENT),
diff --git a/tests/unit/style/custom_properties.rs b/tests/unit/style/custom_properties.rs
index 135583e9d62..7a2741633c8 100644
--- a/tests/unit/style/custom_properties.rs
+++ b/tests/unit/style/custom_properties.rs
@@ -4,7 +4,7 @@
use cssparser::{Parser, ParserInput};
use servo_arc::Arc;
-use style::custom_properties::{self, Name, SpecifiedValue, CustomPropertiesMap};
+use style::custom_properties::{Name, SpecifiedValue, CustomPropertiesMap, CustomPropertiesBuilder};
use style::properties::DeclaredValue;
use test::{self, Bencher};
@@ -18,19 +18,13 @@ fn cascade(
(Name::from(name), SpecifiedValue::parse(&mut parser).unwrap())
}).collect::<Vec<_>>();
- let mut custom_properties = None;
- let mut seen = Default::default();
+ let mut builder = CustomPropertiesBuilder::new(inherited);
+
for &(ref name, ref val) in &values {
- custom_properties::cascade(
- &mut custom_properties,
- inherited,
- &mut seen,
- name,
- DeclaredValue::Value(val)
- )
+ builder.cascade(name, DeclaredValue::Value(val));
}
- custom_properties::finish_cascade(custom_properties, inherited)
+ builder.build()
}
#[bench]