diff --git a/components/style/animation.rs b/components/style/animation.rs index 15c58c6098e..d090ecb1ecb 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -10,7 +10,7 @@ use context::SharedStyleContext; use dom::{OpaqueNode, TElement}; use font_metrics::FontMetricsProvider; use properties::{self, CascadeFlags, ComputedValues, LonghandId}; -use properties::animated_properties::{AnimatedProperty, TransitionProperty}; +use properties::animated_properties::AnimatedProperty; use properties::longhands::animation_direction::computed_value::single_value::T as AnimationDirection; use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState; use rule_tree::CascadeLevel; @@ -20,6 +20,7 @@ use std::sync::mpsc::Sender; use stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue}; use timer::Timer; use values::computed::Time; +use values::computed::box_::TransitionProperty; use values::computed::transform::TimingFunction; use values::generics::box_::AnimationIterationCount; use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction}; diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 3ba686911ee..4eae24a2bfa 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -67,7 +67,6 @@ use media_queries::Device; use properties::{ComputedValues, LonghandId}; use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; use properties::animated_properties::{AnimationValue, AnimationValueMap}; -use properties::animated_properties::TransitionProperty; use properties::style_structs::Font; use rule_tree::CascadeLevel as ServoCascadeLevel; use selector_parser::{AttrValue, Direction, PseudoClassStringArg}; @@ -1586,6 +1585,7 @@ impl<'le> TElement for GeckoElement<'le> { ) -> bool { use gecko_bindings::structs::nsCSSPropertyID; use properties::LonghandIdSet; + use values::computed::TransitionProperty; debug_assert!( self.might_need_transitions_update(Some(before_change_style), after_change_style), diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 4fa98fc1b9d..b4411e1ea8b 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -48,7 +48,6 @@ use gecko::values::GeckoStyleCoordConvertible; use gecko::values::round_border_to_device_pixels; use logical_geometry::WritingMode; use media_queries::Device; -use properties::animated_properties::TransitionProperty; use properties::computed_value_flags::*; use properties::{longhands, Importance, LonghandId}; use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId}; @@ -59,7 +58,7 @@ use std::marker::PhantomData; use std::mem::{forget, uninitialized, transmute, zeroed}; use std::{cmp, ops, ptr}; use values::{self, CustomIdent, Either, KeyframesName, None_}; -use values::computed::{NonNegativeLength, ToComputedValue, Percentage}; +use values::computed::{NonNegativeLength, ToComputedValue, Percentage, TransitionProperty}; use values::computed::font::FontSize; use values::computed::effects::{BoxShadow, Filter, SimpleShadow}; use values::computed::outline::OutlineStyle; diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index bccbc4d9683..acdaebef205 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -9,16 +9,13 @@ from itertools import groupby %> -use Atom; -use cssparser::Parser; #[cfg(feature = "gecko")] use gecko_bindings::bindings::RawServoAnimationValueMap; #[cfg(feature = "gecko")] use gecko_bindings::structs::RawGeckoGfxMatrix4x4; #[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSPropertyID; #[cfg(feature = "gecko")] use gecko_bindings::sugar::ownership::{HasFFI, HasSimpleFFI}; use itertools::{EitherOrBoth, Itertools}; use num_traits::Zero; -use parser::ParserContext; -use properties::{CSSWideKeyword, PropertyDeclaration, PropertyDeclarationId}; +use properties::{CSSWideKeyword, PropertyDeclaration}; use properties::longhands; use properties::longhands::font_weight::computed_value::T as FontWeight; use properties::longhands::visibility::computed_value::T as Visibility; @@ -27,19 +24,17 @@ use properties::{LonghandId, ShorthandId}; use servo_arc::Arc; use smallvec::SmallVec; use std::{cmp, ptr}; -use std::fmt::{self, Write}; use std::mem::{self, ManuallyDrop}; #[cfg(feature = "gecko")] use hash::FnvHashMap; -use style_traits::{KeywordsCollectFn, ParseError, SpecifiedValueInfo, ToCss, CssWriter}; use super::ComputedValues; -use values::{CSSFloat, CustomIdent}; +use values::CSSFloat; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; use values::animated::color::RGBA as AnimatedRGBA; use values::animated::effects::Filter as AnimatedFilter; use values::computed::{Angle, CalcLengthOrPercentage}; use values::computed::{ClipRect, Context}; use values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto}; -use values::computed::{LengthOrPercentageOrNone, MaxLength}; +use values::computed::{LengthOrPercentageOrNone, MaxLength, TransitionProperty}; use values::computed::{NonNegativeNumber, Number, NumberOrPercentage, Percentage}; use values::computed::length::NonNegativeLengthOrPercentage; use values::computed::ToComputedValue; @@ -73,91 +68,6 @@ pub fn nscsspropertyid_is_animatable(property: nsCSSPropertyID) -> bool { } } -/// A given transition property, that is either `All`, a transitionable longhand property, -/// a shorthand with at least one transitionable longhand component, or an unsupported property. -// NB: This needs to be here because it needs all the longhands generated -// beforehand. -#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)] -pub enum TransitionProperty { - /// A shorthand. - Shorthand(ShorthandId), - /// A longhand transitionable property. - Longhand(LonghandId), - /// A custom property. - Custom(Atom), - /// Unrecognized property which could be any non-transitionable, custom property, or - /// unknown property. - Unsupported(CustomIdent), -} - -impl ToCss for TransitionProperty { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - use values::serialize_atom_identifier; - match *self { - TransitionProperty::Shorthand(ref s) => s.to_css(dest), - TransitionProperty::Longhand(ref l) => l.to_css(dest), - TransitionProperty::Custom(ref name) => { - dest.write_str("--")?; - serialize_atom_identifier(name, dest) - } - TransitionProperty::Unsupported(ref i) => i.to_css(dest), - } - } -} - -impl TransitionProperty { - /// Returns `all`. - #[inline] - pub fn all() -> Self { - TransitionProperty::Shorthand(ShorthandId::All) - } - - /// Parse a transition-property value. - pub fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let location = input.current_source_location(); - let ident = input.expect_ident()?; - - let id = match PropertyId::parse(&ident, context) { - Ok(id) => id, - Err(..) => return Ok(TransitionProperty::Unsupported( - CustomIdent::from_ident(location, ident, &["none"])?, - )), - }; - - Ok(match id.as_shorthand() { - Ok(s) => TransitionProperty::Shorthand(s), - Err(longhand_or_custom) => { - match longhand_or_custom { - PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id), - PropertyDeclarationId::Custom(custom) => { - TransitionProperty::Custom(custom.clone()) - } - } - } - }) - } - - /// Convert TransitionProperty to nsCSSPropertyID. - #[cfg(feature = "gecko")] - pub fn to_nscsspropertyid(&self) -> Result { - Ok(match *self { - TransitionProperty::Shorthand(ShorthandId::All) => { - nsCSSPropertyID::eCSSPropertyExtra_all_properties - } - TransitionProperty::Shorthand(ref id) => id.to_nscsspropertyid(), - TransitionProperty::Longhand(ref id) => id.to_nscsspropertyid(), - TransitionProperty::Custom(..) | - TransitionProperty::Unsupported(..) => return Err(()), - }) - } -} - /// Convert nsCSSPropertyID to TransitionProperty #[cfg(feature = "gecko")] #[allow(non_upper_case_globals)] @@ -184,15 +94,6 @@ impl From for TransitionProperty { } } -impl SpecifiedValueInfo for TransitionProperty { - fn collect_completion_keywords(f: KeywordsCollectFn) { - // `transition-property` can actually accept all properties and - // arbitrary identifiers, but `all` is a special one we'd like - // to list. - f(&["all"]); - } -} - /// Returns true if this nsCSSPropertyID is one of the transitionable properties. #[cfg(feature = "gecko")] pub fn nscsspropertyid_is_transitionable(property: nsCSSPropertyID) -> bool { diff --git a/components/style/properties/shorthand/box.mako.rs b/components/style/properties/shorthand/box.mako.rs index d4f1eb66293..842dfbd7229 100644 --- a/components/style/properties/shorthand/box.mako.rs +++ b/components/style/properties/shorthand/box.mako.rs @@ -123,9 +123,11 @@ macro_rules! try_parse_one { transition-timing-function transition-delay" spec="https://drafts.csswg.org/css-transitions/#propdef-transition"> + use parser::Parse; % for prop in "delay duration property timing_function".split(): use properties::longhands::transition_${prop}; % endfor + use values::specified::TransitionProperty; pub fn parse_value<'i, 't>( context: &ParserContext, @@ -137,7 +139,7 @@ macro_rules! try_parse_one { % endfor // Unlike other properties, transition-property uses an Option<> to // represent 'none' as `None`. - transition_property: Option, + transition_property: Option, } fn parse_one_transition<'i, 't>( @@ -158,7 +160,7 @@ macro_rules! try_parse_one { // Must check 'transition-property' after 'transition-timing-function' since // 'transition-property' accepts any keyword. if property.is_none() { - if let Ok(value) = input.try(|i| transition_property::SingleSpecifiedValue::parse(context, i)) { + if let Ok(value) = input.try(|i| TransitionProperty::parse(context, i)) { property = Some(Some(value)); continue; } diff --git a/components/style/values/computed/box.rs b/components/style/values/computed/box.rs index 96696702a2a..224fe4669a1 100644 --- a/components/style/values/computed/box.rs +++ b/components/style/values/computed/box.rs @@ -11,7 +11,7 @@ use values::generics::box_::Perspective as GenericPerspective; use values::generics::box_::VerticalAlign as GenericVerticalAlign; pub use values::specified::box_::{AnimationName, Contain, Display, OverflowClipBox}; -pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, WillChange}; +pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, TransitionProperty, WillChange}; /// A computed value for the `vertical-align` property. pub type VerticalAlign = GenericVerticalAlign; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index d6660f6a6eb..e742c4e49f1 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -30,7 +30,6 @@ use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent use super::specified; pub use app_units::Au; -pub use properties::animated_properties::TransitionProperty; #[cfg(feature = "gecko")] pub use self::align::{AlignContent, AlignItems, JustifyContent, JustifyItems, SelfAlignment}; #[cfg(feature = "gecko")] @@ -43,7 +42,7 @@ pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontV pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings}; pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; -pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display}; +pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display, TransitionProperty}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective}; pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index dcce3d592ab..059188f824d 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -7,10 +7,10 @@ use Atom; use cssparser::Parser; use parser::{Parse, ParserContext}; -use properties::{LonghandId, PropertyId, PropertyFlags, PropertyDeclarationId}; +use properties::{LonghandId, ShorthandId, PropertyId, PropertyFlags, PropertyDeclarationId}; use selectors::parser::SelectorParseErrorKind; use std::fmt::{self, Write}; -use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; +use style_traits::{CssWriter, KeywordsCollectFn, ParseError, StyleParseErrorKind, SpecifiedValueInfo, ToCss}; use values::{CustomIdent, KeyframesName}; use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use values::generics::box_::Perspective as GenericPerspective; @@ -714,3 +714,96 @@ impl Parse for Perspective { )?)) } } + +/// A given transition property, that is either `All`, a longhand or shorthand +/// property, or an unsupported or custom property. +#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)] +pub enum TransitionProperty { + /// A shorthand. + Shorthand(ShorthandId), + /// A longhand transitionable property. + Longhand(LonghandId), + /// A custom property. + Custom(Atom), + /// Unrecognized property which could be any non-transitionable, custom property, or + /// unknown property. + Unsupported(CustomIdent), +} + +impl ToCss for TransitionProperty { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + use values::serialize_atom_identifier; + match *self { + TransitionProperty::Shorthand(ref s) => s.to_css(dest), + TransitionProperty::Longhand(ref l) => l.to_css(dest), + TransitionProperty::Custom(ref name) => { + dest.write_str("--")?; + serialize_atom_identifier(name, dest) + } + TransitionProperty::Unsupported(ref i) => i.to_css(dest), + } + } +} + +impl Parse for TransitionProperty { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + let location = input.current_source_location(); + let ident = input.expect_ident()?; + + let id = match PropertyId::parse(&ident, context) { + Ok(id) => id, + Err(..) => return Ok(TransitionProperty::Unsupported( + CustomIdent::from_ident(location, ident, &["none"])?, + )), + }; + + Ok(match id.as_shorthand() { + Ok(s) => TransitionProperty::Shorthand(s), + Err(longhand_or_custom) => { + match longhand_or_custom { + PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id), + PropertyDeclarationId::Custom(custom) => { + TransitionProperty::Custom(custom.clone()) + } + } + } + }) + } +} + +impl SpecifiedValueInfo for TransitionProperty { + fn collect_completion_keywords(f: KeywordsCollectFn) { + // `transition-property` can actually accept all properties and + // arbitrary identifiers, but `all` is a special one we'd like + // to list. + f(&["all"]); + } +} + +impl TransitionProperty { + /// Returns `all`. + #[inline] + pub fn all() -> Self { + TransitionProperty::Shorthand(ShorthandId::All) + } + + /// Convert TransitionProperty to nsCSSPropertyID. + #[cfg(feature = "gecko")] + pub fn to_nscsspropertyid(&self) -> Result<::gecko_bindings::structs::nsCSSPropertyID, ()> { + Ok(match *self { + TransitionProperty::Shorthand(ShorthandId::All) => { + ::gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_all_properties + } + TransitionProperty::Shorthand(ref id) => id.to_nscsspropertyid(), + TransitionProperty::Longhand(ref id) => id.to_nscsspropertyid(), + TransitionProperty::Custom(..) | + TransitionProperty::Unsupported(..) => return Err(()), + }) + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index c25d58332f5..c5794bbad1e 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -23,7 +23,6 @@ use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericT use values::serialize_atom_identifier; use values::specified::calc::CalcNode; -pub use properties::animated_properties::TransitionProperty; pub use self::angle::Angle; #[cfg(feature = "gecko")] pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution}; @@ -40,7 +39,7 @@ pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumer pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective}; -pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange}; +pub use self::box_::{ScrollSnapType, TouchAction, TransitionProperty, VerticalAlign, WillChange}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; pub use self::effects::{BoxShadow, Filter, SimpleShadow};