From b1bcb22650e4de4973088e9587a534082ba10daa Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Tue, 2 May 2023 22:47:28 +0000 Subject: [PATCH] style: Move animation-related values from box.rs/ui.rs to animation.rs Although we store animation and transition style values in StyleUIReset and define their properties in longhands/ui.mako.rs, but we may move them in the future if this style struct becomes too large. So let's move the definition of their values to an independent module, animation, so we don't have to worry about this again. This patch doesn't change any other things. Only move code. Differential Revision: https://phabricator.services.mozilla.com/D173903 --- components/style/values/computed/animation.rs | 66 ++++ components/style/values/computed/box.rs | 61 +-- components/style/values/computed/mod.rs | 24 +- components/style/values/computed/ui.rs | 5 +- components/style/values/generics/animation.rs | 59 +++ components/style/values/generics/mod.rs | 1 + components/style/values/generics/ui.rs | 51 --- .../style/values/specified/animation.rs | 355 ++++++++++++++++++ components/style/values/specified/box.rs | 328 +--------------- components/style/values/specified/mod.rs | 25 +- components/style/values/specified/ui.rs | 22 +- 11 files changed, 518 insertions(+), 479 deletions(-) create mode 100644 components/style/values/computed/animation.rs create mode 100644 components/style/values/generics/animation.rs create mode 100644 components/style/values/specified/animation.rs diff --git a/components/style/values/computed/animation.rs b/components/style/values/computed/animation.rs new file mode 100644 index 00000000000..c30bc11b08b --- /dev/null +++ b/components/style/values/computed/animation.rs @@ -0,0 +1,66 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Computed values for properties related to animations and transitions + +use crate::values::computed::{Context, LengthPercentage, ToComputedValue}; +use crate::values::generics::animation as generics; +use crate::values::specified::animation as specified; +use std::fmt::{self, Write}; +use style_traits::{CssWriter, ToCss}; + +pub use crate::values::specified::animation::{ + AnimationName, AnimationTimeline, ScrollAxis, ScrollTimelineName, TransitionProperty, +}; + +/// A computed value for the `animation-iteration-count` property. +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToResolvedValue, ToShmem)] +#[repr(C)] +pub struct AnimationIterationCount(pub f32); + +impl ToComputedValue for specified::AnimationIterationCount { + type ComputedValue = AnimationIterationCount; + + #[inline] + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { + AnimationIterationCount(match *self { + specified::AnimationIterationCount::Number(n) => n.to_computed_value(context).0, + specified::AnimationIterationCount::Infinite => std::f32::INFINITY, + }) + } + + #[inline] + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + use crate::values::specified::NonNegativeNumber; + if computed.0.is_infinite() { + specified::AnimationIterationCount::Infinite + } else { + specified::AnimationIterationCount::Number(NonNegativeNumber::new(computed.0)) + } + } +} + +impl AnimationIterationCount { + /// Returns the value `1.0`. + #[inline] + pub fn one() -> Self { + Self(1.0) + } +} + +impl ToCss for AnimationIterationCount { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + if self.0.is_infinite() { + dest.write_str("infinite") + } else { + self.0.to_css(dest) + } + } +} + +/// A computed value for the `view-timeline-inset` property. +pub type ViewTimelineInset = generics::GenericViewTimelineInset; diff --git a/components/style/values/computed/box.rs b/components/style/values/computed/box.rs index 06f83aa70ad..238bbe8376a 100644 --- a/components/style/values/computed/box.rs +++ b/components/style/values/computed/box.rs @@ -13,68 +13,15 @@ use crate::values::generics::box_::{ use crate::values::specified::box_ as specified; pub use crate::values::specified::box_::{ - AnimationName, AnimationTimeline, Appearance, BreakBetween, BreakWithin, - Clear as SpecifiedClear, Contain, ContainerName, ContainerType, ContentVisibility, Display, - Float as SpecifiedFloat, Overflow, OverflowAnchor, OverflowClipBox, OverscrollBehavior, - ScrollAxis, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop, ScrollSnapStrictness, - ScrollSnapType, ScrollTimelineName, ScrollbarGutter, TouchAction, TransitionProperty, - WillChange, + Appearance, BreakBetween, BreakWithin, Clear as SpecifiedClear, Contain, ContainerName, + ContainerType, ContentVisibility, Display, Float as SpecifiedFloat, Overflow, OverflowAnchor, + OverflowClipBox, OverscrollBehavior, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop, + ScrollSnapStrictness, ScrollSnapType, ScrollbarGutter, TouchAction, WillChange, }; -use std::fmt::{self, Write}; -use style_traits::{ToCss, CssWriter}; - /// A computed value for the `vertical-align` property. pub type VerticalAlign = GenericVerticalAlign; -/// A computed value for the `animation-iteration-count` property. -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToResolvedValue, ToShmem)] -#[repr(C)] -pub struct AnimationIterationCount(pub f32); - -impl ToComputedValue for specified::AnimationIterationCount { - type ComputedValue = AnimationIterationCount; - - #[inline] - fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { - AnimationIterationCount(match *self { - specified::AnimationIterationCount::Number(n) => n.to_computed_value(context).0, - specified::AnimationIterationCount::Infinite => std::f32::INFINITY, - }) - } - - #[inline] - fn from_computed_value(computed: &Self::ComputedValue) -> Self { - use crate::values::specified::NonNegativeNumber; - if computed.0.is_infinite() { - specified::AnimationIterationCount::Infinite - } else { - specified::AnimationIterationCount::Number(NonNegativeNumber::new(computed.0)) - } - } -} - -impl AnimationIterationCount { - /// Returns the value `1.0`. - #[inline] - pub fn one() -> Self { - Self(1.0) - } -} - -impl ToCss for AnimationIterationCount { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - if self.0.is_infinite() { - dest.write_str("infinite") - } else { - self.0.to_css(dest) - } - } -} - /// A computed value for the `contain-intrinsic-size` property. pub type ContainIntrinsicSize = GenericContainIntrinsicSize; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 49048711643..ff1e0696bc9 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -47,25 +47,26 @@ pub use self::basic_shape::FillRule; pub use self::border::{BorderCornerRadius, BorderRadius, BorderSpacing}; pub use self::border::{BorderImageRepeat, BorderImageSideWidth}; pub use self::border::{BorderImageSlice, BorderImageWidth}; -pub use self::box_::{ - AnimationIterationCount, AnimationName, AnimationTimeline, Contain, ContainerName, - ContainerType, -}; pub use self::box_::{ Appearance, BreakBetween, BreakWithin, Clear, ContainIntrinsicSize, ContentVisibility, Float, }; -pub use self::box_::{Display, LineClamp, Overflow, OverflowAnchor, TransitionProperty}; +pub use self::box_::{ + Contain, ContainerName, ContainerType, Display, LineClamp, Overflow, OverflowAnchor, +}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollbarGutter}; -pub use self::box_::{ScrollAxis, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop}; -pub use self::box_::{ScrollSnapStrictness, ScrollSnapType, ScrollTimelineName}; +pub use self::box_::{ + ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop, ScrollSnapStrictness, ScrollSnapType, +}; pub use self::box_::{TouchAction, VerticalAlign, WillChange}; -pub use self::color::{Color, ColorOrAuto, ColorPropertyValue, ColorScheme, PrintColorAdjust, ForcedColorAdjust}; +pub use self::color::{ + Color, ColorOrAuto, ColorPropertyValue, ColorScheme, ForcedColorAdjust, PrintColorAdjust, +}; pub use self::column::ColumnCount; pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset, CounterSet}; pub use self::easing::TimingFunction; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; pub use self::flex::FlexBasis; -pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontPalette}; +pub use self::font::{FontFamily, FontLanguageOverride, FontPalette, FontStyle}; pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis}; pub use self::font::{FontVariantAlternates, FontWeight}; @@ -104,7 +105,9 @@ pub use self::transform::{Rotate, Scale, Transform, TransformOperation}; pub use self::transform::{TransformOrigin, TransformStyle, Translate}; #[cfg(feature = "gecko")] pub use self::ui::CursorImage; -pub use self::ui::{BoolInteger, Cursor, UserSelect, ViewTimelineInset}; +pub use self::ui::{BoolInteger, Cursor, UserSelect}; +pub use self::animation::{AnimationIterationCount, AnimationName, AnimationTimeline}; +pub use self::animation::{ScrollAxis, ScrollTimelineName, TransitionProperty, ViewTimelineInset}; pub use super::specified::TextTransform; pub use super::specified::ViewportVariant; pub use super::specified::{BorderStyle, TextDecorationLine}; @@ -113,6 +116,7 @@ pub use app_units::Au; #[cfg(feature = "gecko")] pub mod align; pub mod angle; +pub mod animation; pub mod background; pub mod basic_shape; pub mod border; diff --git a/components/style/values/computed/ui.rs b/components/style/values/computed/ui.rs index 477050ed657..6fa5137adf0 100644 --- a/components/style/values/computed/ui.rs +++ b/components/style/values/computed/ui.rs @@ -6,7 +6,7 @@ use crate::values::computed::color::Color; use crate::values::computed::image::Image; -use crate::values::computed::{LengthPercentage, Number}; +use crate::values::computed::Number; use crate::values::generics::ui as generics; pub use crate::values::specified::ui::CursorKind; @@ -20,6 +20,3 @@ pub type CursorImage = generics::GenericCursorImage; /// A computed value for `scrollbar-color` property. pub type ScrollbarColor = generics::GenericScrollbarColor; - -/// A computed value for the `view-timeline-inset` property. -pub type ViewTimelineInset = generics::GenericViewTimelineInset; diff --git a/components/style/values/generics/animation.rs b/components/style/values/generics/animation.rs new file mode 100644 index 00000000000..db1e08da1ac --- /dev/null +++ b/components/style/values/generics/animation.rs @@ -0,0 +1,59 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Generic values for properties related to animations and transitions. + +use crate::values::generics::length::GenericLengthPercentageOrAuto; +use std::fmt::{self, Write}; +use style_traits::{CssWriter, ToCss}; + +/// A generic value for the `[ [ auto | ]{1,2} ]`. +/// +/// https://drafts.csswg.org/scroll-animations-1/#view-timeline-inset +#[derive( + Clone, + Copy, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToResolvedValue, + ToShmem, +)] +#[repr(C)] +pub struct GenericViewTimelineInset { + /// The start inset in the relevant axis. + pub start: GenericLengthPercentageOrAuto, + /// The end inset. + pub end: GenericLengthPercentageOrAuto, +} + +pub use self::GenericViewTimelineInset as ViewTimelineInset; + +impl ToCss for ViewTimelineInset +where + LengthPercent: PartialEq + ToCss, +{ + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + self.start.to_css(dest)?; + if self.end != self.start { + dest.write_char(' ')?; + self.end.to_css(dest)?; + } + Ok(()) + } +} + +impl Default for ViewTimelineInset { + fn default() -> Self { + Self { + start: GenericLengthPercentageOrAuto::auto(), + end: GenericLengthPercentageOrAuto::auto(), + } + } +} diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index 58c982f78c6..237d3c16a32 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -13,6 +13,7 @@ use cssparser::Parser; use std::ops::Add; use style_traits::{KeywordsCollectFn, ParseError, SpecifiedValueInfo, StyleParseErrorKind}; +pub mod animation; pub mod background; pub mod basic_shape; pub mod border; diff --git a/components/style/values/generics/ui.rs b/components/style/values/generics/ui.rs index de347435be3..87c8674182c 100644 --- a/components/style/values/generics/ui.rs +++ b/components/style/values/generics/ui.rs @@ -4,7 +4,6 @@ //! Generic values for UI properties. -use crate::values::generics::length::GenericLengthPercentageOrAuto; use crate::values::specified::ui::CursorKind; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; @@ -128,53 +127,3 @@ impl Default for ScrollbarColor { ScrollbarColor::Auto } } - -/// A generic value for the `[ [ auto | ]{1,2} ]`. -/// -/// https://drafts.csswg.org/scroll-animations-1/#view-timeline-inset -#[derive( - Clone, - Copy, - Debug, - MallocSizeOf, - PartialEq, - SpecifiedValueInfo, - ToComputedValue, - ToResolvedValue, - ToShmem, -)] -#[repr(C)] -pub struct GenericViewTimelineInset { - /// The start inset in the relevant axis. - pub start: GenericLengthPercentageOrAuto, - /// The end inset. - pub end: GenericLengthPercentageOrAuto, -} - -pub use self::GenericViewTimelineInset as ViewTimelineInset; - -impl ToCss for ViewTimelineInset -where - LengthPercent: ToCss + PartialEq, -{ - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - self.start.to_css(dest)?; - if self.end != self.start { - dest.write_char(' ')?; - self.end.to_css(dest)?; - } - Ok(()) - } -} - -impl Default for ViewTimelineInset { - fn default() -> Self { - Self { - start: GenericLengthPercentageOrAuto::auto(), - end: GenericLengthPercentageOrAuto::auto(), - } - } -} diff --git a/components/style/values/specified/animation.rs b/components/style/values/specified/animation.rs new file mode 100644 index 00000000000..de1db576151 --- /dev/null +++ b/components/style/values/specified/animation.rs @@ -0,0 +1,355 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Specified types for properties related to animations and transitions. + +use crate::custom_properties::Name as CustomPropertyName; +use crate::parser::{Parse, ParserContext}; +use crate::properties::{LonghandId, PropertyDeclarationId, PropertyId, ShorthandId}; +use crate::values::generics::animation as generics; +use crate::values::specified::{LengthPercentage, NonNegativeNumber}; +use crate::values::{CustomIdent, KeyframesName, TimelineName}; +use crate::Atom; +use cssparser::Parser; +use std::fmt::{self, Write}; +use style_traits::{CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, ToCss}; + +/// 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, ToResolvedValue, ToShmem, +)] +pub enum TransitionProperty { + /// A shorthand. + Shorthand(ShorthandId), + /// A longhand transitionable property. + Longhand(LonghandId), + /// A custom property. + Custom(CustomPropertyName), + /// 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 crate::values::serialize_atom_name; + 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_name(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_ignoring_rule_type(&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 { + Ok(match *self { + TransitionProperty::Shorthand(ShorthandId::All) => { + crate::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(()), + }) + } +} + +/// https://drafts.csswg.org/css-animations/#animation-iteration-count +#[derive(Clone, Debug, MallocSizeOf, PartialEq, Parse, SpecifiedValueInfo, ToCss, ToShmem)] +pub enum AnimationIterationCount { + /// A `` value. + Number(NonNegativeNumber), + /// The `infinite` keyword. + Infinite, +} + +impl AnimationIterationCount { + /// Returns the value `1.0`. + #[inline] + pub fn one() -> Self { + Self::Number(NonNegativeNumber::new(1.0)) + } +} + +/// A value for the `animation-name` property. +#[derive( + Clone, + Debug, + Eq, + Hash, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[value_info(other_values = "none")] +#[repr(C)] +pub struct AnimationName(pub KeyframesName); + +impl AnimationName { + /// Get the name of the animation as an `Atom`. + pub fn as_atom(&self) -> Option<&Atom> { + if self.is_none() { + return None; + } + Some(self.0.as_atom()) + } + + /// Returns the `none` value. + pub fn none() -> Self { + AnimationName(KeyframesName::none()) + } + + /// Returns whether this is the none value. + pub fn is_none(&self) -> bool { + self.0.is_none() + } +} + +impl Parse for AnimationName { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + if let Ok(name) = input.try_parse(|input| KeyframesName::parse(context, input)) { + return Ok(AnimationName(name)); + } + + input.expect_ident_matching("none")?; + Ok(AnimationName(KeyframesName::none())) + } +} + +/// A value for the used in scroll(). +/// +/// https://drafts.csswg.org/scroll-animations-1/rewrite#typedef-scroller +#[derive( + Clone, + Debug, + Eq, + Hash, + MallocSizeOf, + Parse, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(u8)] +pub enum Scroller { + /// The nearest ancestor scroll container. (Default.) + Nearest, + /// The document viewport as the scroll container. + Root, + // FIXME: Bug 1764450: Once we support container-name CSS property (Bug 1744224), we may add + // here, based on the result of the spec issue: + // https://github.com/w3c/csswg-drafts/issues/7046 +} + +impl Default for Scroller { + fn default() -> Self { + Self::Nearest + } +} + +/// A value for the used in scroll(), or a value for {scroll|view}-timeline-axis. +/// +/// https://drafts.csswg.org/scroll-animations-1/#typedef-axis +/// https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-axis +/// https://drafts.csswg.org/scroll-animations-1/#view-timeline-axis +#[derive( + Clone, + Debug, + Eq, + Hash, + MallocSizeOf, + Parse, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(u8)] +pub enum ScrollAxis { + /// The block axis of the scroll container. (Default.) + Block = 0, + /// The inline axis of the scroll container. + Inline = 1, + /// The vertical block axis of the scroll container. + Vertical = 2, + /// The horizontal axis of the scroll container. + Horizontal = 3, +} + +impl Default for ScrollAxis { + fn default() -> Self { + Self::Block + } +} + +#[inline] +fn is_default(value: &T) -> bool { + *value == Default::default() +} + +/// A value for the . +/// +/// https://drafts.csswg.org/css-animations-2/#typedef-single-animation-timeline +#[derive( + Clone, + Debug, + Eq, + Hash, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(C, u8)] +pub enum AnimationTimeline { + /// Use default timeline. The animation’s timeline is a DocumentTimeline. + Auto, + /// The scroll-timeline name or view-timeline-name. + /// https://drafts.csswg.org/scroll-animations-1/#scroll-timelines-named + /// https://drafts.csswg.org/scroll-animations-1/#view-timeline-name + Timeline(TimelineName), + /// The scroll() notation. + /// https://drafts.csswg.org/scroll-animations-1/#scroll-notation + #[css(function)] + Scroll( + #[css(skip_if = "is_default")] ScrollAxis, + #[css(skip_if = "is_default")] Scroller, + ), +} + +impl AnimationTimeline { + /// Returns the `auto` value. + pub fn auto() -> Self { + Self::Auto + } + + /// Returns true if it is auto (i.e. the default value). + pub fn is_auto(&self) -> bool { + matches!(self, Self::Auto) + } +} + +impl Parse for AnimationTimeline { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() { + return Ok(Self::Auto); + } + + if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() { + return Ok(AnimationTimeline::Timeline(TimelineName::none())); + } + + // https://drafts.csswg.org/scroll-animations-1/#scroll-notation + if input + .try_parse(|i| i.expect_function_matching("scroll")) + .is_ok() + { + return input.parse_nested_block(|i| { + Ok(Self::Scroll( + i.try_parse(ScrollAxis::parse).unwrap_or(ScrollAxis::Block), + i.try_parse(Scroller::parse).unwrap_or(Scroller::Nearest), + )) + }); + } + + TimelineName::parse(context, input).map(AnimationTimeline::Timeline) + } +} + +/// A value for the scroll-timeline-name or view-timeline-name. +pub type ScrollTimelineName = AnimationName; + +/// A specified value for the `view-timeline-inset` property. +pub type ViewTimelineInset = generics::GenericViewTimelineInset; + +impl Parse for ViewTimelineInset { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + use crate::values::specified::LengthPercentageOrAuto; + + let start = LengthPercentageOrAuto::parse(context, input)?; + let end = match input.try_parse(|input| LengthPercentageOrAuto::parse(context, input)) { + Ok(end) => end, + Err(_) => start.clone(), + }; + + Ok(Self { start, end }) + } +} diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index ea3e8d5b015..cf62f16162a 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -4,18 +4,15 @@ //! Specified types for box properties. -use crate::custom_properties::Name as CustomPropertyName; use crate::parser::{Parse, ParserContext}; -use crate::properties::{LonghandId, PropertyDeclarationId}; -use crate::properties::{PropertyId, ShorthandId}; +use crate::properties::{LonghandId, PropertyDeclarationId, PropertyId}; use crate::values::generics::box_::{ GenericLineClamp, GenericPerspective, GenericContainIntrinsicSize, GenericVerticalAlign, VerticalAlignKeyword, }; use crate::values::specified::length::{LengthPercentage, NonNegativeLength}; -use crate::values::specified::{AllowQuirks, Integer, NonNegativeNumber}; -use crate::values::{CustomIdent, KeyframesName, TimelineName}; -use crate::Atom; +use crate::values::specified::{AllowQuirks, Integer}; +use crate::values::CustomIdent; use cssparser::Parser; use num_traits::FromPrimitive; use std::fmt::{self, Debug, Formatter, Write}; @@ -606,229 +603,6 @@ impl Parse for VerticalAlign { } } -/// https://drafts.csswg.org/css-animations/#animation-iteration-count -#[derive(Clone, Debug, MallocSizeOf, PartialEq, Parse, SpecifiedValueInfo, ToCss, ToShmem)] -pub enum AnimationIterationCount { - /// A `` value. - Number(NonNegativeNumber), - /// The `infinite` keyword. - Infinite, -} - -impl AnimationIterationCount { - /// Returns the value `1.0`. - #[inline] - pub fn one() -> Self { - Self::Number(NonNegativeNumber::new(1.0)) - } -} - -/// A value for the `animation-name` property. -#[derive( - Clone, - Debug, - Eq, - Hash, - MallocSizeOf, - PartialEq, - SpecifiedValueInfo, - ToComputedValue, - ToCss, - ToResolvedValue, - ToShmem, -)] -#[value_info(other_values = "none")] -#[repr(C)] -pub struct AnimationName(pub KeyframesName); - -impl AnimationName { - /// Get the name of the animation as an `Atom`. - pub fn as_atom(&self) -> Option<&Atom> { - if self.is_none() { - return None; - } - Some(self.0.as_atom()) - } - - /// Returns the `none` value. - pub fn none() -> Self { - AnimationName(KeyframesName::none()) - } - - /// Returns whether this is the none value. - pub fn is_none(&self) -> bool { - self.0.is_none() - } -} - -impl Parse for AnimationName { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - if let Ok(name) = input.try_parse(|input| KeyframesName::parse(context, input)) { - return Ok(AnimationName(name)); - } - - input.expect_ident_matching("none")?; - Ok(AnimationName(KeyframesName::none())) - } -} - -/// A value for the used in scroll(). -/// -/// https://drafts.csswg.org/scroll-animations-1/rewrite#typedef-scroller -#[derive( - Clone, - Debug, - Eq, - Hash, - MallocSizeOf, - Parse, - PartialEq, - SpecifiedValueInfo, - ToComputedValue, - ToCss, - ToResolvedValue, - ToShmem, -)] -#[repr(u8)] -pub enum Scroller { - /// The nearest ancestor scroll container. (Default.) - Nearest, - /// The document viewport as the scroll container. - Root, - // FIXME: Bug 1764450: Once we support container-name CSS property (Bug 1744224), we may add - // here, based on the result of the spec issue: - // https://github.com/w3c/csswg-drafts/issues/7046 -} - -impl Default for Scroller { - fn default() -> Self { - Self::Nearest - } -} - -/// A value for the used in scroll(), or a value for {scroll|view}-timeline-axis. -/// -/// https://drafts.csswg.org/scroll-animations-1/#typedef-axis -/// https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-axis -/// https://drafts.csswg.org/scroll-animations-1/#view-timeline-axis -#[derive( - Clone, - Debug, - Eq, - Hash, - MallocSizeOf, - Parse, - PartialEq, - SpecifiedValueInfo, - ToComputedValue, - ToCss, - ToResolvedValue, - ToShmem, -)] -#[repr(u8)] -pub enum ScrollAxis { - /// The block axis of the scroll container. (Default.) - Block = 0, - /// The inline axis of the scroll container. - Inline = 1, - /// The vertical block axis of the scroll container. - Vertical = 2, - /// The horizontal axis of the scroll container. - Horizontal = 3, -} - -impl Default for ScrollAxis { - fn default() -> Self { - Self::Block - } -} - -#[inline] -fn is_default(value: &T) -> bool { - *value == Default::default() -} - -/// A value for the . -/// -/// https://drafts.csswg.org/css-animations-2/#typedef-single-animation-timeline -#[derive( - Clone, - Debug, - Eq, - Hash, - MallocSizeOf, - PartialEq, - SpecifiedValueInfo, - ToComputedValue, - ToCss, - ToResolvedValue, - ToShmem, -)] -#[repr(C, u8)] -pub enum AnimationTimeline { - /// Use default timeline. The animation’s timeline is a DocumentTimeline. - Auto, - /// The scroll-timeline name or view-timeline-name. - /// https://drafts.csswg.org/scroll-animations-1/#scroll-timelines-named - /// https://drafts.csswg.org/scroll-animations-1/#view-timeline-name - Timeline(TimelineName), - /// The scroll() notation. - /// https://drafts.csswg.org/scroll-animations-1/#scroll-notation - #[css(function)] - Scroll( - #[css(skip_if = "is_default")] ScrollAxis, - #[css(skip_if = "is_default")] Scroller, - ), -} - -impl AnimationTimeline { - /// Returns the `auto` value. - pub fn auto() -> Self { - Self::Auto - } - - /// Returns true if it is auto (i.e. the default value). - pub fn is_auto(&self) -> bool { - matches!(self, Self::Auto) - } -} - -impl Parse for AnimationTimeline { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() { - return Ok(Self::Auto); - } - - if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() { - return Ok(AnimationTimeline::Timeline(TimelineName::none())); - } - - // https://drafts.csswg.org/scroll-animations-1/#scroll-notation - if input - .try_parse(|i| i.expect_function_matching("scroll")) - .is_ok() - { - return input.parse_nested_block(|i| { - Ok(Self::Scroll( - i.try_parse(ScrollAxis::parse).unwrap_or(ScrollAxis::Block), - i.try_parse(Scroller::parse).unwrap_or(Scroller::Nearest), - )) - }); - } - - TimelineName::parse(context, input).map(AnimationTimeline::Timeline) - } -} - -/// A value for the scroll-timeline-name or view-timeline-name. -pub type ScrollTimelineName = AnimationName; - /// https://drafts.csswg.org/css-scroll-snap-1/#snap-axis #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] @@ -1501,102 +1275,6 @@ impl Parse for ContainerName { /// A specified value for the `perspective` property. pub type Perspective = GenericPerspective; -/// 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, ToResolvedValue, ToShmem, -)] -pub enum TransitionProperty { - /// A shorthand. - Shorthand(ShorthandId), - /// A longhand transitionable property. - Longhand(LonghandId), - /// A custom property. - Custom(CustomPropertyName), - /// 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 crate::values::serialize_atom_name; - 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_name(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_ignoring_rule_type(&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 { - Ok(match *self { - TransitionProperty::Shorthand(ShorthandId::All) => { - crate::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(()), - }) - } -} - #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 1acf622980c..b0c155a81ab 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -36,22 +36,24 @@ pub use self::basic_shape::FillRule; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderImageRepeat, BorderImageSideWidth}; pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing, BorderStyle}; -pub use self::box_::{AnimationIterationCount, AnimationName, AnimationTimeline, Contain, Display}; pub use self::box_::{Appearance, BreakBetween, BreakWithin, ContainerName, ContainerType}; pub use self::box_::{ Clear, ContainIntrinsicSize, ContentVisibility, Float, LineClamp, Overflow, OverflowAnchor, }; +pub use self::box_::{Contain, Display}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollbarGutter}; -pub use self::box_::{ScrollAxis, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop}; -pub use self::box_::{ScrollSnapStrictness, ScrollSnapType, ScrollTimelineName}; -pub use self::box_::{TouchAction, TransitionProperty, VerticalAlign, WillChange}; -pub use self::color::{Color, ColorOrAuto, ColorPropertyValue, ColorScheme, PrintColorAdjust, ForcedColorAdjust}; +pub use self::box_::{ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop}; +pub use self::box_::{ScrollSnapStrictness, ScrollSnapType}; +pub use self::box_::{TouchAction, VerticalAlign, WillChange}; +pub use self::color::{ + Color, ColorOrAuto, ColorPropertyValue, ColorScheme, ForcedColorAdjust, PrintColorAdjust, +}; pub use self::column::ColumnCount; pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset, CounterSet}; pub use self::easing::TimingFunction; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; pub use self::flex::FlexBasis; -pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontPalette}; +pub use self::font::{FontFamily, FontLanguageOverride, FontPalette, FontStyle}; pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; pub use self::font::{FontSize, FontSizeAdjust, FontSizeKeyword, FontStretch, FontSynthesis}; pub use self::font::{FontVariantAlternates, FontWeight}; @@ -75,10 +77,8 @@ pub use self::outline::OutlineStyle; pub use self::page::{PageName, PageOrientation, PageSize, PageSizeOrientation, PaperSize}; pub use self::percentage::{NonNegativePercentage, Percentage}; pub use self::position::AspectRatio; -pub use self::position::{ - GridAutoFlow, GridTemplateAreas, Position, PositionOrAuto, -}; -pub use self::position::{MasonryAutoFlow, MasonryPlacement, MasonryItemOrder}; +pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, PositionOrAuto}; +pub use self::position::{MasonryAutoFlow, MasonryItemOrder, MasonryPlacement}; pub use self::position::{PositionComponent, ZIndex}; pub use self::ratio::Ratio; pub use self::rect::NonNegativeLengthOrNumberRect; @@ -100,12 +100,15 @@ pub use self::transform::{Rotate, Scale, Transform}; pub use self::transform::{TransformOrigin, TransformStyle, Translate}; #[cfg(feature = "gecko")] pub use self::ui::CursorImage; -pub use self::ui::{BoolInteger, Cursor, UserSelect, ViewTimelineInset}; +pub use self::ui::{BoolInteger, Cursor, UserSelect}; +pub use self::animation::{AnimationIterationCount, AnimationName, AnimationTimeline}; +pub use self::animation::{ScrollAxis, ScrollTimelineName, TransitionProperty, ViewTimelineInset}; pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; #[cfg(feature = "gecko")] pub mod align; pub mod angle; +pub mod animation; pub mod background; pub mod basic_shape; pub mod border; diff --git a/components/style/values/specified/ui.rs b/components/style/values/specified/ui.rs index c6af7353286..0c656faab20 100644 --- a/components/style/values/specified/ui.rs +++ b/components/style/values/specified/ui.rs @@ -8,7 +8,7 @@ use crate::parser::{Parse, ParserContext}; use crate::values::generics::ui as generics; use crate::values::specified::color::Color; use crate::values::specified::image::Image; -use crate::values::specified::{LengthPercentage, Number}; +use crate::values::specified::Number; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{ @@ -230,23 +230,3 @@ pub enum CursorKind { ZoomOut, Auto, } - -/// A specified value for the `view-timeline-inset` property. -pub type ViewTimelineInset = generics::GenericViewTimelineInset; - -impl Parse for ViewTimelineInset { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - use crate::values::specified::LengthPercentageOrAuto; - - let start = LengthPercentageOrAuto::parse(context, input)?; - let end = match input.try_parse(|input| LengthPercentageOrAuto::parse(context, input)) { - Ok(end) => end, - Err(_) => start.clone(), - }; - - Ok(Self { start, end }) - } -}