From e20a3ad9b5496b5fa1e7530592e4775a56995a05 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Sat, 28 Jan 2017 18:53:36 +0900 Subject: [PATCH] Bug 1328787 - Part 8: Animation timing function can be overridden by animation-timing-function specified in keyframe. r=heycam --- components/style/keyframes.rs | 31 +++++++++++++++++++ .../style/properties/longhand/box.mako.rs | 2 +- ports/geckolib/glue.rs | 7 ++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/components/style/keyframes.rs b/components/style/keyframes.rs index 001a994dbfe..247ca8efc25 100644 --- a/components/style/keyframes.rs +++ b/components/style/keyframes.rs @@ -11,8 +11,10 @@ use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule}; use parking_lot::RwLock; use parser::{ParserContext, ParserContextExtraData, log_css_error}; use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId}; +use properties::{PropertyDeclarationId, LonghandId, DeclaredValue}; use properties::PropertyDeclarationParseResult; use properties::animated_properties::TransitionProperty; +use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; use std::fmt; use std::sync::Arc; use style_traits::ToCss; @@ -198,6 +200,35 @@ impl KeyframesStep { declared_timing_function: declared_timing_function, } } + + /// Return specified TransitionTimingFunction if this KeyframesSteps has 'animation-timing-function'. + pub fn get_animation_timing_function(&self) -> Option { + if !self.declared_timing_function { + return None; + } + match self.value { + KeyframesStepValue::Declarations { ref block } => { + let guard = block.read(); + let &(ref declaration, _) = + guard.get(PropertyDeclarationId::Longhand(LonghandId::AnimationTimingFunction)).unwrap(); + match *declaration { + PropertyDeclaration::AnimationTimingFunction(ref value) => { + match *value { + DeclaredValue::Value(ref value) => { + // Use the first value. + Some(value.0[0]) + }, + _ => None, + } + }, + _ => panic!(), + } + }, + KeyframesStepValue::ComputedValues => { + panic!("Shouldn't happen to set animation-timing-function in missing keyframes") + }, + } + } } /// This structure represents a list of animation steps computed from the list diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 1558e597ead..4468f0e1eae 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -830,7 +830,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", animatable="False", extra_prefixes="moz webkit" spec="https://drafts.csswg.org/css-animations/#propdef-animation-timing-function", - allowed_in_keyframe_block="False"> + allowed_in_keyframe_block="True"> pub use properties::longhands::transition_timing_function::single_value::computed_value; pub use properties::longhands::transition_timing_function::single_value::get_initial_value; pub use properties::longhands::transition_timing_function::single_value::get_initial_specified_value; diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index bf9a0a77460..8ccc2f901d4 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -1155,7 +1155,12 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet if let Some(ref animation) = data.stylist.animations().get(&name) { for step in &animation.steps { - let timing_function = *style_timing_function; + // Override timing_function if the keyframe has animation-timing-function. + let timing_function = if let Some(val) = step.get_animation_timing_function() { + val.into() + } else { + *style_timing_function + }; let _keyframe = unsafe { Gecko_AnimationAppendKeyframe(keyframes,