diff options
5 files changed, 141 insertions, 43 deletions
diff --git a/components/style/animation.rs b/components/style/animation.rs index 110a73bbacd..941db59cc85 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -339,19 +339,24 @@ impl PropertyAnimation { /// Update the given animation at a given point of progress. pub fn update(&self, style: &mut ComputedValues, time: f64) { - let progress = match self.timing_function { + let timing_function = match self.timing_function { + TransitionTimingFunction::Keyword(keyword) => + keyword.to_non_keyword_value(), + other => other, + }; + let progress = match timing_function { TransitionTimingFunction::CubicBezier(p1, p2) => { // See `WebCore::AnimationBase::solveEpsilon(double)` in WebKit. let epsilon = 1.0 / (200.0 * (self.duration.seconds() as f64)); Bezier::new(Point2D::new(p1.x as f64, p1.y as f64), Point2D::new(p2.x as f64, p2.y as f64)).solve(time, epsilon) - } + }, TransitionTimingFunction::Steps(steps, StartEnd::Start) => { (time * (steps as f64)).ceil() / (steps as f64) - } + }, TransitionTimingFunction::Steps(steps, StartEnd::End) => { (time * (steps as f64)).floor() / (steps as f64) - } + }, TransitionTimingFunction::Frames(frames) => { // https://drafts.csswg.org/css-timing/#frames-timing-functions let mut out = (time * (frames as f64)).floor() / ((frames - 1) as f64); @@ -367,7 +372,10 @@ impl PropertyAnimation { out = 1.0; } out - } + }, + TransitionTimingFunction::Keyword(_) => { + panic!("Keyword function should not appear") + }, }; self.property.update(style, progress); diff --git a/components/style/gecko_bindings/sugar/ns_timing_function.rs b/components/style/gecko_bindings/sugar/ns_timing_function.rs index 7b21d4bee59..69b64c3da52 100644 --- a/components/style/gecko_bindings/sugar/ns_timing_function.rs +++ b/components/style/gecko_bindings/sugar/ns_timing_function.rs @@ -9,6 +9,7 @@ use properties::longhands::transition_timing_function::single_value::SpecifiedVa use properties::longhands::transition_timing_function::single_value::computed_value::StartEnd; use properties::longhands::transition_timing_function::single_value::computed_value::T as ComputedTimingFunction; use std::mem; +use values::computed::ToComputedValue; impl nsTimingFunction { fn set_as_step(&mut self, function_type: nsTimingFunction_Type, steps: u32) { @@ -46,23 +47,7 @@ impl nsTimingFunction { impl From<ComputedTimingFunction> for nsTimingFunction { fn from(function: ComputedTimingFunction) -> nsTimingFunction { - let mut tf: nsTimingFunction = unsafe { mem::zeroed() }; - - match function { - ComputedTimingFunction::Steps(steps, StartEnd::Start) => { - tf.set_as_step(nsTimingFunction_Type::StepStart, steps); - }, - ComputedTimingFunction::Steps(steps, StartEnd::End) => { - tf.set_as_step(nsTimingFunction_Type::StepEnd, steps); - }, - ComputedTimingFunction::Frames(frames) => { - tf.set_as_frames(frames); - }, - ComputedTimingFunction::CubicBezier(p1, p2) => { - tf.set_as_bezier(nsTimingFunction_Type::CubicBezier, p1, p2); - }, - } - tf + SpecifiedTimingFunction::from_computed_value(&function).into() } } @@ -89,7 +74,7 @@ impl From<SpecifiedTimingFunction> for nsTimingFunction { Point2D::new(p2.x.get(), p2.y.get())); }, SpecifiedTimingFunction::Keyword(keyword) => { - match keyword.to_computed_value() { + match keyword.to_non_keyword_value() { ComputedTimingFunction::CubicBezier(p1, p2) => { match keyword { FunctionKeyword::Ease => { @@ -120,7 +105,10 @@ impl From<SpecifiedTimingFunction> for nsTimingFunction { }, ComputedTimingFunction::Frames(frames) => { tf.set_as_frames(frames) - } + }, + ComputedTimingFunction::Keyword(_) => { + panic!("Keyword function should not appear") + }, } }, } @@ -145,11 +133,21 @@ impl From<nsTimingFunction> for ComputedTimingFunction { ComputedTimingFunction::Frames( unsafe { function.__bindgen_anon_1.__bindgen_anon_1.as_ref().mStepsOrFrames }) } - nsTimingFunction_Type::Ease | - nsTimingFunction_Type::Linear | - nsTimingFunction_Type::EaseIn | - nsTimingFunction_Type::EaseOut | - nsTimingFunction_Type::EaseInOut | + nsTimingFunction_Type::Ease => { + ComputedTimingFunction::Keyword(FunctionKeyword::Ease) + }, + nsTimingFunction_Type::Linear => { + ComputedTimingFunction::Keyword(FunctionKeyword::Linear) + }, + nsTimingFunction_Type::EaseIn => { + ComputedTimingFunction::Keyword(FunctionKeyword::EaseIn) + }, + nsTimingFunction_Type::EaseOut => { + ComputedTimingFunction::Keyword(FunctionKeyword::EaseOut) + }, + nsTimingFunction_Type::EaseInOut => { + ComputedTimingFunction::Keyword(FunctionKeyword::EaseInOut) + }, nsTimingFunction_Type::CubicBezier => { ComputedTimingFunction::CubicBezier( TypedPoint2D::new(unsafe { function.__bindgen_anon_1.mFunc.as_ref().mX1 }, diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index c69c32fdb4f..85350c76ddf 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -502,6 +502,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", use parser::{Parse, ParserContext}; use std::fmt; use style_traits::ToCss; + use super::FunctionKeyword; use values::specified; pub use super::parse; @@ -512,6 +513,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", CubicBezier(Point2D<f32>, Point2D<f32>), Steps(u32, StartEnd), Frames(u32), + Keyword(FunctionKeyword), } impl ToCss for T { @@ -538,6 +540,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", try!(frames.to_css(dest)); dest.write_str(")") }, + T::Keyword(keyword) => { + super::serialize_keyword(dest, keyword) + } } } } @@ -651,6 +656,22 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", dest.write_str(")") } + fn serialize_keyword<W>(dest: &mut W, keyword: FunctionKeyword) -> fmt::Result + where W: fmt::Write, + { + match keyword { + FunctionKeyword::StepStart => { + serialize_steps(dest, specified::Integer::new(1), StartEnd::Start) + }, + FunctionKeyword::StepEnd => { + serialize_steps(dest, specified::Integer::new(1), StartEnd::End) + }, + _ => { + keyword.to_css(dest) + }, + } + } + // https://drafts.csswg.org/css-transitions/#serializing-a-timing-function impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { @@ -675,17 +696,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", dest.write_str(")") }, SpecifiedValue::Keyword(keyword) => { - match keyword { - FunctionKeyword::StepStart => { - serialize_steps(dest, specified::Integer::new(1), StartEnd::Start) - }, - FunctionKeyword::StepEnd => { - serialize_steps(dest, specified::Integer::new(1), StartEnd::End) - }, - _ => { - keyword.to_css(dest) - }, - } + serialize_keyword(dest, keyword) }, } } @@ -708,7 +719,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", SpecifiedValue::Frames(frames) => { computed_value::T::Frames(frames.to_computed_value(context) as u32) }, - SpecifiedValue::Keyword(keyword) => keyword.to_computed_value(), + SpecifiedValue::Keyword(keyword) => { + computed_value::T::Keyword(keyword) + }, } } #[inline] @@ -729,13 +742,16 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", let frames = frames as i32; SpecifiedValue::Frames(specified::Integer::from_computed_value(&frames)) }, + computed_value::T::Keyword(keyword) => { + SpecifiedValue::Keyword(keyword) + }, } } } impl FunctionKeyword { #[inline] - pub fn to_computed_value(&self) -> computed_value::T { + pub fn to_non_keyword_value(&self) -> computed_value::T { match *self { FunctionKeyword::Ease => ease(), FunctionKeyword::Linear => linear(), @@ -753,7 +769,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", #[inline] pub fn get_initial_value() -> computed_value::T { - ease() + computed_value::T::Keyword(FunctionKeyword::Ease) } #[inline] diff --git a/tests/wpt/metadata-css/css-transitions-1_dev/html/transition-001.htm.ini b/tests/wpt/metadata-css/css-transitions-1_dev/html/transition-001.htm.ini new file mode 100644 index 00000000000..e727848ceab --- /dev/null +++ b/tests/wpt/metadata-css/css-transitions-1_dev/html/transition-001.htm.ini @@ -0,0 +1,38 @@ +[transition-001.htm] + type: testharness + [parse '1s'] + expected: FAIL + + [parse '1s 2s'] + expected: FAIL + + [parse '1s 2s ease-in'] + expected: FAIL + + [parse '1s ease-in 2s'] + expected: FAIL + + [parse 'ease-in 1s 2s'] + expected: FAIL + + [parse '1s width'] + expected: FAIL + + [parse 'width 1s'] + expected: FAIL + + [parse '1s width 2s'] + expected: FAIL + + [parse '1s 2s width ease-in'] + expected: FAIL + + [parse '1s ease-in 2s width'] + expected: FAIL + + [parse 'width ease-in 1s 2s'] + expected: FAIL + + [parse 'width .1s ease-in .2s'] + expected: FAIL + diff --git a/tests/wpt/metadata-css/css-transitions-1_dev/html/transition-timing-function-001.htm.ini b/tests/wpt/metadata-css/css-transitions-1_dev/html/transition-timing-function-001.htm.ini new file mode 100644 index 00000000000..f8f5df27e56 --- /dev/null +++ b/tests/wpt/metadata-css/css-transitions-1_dev/html/transition-timing-function-001.htm.ini @@ -0,0 +1,38 @@ +[transition-timing-function-001.htm] + type: testharness + [parse 'ease'] + expected: FAIL + + [parse 'linear'] + expected: FAIL + + [parse 'ease-in'] + expected: FAIL + + [parse 'ease-out'] + expected: FAIL + + [parse 'ease-in-out'] + expected: FAIL + + [parse 'cubic-bezier(foobar)'] + expected: FAIL + + [parse 'steps(foobar)'] + expected: FAIL + + [parse 'steps(3.3, end)'] + expected: FAIL + + [parse 'steps(3, top)'] + expected: FAIL + + [parse 'steps(-3, top)'] + expected: FAIL + + [parse 'cubic-bezier(-0.1, -0.2, -0.3, -0.4)'] + expected: FAIL + + [parse 'cubic-bezier(1.1, 1.2, 1.3, 1.4)'] + expected: FAIL + |