mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
style: Introduce CustomPropertiesBuilder.
I'm about to introduce more state here to implement optimizations for custom property cascading, so this abstraction is useful to encapsulate that state.
This commit is contained in:
parent
47efcd5e52
commit
d0f080d5dd
4 changed files with 73 additions and 63 deletions
|
@ -457,9 +457,59 @@ fn parse_var_function<'i, 't>(
|
||||||
Ok(())
|
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
|
/// Add one custom property declaration to a map, unless another with the same
|
||||||
/// name was already there.
|
/// name was already there.
|
||||||
pub fn cascade<'a>(
|
fn cascade<'a>(
|
||||||
custom_properties: &mut Option<OrderedMap<&'a Name, BorrowedSpecifiedValue<'a>>>,
|
custom_properties: &mut Option<OrderedMap<&'a Name, BorrowedSpecifiedValue<'a>>>,
|
||||||
inherited: Option<&'a Arc<CustomPropertiesMap>>,
|
inherited: Option<&'a Arc<CustomPropertiesMap>>,
|
||||||
seen: &mut PrecomputedHashSet<&'a Name>,
|
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
|
/// https://drafts.csswg.org/css-variables/#cycles
|
||||||
///
|
///
|
||||||
/// The initial value of a custom property is represented by this property not
|
/// The initial value of a custom property is represented by this property not
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
|
use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
|
||||||
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError};
|
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError};
|
||||||
|
use custom_properties::CustomPropertiesBuilder;
|
||||||
use error_reporting::{ParseErrorReporter, ContextualParseError};
|
use error_reporting::{ParseErrorReporter, ContextualParseError};
|
||||||
use parser::{ParserContext, ParserErrorContext};
|
use parser::{ParserContext, ParserErrorContext};
|
||||||
use properties::animated_properties::AnimationValue;
|
use properties::animated_properties::AnimationValue;
|
||||||
|
@ -691,24 +692,15 @@ impl PropertyDeclarationBlock {
|
||||||
&self,
|
&self,
|
||||||
inherited_custom_properties: Option<&Arc<::custom_properties::CustomPropertiesMap>>,
|
inherited_custom_properties: Option<&Arc<::custom_properties::CustomPropertiesMap>>,
|
||||||
) -> Option<Arc<::custom_properties::CustomPropertiesMap>> {
|
) -> Option<Arc<::custom_properties::CustomPropertiesMap>> {
|
||||||
let mut custom_properties = None;
|
let mut builder = CustomPropertiesBuilder::new(inherited_custom_properties);
|
||||||
let mut seen_custom = PrecomputedHashSet::default();
|
|
||||||
|
|
||||||
for declaration in self.normal_declaration_iter() {
|
for declaration in self.normal_declaration_iter() {
|
||||||
if let PropertyDeclaration::Custom(ref name, ref value) = *declaration {
|
if let PropertyDeclaration::Custom(ref name, ref value) = *declaration {
|
||||||
::custom_properties::cascade(
|
builder.cascade(name, value.borrow());
|
||||||
&mut custom_properties,
|
|
||||||
inherited_custom_properties,
|
|
||||||
&mut seen_custom,
|
|
||||||
name,
|
|
||||||
value.borrow(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
::custom_properties::finish_cascade(
|
|
||||||
custom_properties,
|
builder.build()
|
||||||
inherited_custom_properties,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
use custom_properties::CustomPropertiesBuilder;
|
||||||
use servo_arc::{Arc, UniqueArc};
|
use servo_arc::{Arc, UniqueArc};
|
||||||
use smallbitvec::SmallBitVec;
|
use smallbitvec::SmallBitVec;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -33,7 +34,6 @@ use media_queries::Device;
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
#[cfg(feature = "gecko")] use properties::longhands::system_font::SystemFont;
|
#[cfg(feature = "gecko")] use properties::longhands::system_font::SystemFont;
|
||||||
use rule_cache::{RuleCache, RuleCacheConditions};
|
use rule_cache::{RuleCache, RuleCacheConditions};
|
||||||
use selector_map::PrecomputedHashSet;
|
|
||||||
use selector_parser::PseudoElement;
|
use selector_parser::PseudoElement;
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseError;
|
||||||
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
||||||
|
@ -3228,26 +3228,18 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let inherited_custom_properties = inherited_style.custom_properties();
|
let custom_properties = {
|
||||||
let mut custom_properties = None;
|
let mut builder =
|
||||||
let mut seen_custom = PrecomputedHashSet::default();
|
CustomPropertiesBuilder::new(inherited_style.custom_properties());
|
||||||
|
|
||||||
for (declaration, _cascade_level) in iter_declarations() {
|
for (declaration, _cascade_level) in iter_declarations() {
|
||||||
if let PropertyDeclaration::Custom(ref name, ref value) = *declaration {
|
if let PropertyDeclaration::Custom(ref name, ref value) = *declaration {
|
||||||
::custom_properties::cascade(
|
builder.cascade(name, value.borrow());
|
||||||
&mut custom_properties,
|
|
||||||
inherited_custom_properties,
|
|
||||||
&mut seen_custom,
|
|
||||||
name,
|
|
||||||
value.borrow(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let custom_properties =
|
builder.build()
|
||||||
::custom_properties::finish_cascade(
|
};
|
||||||
custom_properties,
|
|
||||||
inherited_custom_properties,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut context = computed::Context {
|
let mut context = computed::Context {
|
||||||
is_root_element: flags.contains(IS_ROOT_ELEMENT),
|
is_root_element: flags.contains(IS_ROOT_ELEMENT),
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use cssparser::{Parser, ParserInput};
|
use cssparser::{Parser, ParserInput};
|
||||||
use servo_arc::Arc;
|
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 style::properties::DeclaredValue;
|
||||||
use test::{self, Bencher};
|
use test::{self, Bencher};
|
||||||
|
|
||||||
|
@ -18,19 +18,13 @@ fn cascade(
|
||||||
(Name::from(name), SpecifiedValue::parse(&mut parser).unwrap())
|
(Name::from(name), SpecifiedValue::parse(&mut parser).unwrap())
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut custom_properties = None;
|
let mut builder = CustomPropertiesBuilder::new(inherited);
|
||||||
let mut seen = Default::default();
|
|
||||||
for &(ref name, ref val) in &values {
|
for &(ref name, ref val) in &values {
|
||||||
custom_properties::cascade(
|
builder.cascade(name, DeclaredValue::Value(val));
|
||||||
&mut custom_properties,
|
|
||||||
inherited,
|
|
||||||
&mut seen,
|
|
||||||
name,
|
|
||||||
DeclaredValue::Value(val)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
custom_properties::finish_cascade(custom_properties, inherited)
|
builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue