diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 7686d1be53a..26e56a89c52 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -723,21 +723,16 @@ impl Animatable for AnimationValue { } } - fn get_zero_value(&self) -> Option { - match self { + fn get_zero_value(&self) -> Result { + match *self { % for prop in data.longhands: - % if prop.animatable: - % if prop.animation_value_type == "discrete": - &AnimationValue::${prop.camel_case}(_) => { - None - } - % else: - &AnimationValue::${prop.camel_case}(ref base) => { - base.get_zero_value().map(AnimationValue::${prop.camel_case}) - } - % endif - % endif + % if prop.animatable and prop.animation_value_type != "discrete": + AnimationValue::${prop.camel_case}(ref base) => { + Ok(AnimationValue::${prop.camel_case}(base.get_zero_value()?)) + }, + % endif % endfor + _ => Err(()), } } @@ -804,9 +799,8 @@ pub trait Animatable: Sized { /// This is not the necessarily the same as the initial value of a property. For example, the /// initial value of 'stroke-width' is 1, but the zero value is 0, since adding 1 to the /// underlying value will not produce the underlying value. - fn get_zero_value(&self) -> Option { - None - } + #[inline] + fn get_zero_value(&self) -> Result { Err(()) } /// Compute distance between a value and another for a given property. fn compute_distance(&self, _other: &Self) -> Result { Err(()) } @@ -864,7 +858,7 @@ impl Animatable for Au { } #[inline] - fn get_zero_value(&self) -> Option { Some(Au(0)) } + fn get_zero_value(&self) -> Result { Ok(Au(0)) } #[inline] fn compute_distance(&self, other: &Self) -> Result { @@ -917,7 +911,7 @@ impl Animatable for f32 { } #[inline] - fn get_zero_value(&self) -> Option { Some(0.) } + fn get_zero_value(&self) -> Result { Ok(0.) } #[inline] fn compute_distance(&self, other: &Self) -> Result { @@ -933,7 +927,7 @@ impl Animatable for f64 { } #[inline] - fn get_zero_value(&self) -> Option { Some(0.) } + fn get_zero_value(&self) -> Result { Ok(0.) } #[inline] fn compute_distance(&self, other: &Self) -> Result { @@ -949,7 +943,7 @@ impl Animatable for i32 { } #[inline] - fn get_zero_value(&self) -> Option { Some(0) } + fn get_zero_value(&self) -> Result { Ok(0) } #[inline] fn compute_distance(&self, other: &Self) -> Result { @@ -986,7 +980,7 @@ impl Animatable for Percentage { } #[inline] - fn get_zero_value(&self) -> Option { Some(Percentage(0.)) } + fn get_zero_value(&self) -> Result { Ok(Percentage(0.)) } #[inline] fn compute_distance(&self, other: &Self) -> Result { @@ -1172,7 +1166,9 @@ impl Animatable for LengthOrPercentage { } #[inline] - fn get_zero_value(&self) -> Option { Some(LengthOrPercentage::zero()) } + fn get_zero_value(&self) -> Result { + Ok(LengthOrPercentage::zero()) + } #[inline] fn compute_distance(&self, other: &Self) -> Result { @@ -1247,14 +1243,14 @@ impl Animatable for LengthOrPercentageOrAuto { } #[inline] - fn get_zero_value(&self) -> Option { + fn get_zero_value(&self) -> Result { match *self { LengthOrPercentageOrAuto::Length(_) | LengthOrPercentageOrAuto::Percentage(_) | LengthOrPercentageOrAuto::Calc(_) => { - Some(LengthOrPercentageOrAuto::Length(Au(0))) + Ok(LengthOrPercentageOrAuto::Length(Au(0))) }, - LengthOrPercentageOrAuto::Auto => { None }, + LengthOrPercentageOrAuto::Auto => Err(()), } } @@ -1336,14 +1332,14 @@ impl Animatable for LengthOrPercentageOrNone { } #[inline] - fn get_zero_value(&self) -> Option { + fn get_zero_value(&self) -> Result { match *self { LengthOrPercentageOrNone::Length(_) | LengthOrPercentageOrNone::Percentage(_) | LengthOrPercentageOrNone::Calc(_) => { - Some(LengthOrPercentageOrNone::Length(Au(0))) + Ok(LengthOrPercentageOrNone::Length(Au(0))) }, - LengthOrPercentageOrNone::None => { None }, + LengthOrPercentageOrNone::None => Err(()), } } @@ -1450,7 +1446,7 @@ impl Animatable for FontWeight { } #[inline] - fn get_zero_value(&self) -> Option { Some(FontWeight::Weight400) } + fn get_zero_value(&self) -> Result { Ok(FontWeight::Weight400) } #[inline] fn compute_distance(&self, other: &Self) -> Result { @@ -1513,11 +1509,6 @@ impl Into for f64 { } } -// Like std::macros::try!, but for Option<>. -macro_rules! option_try { - ($e:expr) => (match $e { Some(e) => e, None => return None }) -} - /// https://drafts.csswg.org/css-transitions/#animtype-simple-list impl Animatable for generic_position::Position { #[inline] @@ -1529,10 +1520,10 @@ impl Animatable for generic_position::Position Option { - Some(generic_position::Position { - horizontal: option_try!(self.horizontal.get_zero_value()), - vertical: option_try!(self.vertical.get_zero_value()), + fn get_zero_value(&self) -> Result { + Ok(generic_position::Position { + horizontal: self.horizontal.get_zero_value()?, + vertical: self.vertical.get_zero_value()?, }) } @@ -2656,7 +2647,7 @@ impl Animatable for TransformList { } #[inline] - fn get_zero_value(&self) -> Option { Some(TransformList(None)) } + fn get_zero_value(&self) -> Result { Ok(TransformList(None)) } } impl Animatable for Either @@ -2679,10 +2670,14 @@ impl Animatable for Either } #[inline] - fn get_zero_value(&self) -> Option { + fn get_zero_value(&self) -> Result { match *self { - Either::First(ref this) => { this.get_zero_value().map(Either::First) }, - Either::Second(ref this) => { this.get_zero_value().map(Either::Second) }, + Either::First(ref this) => { + Ok(Either::First(this.get_zero_value()?)) + }, + Either::Second(ref this) => { + Ok(Either::Second(this.get_zero_value()?)) + }, } } @@ -2792,8 +2787,8 @@ impl Animatable for IntermediateRGBA { } #[inline] - fn get_zero_value(&self) -> Option { - Some(IntermediateRGBA::transparent()) + fn get_zero_value(&self) -> Result { + Ok(IntermediateRGBA::transparent()) } #[inline] @@ -2985,10 +2980,10 @@ impl Animatable for IntermediateSVGPaint { } #[inline] - fn get_zero_value(&self) -> Option { - Some(IntermediateSVGPaint { - kind: option_try!(self.kind.get_zero_value()), - fallback: self.fallback.and_then(|v| v.get_zero_value()), + fn get_zero_value(&self) -> Result { + Ok(IntermediateSVGPaint { + kind: self.kind.get_zero_value()?, + fallback: self.fallback.and_then(|v| v.get_zero_value().ok()), }) } } @@ -3023,14 +3018,15 @@ impl Animatable for IntermediateSVGPaintKind { } #[inline] - fn get_zero_value(&self) -> Option { - match self { - &SVGPaintKind::Color(ref color) => color.get_zero_value() - .map(SVGPaintKind::Color), - &SVGPaintKind::None | - &SVGPaintKind::ContextFill | - &SVGPaintKind::ContextStroke => Some(self.clone()), - _ => None, + fn get_zero_value(&self) -> Result { + match *self { + SVGPaintKind::Color(ref color) => { + Ok(SVGPaintKind::Color(color.get_zero_value()?)) + }, + SVGPaintKind::None | + SVGPaintKind::ContextFill | + SVGPaintKind::ContextStroke => Ok(self.clone()), + _ => Err(()), } } } diff --git a/components/style/values/animated/effects.rs b/components/style/values/animated/effects.rs index fb8fb96d3ef..0d5204275a3 100644 --- a/components/style/values/animated/effects.rs +++ b/components/style/values/animated/effects.rs @@ -4,7 +4,6 @@ //! Animated types for CSS values related to effects. -use app_units::Au; use properties::animated_properties::{Animatable, IntermediateColor}; use properties::longhands::box_shadow::computed_value::T as ComputedBoxShadowList; use properties::longhands::filter::computed_value::T as ComputedFilterList; @@ -19,10 +18,18 @@ use values::generics::effects::BoxShadow as GenericBoxShadow; use values::generics::effects::Filter as GenericFilter; use values::generics::effects::SimpleShadow as GenericSimpleShadow; +/// An animated value for the `box-shadow` property. +pub type BoxShadowList = ShadowList; + +/// An animated value for the `text-shadow` property. +pub type TextShadowList = ShadowList; + +/// An animated value for shadow lists. +/// +/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, Debug, PartialEq)] -/// An animated value for the `box-shadow` property. -pub struct BoxShadowList(pub Vec); +pub struct ShadowList(Vec); /// An animated value for a single `box-shadow`. pub type BoxShadow = GenericBoxShadow; @@ -40,11 +47,6 @@ pub type Filter = GenericFilter; #[cfg(not(feature = "gecko"))] pub type Filter = GenericFilter; -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Debug, PartialEq)] -/// An animated value for the `box-shadow` property. -pub struct TextShadowList(pub Vec); - /// An animated value for the `drop-shadow()` filter. pub type SimpleShadow = GenericSimpleShadow; @@ -53,7 +55,7 @@ impl ToAnimatedValue for ComputedBoxShadowList { #[inline] fn to_animated_value(self) -> Self::AnimatedValue { - BoxShadowList(self.0.to_animated_value()) + ShadowList(self.0.to_animated_value()) } #[inline] @@ -62,8 +64,10 @@ impl ToAnimatedValue for ComputedBoxShadowList { } } -/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list -impl Animatable for BoxShadowList { +impl Animatable for ShadowList +where + S: Animatable + Clone, +{ #[inline] fn add_weighted( &self, @@ -71,18 +75,6 @@ impl Animatable for BoxShadowList { self_portion: f64, other_portion: f64, ) -> Result { - // The inset value must change - let mut zero = BoxShadow { - base: SimpleShadow { - color: IntermediateColor::transparent(), - horizontal: Au(0), - vertical: Au(0), - blur: Au(0), - }, - spread: Au(0), - inset: false, - }; - let max_len = cmp::max(self.0.len(), other.0.len()); let mut shadows = Vec::with_capacity(max_len); for i in 0..max_len { @@ -91,23 +83,20 @@ impl Animatable for BoxShadowList { shadow.add_weighted(other, self_portion, other_portion)? }, (Some(shadow), None) => { - zero.inset = shadow.inset; - shadow.add_weighted(&zero, self_portion, other_portion)? + shadow.add_weighted(&shadow.get_zero_value()?, self_portion, other_portion)? }, (None, Some(shadow)) => { - zero.inset = shadow.inset; - zero.add_weighted(&shadow, self_portion, other_portion)? + shadow.get_zero_value()?.add_weighted(&shadow, self_portion, other_portion)? }, (None, None) => unreachable!(), }); } - - Ok(BoxShadowList(shadows)) + Ok(ShadowList(shadows)) } #[inline] fn add(&self, other: &Self) -> Result { - Ok(BoxShadowList( + Ok(ShadowList( self.0.iter().cloned().chain(other.0.iter().cloned()).collect(), )) } @@ -118,7 +107,7 @@ impl ToAnimatedValue for ComputedTextShadowList { #[inline] fn to_animated_value(self) -> Self::AnimatedValue { - TextShadowList(self.0.to_animated_value()) + ShadowList(self.0.to_animated_value()) } #[inline] @@ -127,50 +116,6 @@ impl ToAnimatedValue for ComputedTextShadowList { } } -/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list -impl Animatable for TextShadowList { - #[inline] - fn add_weighted( - &self, - other: &Self, - self_portion: f64, - other_portion: f64, - ) -> Result { - let zero = SimpleShadow { - color: IntermediateColor::transparent(), - horizontal: Au(0), - vertical: Au(0), - blur: Au(0), - }; - - let max_len = cmp::max(self.0.len(), other.0.len()); - let mut shadows = Vec::with_capacity(max_len); - for i in 0..max_len { - shadows.push(match (self.0.get(i), other.0.get(i)) { - (Some(shadow), Some(other)) => { - shadow.add_weighted(other, self_portion, other_portion)? - }, - (Some(shadow), None) => { - shadow.add_weighted(&zero, self_portion, other_portion)? - }, - (None, Some(shadow)) => { - zero.add_weighted(&shadow, self_portion, other_portion)? - }, - (None, None) => unreachable!(), - }); - } - - Ok(TextShadowList(shadows)) - } - - #[inline] - fn add(&self, other: &Self) -> Result { - Ok(TextShadowList( - self.0.iter().cloned().chain(other.0.iter().cloned()).collect(), - )) - } -} - impl Animatable for BoxShadow { #[inline] fn add_weighted( @@ -189,6 +134,15 @@ impl Animatable for BoxShadow { }) } + #[inline] + fn get_zero_value(&self) -> Result { + Ok(BoxShadow { + base: self.base.get_zero_value()?, + spread: self.spread.get_zero_value()?, + inset: self.inset, + }) + } + #[inline] fn compute_distance(&self, other: &Self) -> Result { self.compute_squared_distance(other).map(|sd| sd.sqrt()) @@ -206,7 +160,6 @@ impl Animatable for BoxShadow { } } - impl ToAnimatedValue for ComputedFilterList { type AnimatedValue = FilterList; @@ -251,6 +204,16 @@ impl Animatable for SimpleShadow { }) } + #[inline] + fn get_zero_value(&self) -> Result { + Ok(SimpleShadow { + color: IntermediateColor::transparent(), + horizontal: self.horizontal.get_zero_value()?, + vertical: self.vertical.get_zero_value()?, + blur: self.blur.get_zero_value()?, + }) + } + #[inline] fn compute_distance(&self, other: &Self) -> Result { self.compute_squared_distance(other).map(|sd| sd.sqrt()) diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index faf69b35f8d..2fe6f9d806e 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -375,7 +375,7 @@ pub extern "C" fn Servo_AnimationValues_GetZeroValue( -> RawServoAnimationValueStrong { let value_to_match = AnimationValue::as_arc(&value_to_match); - if let Some(zero_value) = value_to_match.get_zero_value() { + if let Ok(zero_value) = value_to_match.get_zero_value() { Arc::new(zero_value).into_strong() } else { RawServoAnimationValueStrong::null()