From 554a4cf9f20b82bb5bd9f1c8fd5a169a29b22305 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 10 Sep 2015 11:35:40 -0700 Subject: [PATCH] Add transitions for CSS `calc()`. Closes #7284 --- components/style/animation.rs | 29 +++++++++++++++-- components/style/values.rs | 51 ++++++++++++++++++++++++++++-- tests/ref/basic.list | 1 + tests/ref/transition_calc.html | 25 +++++++++++++++ tests/ref/transition_calc_ref.html | 17 ++++++++++ 5 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 tests/ref/transition_calc.html create mode 100644 tests/ref/transition_calc_ref.html diff --git a/components/style/animation.rs b/components/style/animation.rs index b7104da5683..32aae7c7cce 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -28,7 +28,7 @@ use util::bezier::Bezier; use util::geometry::Au; use values::CSSFloat; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; -use values::computed::{LengthOrPercentage, Length, Time}; +use values::computed::{LengthOrPercentage, Length, Time, Calc}; #[derive(Clone, Debug)] pub struct PropertyAnimation { @@ -513,6 +513,17 @@ impl Interpolate for Color { } } +impl Interpolate for Calc { + #[inline] + fn interpolate(&self, other: &Calc, time: f64) + -> Option { + Some(Calc { + length: self.length().interpolate(&other.length(), time), + percentage: self.percentage().interpolate(&other.percentage(), time), + }) + } +} + impl Interpolate for LengthOrPercentage { #[inline] fn interpolate(&self, other: &LengthOrPercentage, time: f64) @@ -530,7 +541,13 @@ impl Interpolate for LengthOrPercentage { Some(LengthOrPercentage::Percentage(value)) }) } - (_, _) => None, + (this, other) => { + let this: Calc = From::from(this); + let other: Calc = From::from(other); + this.interpolate(&other, time).and_then(|value| { + Some(LengthOrPercentage::Calc(value)) + }) + } } } } @@ -555,7 +572,13 @@ impl Interpolate for LengthOrPercentageOrAuto { (LengthOrPercentageOrAuto::Auto, LengthOrPercentageOrAuto::Auto) => { Some(LengthOrPercentageOrAuto::Auto) } - (_, _) => None, + (this, other) => { + let this: Option = From::from(this); + let other: Option = From::from(other); + this.interpolate(&other, time).unwrap_or(None).and_then(|value| { + Some(LengthOrPercentageOrAuto::Calc(value)) + }) + } } } } diff --git a/components/style/values.rs b/components/style/values.rs index 15aa5682ca5..6907a736988 100644 --- a/components/style/values.rs +++ b/components/style/values.rs @@ -1299,8 +1299,8 @@ pub mod computed { #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)] pub struct Calc { - length: Option, - percentage: Option, + pub length: Option, + pub percentage: Option, } impl Calc { @@ -1313,6 +1313,53 @@ pub mod computed { } } + impl From for Calc { + fn from(len: LengthOrPercentage) -> Calc { + match len { + LengthOrPercentage::Percentage(this) => { + Calc { + length: None, + percentage: Some(this), + } + } + LengthOrPercentage::Length(this) => { + Calc { + length: Some(this), + percentage: None, + } + } + LengthOrPercentage::Calc(this) => { + this + } + } + } + } + + impl From for Option { + fn from(len: LengthOrPercentageOrAuto) -> Option { + match len { + LengthOrPercentageOrAuto::Percentage(this) => { + Some(Calc { + length: None, + percentage: Some(this), + }) + } + LengthOrPercentageOrAuto::Length(this) => { + Some(Calc { + length: Some(this), + percentage: None, + }) + } + LengthOrPercentageOrAuto::Calc(this) => { + Some(this) + } + LengthOrPercentageOrAuto::Auto => { + None + } + } + } + } + impl ::cssparser::ToCss for Calc { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match (self.length, self.percentage) { diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 404adece8de..0db07fcd49d 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -378,6 +378,7 @@ device-pixel-ratio=2 != pixel_snapping_border_a.html pixel_snapping_border_ref.h == transform_simple_a.html transform_simple_ref.html == transform_skew_a.html transform_skew_ref.html == transform_stacking_context_a.html transform_stacking_context_ref.html +== transition_calc.html transition_calc_ref.html == upper_id_attr.html upper_id_attr_ref.html flaky_cpu,prefs:"layout.writing-mode.enabled" == vertical-lr-blocks.html vertical-lr-blocks_ref.html == vertical_align_bottom_a.html vertical_align_bottom_ref.html diff --git a/tests/ref/transition_calc.html b/tests/ref/transition_calc.html new file mode 100644 index 00000000000..2497ddeed0c --- /dev/null +++ b/tests/ref/transition_calc.html @@ -0,0 +1,25 @@ + +
+
+
+ diff --git a/tests/ref/transition_calc_ref.html b/tests/ref/transition_calc_ref.html new file mode 100644 index 00000000000..654e5a26232 --- /dev/null +++ b/tests/ref/transition_calc_ref.html @@ -0,0 +1,17 @@ + +
+
+