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