style/values/generics/
animation.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Generic values for properties related to animations and transitions.
6
7use crate::values::generics::length::GenericLengthPercentageOrAuto;
8use crate::values::specified::animation::{ScrollAxis, ScrollFunction, TimelineName};
9use crate::Zero;
10use std::fmt::{self, Write};
11use style_traits::{CssWriter, ToCss};
12
13/// The `animation-duration` property.
14///
15/// https://drafts.csswg.org/css-animations-2/#animation-duration
16#[derive(
17    Clone,
18    Copy,
19    Debug,
20    MallocSizeOf,
21    PartialEq,
22    SpecifiedValueInfo,
23    ToComputedValue,
24    ToShmem,
25)]
26#[repr(C, u8)]
27pub enum GenericAnimationDuration<T> {
28    /// The initial value. However, we serialize this as 0s if the preference is disabled.
29    Auto,
30    /// The time value, <time [0s,∞]>.
31    Time(T),
32}
33
34pub use self::GenericAnimationDuration as AnimationDuration;
35
36impl<T> AnimationDuration<T> {
37    /// Returns the `auto` value.
38    pub fn auto() -> Self {
39        Self::Auto
40    }
41
42    /// Returns true if it is `auto`.
43    pub fn is_auto(&self) -> bool {
44        matches!(*self, Self::Auto)
45    }
46}
47
48impl<T: Zero> Zero for AnimationDuration<T> {
49    fn zero() -> Self {
50        Self::Time(T::zero())
51    }
52
53    fn is_zero(&self) -> bool {
54        match *self {
55            Self::Time(ref t) => t.is_zero(),
56            _ => false,
57        }
58    }
59}
60
61impl<T: ToCss + Zero> ToCss for AnimationDuration<T> {
62    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
63    where
64        W: Write,
65    {
66        match *self {
67            Self::Auto => {
68                if static_prefs::pref!("layout.css.scroll-driven-animations.enabled") {
69                    dest.write_str("auto")
70                } else {
71                    Self::Time(T::zero()).to_css(dest)
72                }
73            },
74            Self::Time(ref t) => t.to_css(dest),
75        }
76    }
77}
78
79/// The view() notation.
80/// https://drafts.csswg.org/scroll-animations-1/#view-notation
81#[derive(
82    Clone,
83    Debug,
84    MallocSizeOf,
85    PartialEq,
86    SpecifiedValueInfo,
87    ToComputedValue,
88    ToCss,
89    ToResolvedValue,
90    ToShmem,
91)]
92#[css(function = "view")]
93#[repr(C)]
94pub struct GenericViewFunction<LengthPercent> {
95    /// The axis of scrolling that drives the progress of the timeline.
96    #[css(skip_if = "ScrollAxis::is_default")]
97    pub axis: ScrollAxis,
98    /// An adjustment of the view progress visibility range.
99    #[css(skip_if = "GenericViewTimelineInset::is_auto")]
100    #[css(field_bound)]
101    pub inset: GenericViewTimelineInset<LengthPercent>,
102}
103
104pub use self::GenericViewFunction as ViewFunction;
105
106/// A value for the <single-animation-timeline>.
107///
108/// https://drafts.csswg.org/css-animations-2/#typedef-single-animation-timeline
109#[derive(
110    Clone,
111    Debug,
112    MallocSizeOf,
113    PartialEq,
114    SpecifiedValueInfo,
115    ToComputedValue,
116    ToCss,
117    ToResolvedValue,
118    ToShmem,
119)]
120#[repr(C, u8)]
121pub enum GenericAnimationTimeline<LengthPercent> {
122    /// Use default timeline. The animation’s timeline is a DocumentTimeline.
123    Auto,
124    /// The scroll-timeline name or view-timeline-name.
125    /// This also includes `none` value by using an empty atom.
126    /// https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-name
127    /// https://drafts.csswg.org/scroll-animations-1/#view-timeline-name
128    Timeline(TimelineName),
129    /// The scroll() notation.
130    /// https://drafts.csswg.org/scroll-animations-1/#scroll-notation
131    Scroll(ScrollFunction),
132    /// The view() notation.
133    /// https://drafts.csswg.org/scroll-animations-1/#view-notation
134    View(#[css(field_bound)] GenericViewFunction<LengthPercent>),
135}
136
137pub use self::GenericAnimationTimeline as AnimationTimeline;
138
139impl<LengthPercent> AnimationTimeline<LengthPercent> {
140    /// Returns the `auto` value.
141    pub fn auto() -> Self {
142        Self::Auto
143    }
144
145    /// Returns true if it is auto (i.e. the default value).
146    pub fn is_auto(&self) -> bool {
147        matches!(self, Self::Auto)
148    }
149}
150
151/// A generic value for the `[ [ auto | <length-percentage> ]{1,2} ]`.
152///
153/// https://drafts.csswg.org/scroll-animations-1/#view-timeline-inset
154#[derive(
155    Clone,
156    Copy,
157    Debug,
158    MallocSizeOf,
159    PartialEq,
160    SpecifiedValueInfo,
161    ToComputedValue,
162    ToResolvedValue,
163    ToShmem,
164)]
165#[repr(C)]
166pub struct GenericViewTimelineInset<LengthPercent> {
167    /// The start inset in the relevant axis.
168    pub start: GenericLengthPercentageOrAuto<LengthPercent>,
169    /// The end inset.
170    pub end: GenericLengthPercentageOrAuto<LengthPercent>,
171}
172
173pub use self::GenericViewTimelineInset as ViewTimelineInset;
174
175impl<LengthPercent> ViewTimelineInset<LengthPercent> {
176    /// Returns true if it is auto.
177    #[inline]
178    fn is_auto(&self) -> bool {
179        self.start.is_auto() && self.end.is_auto()
180    }
181}
182
183impl<LengthPercent> ToCss for ViewTimelineInset<LengthPercent>
184where
185    LengthPercent: PartialEq + ToCss,
186{
187    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
188    where
189        W: Write,
190    {
191        self.start.to_css(dest)?;
192        if self.end != self.start {
193            dest.write_char(' ')?;
194            self.end.to_css(dest)?;
195        }
196        Ok(())
197    }
198}
199
200impl<LengthPercent> Default for ViewTimelineInset<LengthPercent> {
201    fn default() -> Self {
202        Self {
203            start: GenericLengthPercentageOrAuto::auto(),
204            end: GenericLengthPercentageOrAuto::auto(),
205        }
206    }
207}