diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 8db09e6fe81..eb1706e691e 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -140,7 +140,7 @@ class Longhand(object): need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False, allowed_in_keyframe_block=True, complex_color=False, cast_type='u8', has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False, - flags=None, allowed_in_page_rule=False, allow_quirks=False): + flags=None, allowed_in_page_rule=False, allow_quirks=False, vector=False): self.name = name if not spec: raise TypeError("Spec should be specified for %s" % name) @@ -167,6 +167,7 @@ class Longhand(object): self.flags = flags.split() if flags else [] self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule) self.allow_quirks = allow_quirks + self.is_vector = vector # https://drafts.csswg.org/css-animations/#keyframes # > The inside of accepts any CSS property diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index b69057f916c..65478210d4e 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -74,7 +74,7 @@ <%def name="vector_longhand(name, gecko_only=False, allow_empty=False, delegate_animate=False, space_separated_allowed=False, **kwargs)"> - <%call expr="longhand(name, **kwargs)"> + <%call expr="longhand(name, vector=True, **kwargs)"> % if not gecko_only: use smallvec::SmallVec; use std::fmt; @@ -103,6 +103,8 @@ pub use super::single_value::computed_value as single_value; pub use self::single_value::T as SingleComputedValue; use smallvec::SmallVec; + use values::computed::ComputedVecIter; + /// The computed value, effectively a list of single values. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -129,6 +131,8 @@ } } % endif + + pub type Iter<'a, 'cx, 'cx_a> = ComputedVecIter<'a, 'cx, 'cx_a, super::single_value::SpecifiedValue>; } impl ToCss for computed_value::T { @@ -212,12 +216,18 @@ pub use self::single_value::SpecifiedValue as SingleSpecifiedValue; + impl SpecifiedValue { + pub fn compute_iter<'a, 'cx, 'cx_a>(&'a self, context: &'cx Context<'cx_a>) -> computed_value::Iter<'a, 'cx, 'cx_a> { + computed_value::Iter::new(context, &self.0) + } + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; #[inline] fn to_computed_value(&self, context: &Context) -> computed_value::T { - computed_value::T(self.0.iter().map(|x| x.to_computed_value(context)).collect()) + computed_value::T(self.compute_iter(context).collect()) } #[inline] fn from_computed_value(computed: &computed_value::T) -> Self { diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 19cc22edf27..12775a78218 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -100,6 +100,35 @@ impl<'a> Context<'a> { pub fn mutate_style(&mut self) -> &mut StyleBuilder<'a> { &mut self.style } } +/// An iterator over a slice of computed values +pub struct ComputedVecIter<'a, 'cx, 'cx_a: 'cx, S: ToComputedValue + 'a> { + cx: &'cx Context<'cx_a>, + values: &'a [S], +} + +impl<'a, 'cx, 'cx_a: 'cx, S: ToComputedValue + 'a> ComputedVecIter<'a, 'cx, 'cx_a, S> { + /// Construct an iterator from a slice of specified values and a context + pub fn new(cx: &'cx Context<'cx_a>, values: &'a [S]) -> Self { + ComputedVecIter { + cx: cx, + values: values, + } + } +} + +impl<'a, 'cx, 'cx_a: 'cx, S: ToComputedValue + 'a> Iterator for ComputedVecIter<'a, 'cx, 'cx_a, S> { + type Item = S::ComputedValue; + fn next(&mut self) -> Option { + if let Some((next, rest)) = self.values.split_first() { + let ret = next.to_computed_value(self.cx); + self.values = rest; + Some(ret) + } else { + None + } + } +} + /// A trait to represent the conversion between computed and specified values. pub trait ToComputedValue { /// The computed value type we're going to be converted to.