1use crate::derives::*;
8use crate::values::generics::length::GenericLengthPercentageOrAuto;
9use crate::values::generics::Optional;
10use crate::values::specified::animation::{
11 ScrollAxis, ScrollFunction, TimelineName, TimelineRangeName,
12};
13use crate::values::specified::length::EqualsPercentage;
14use crate::Zero;
15use std::fmt::{self, Write};
16use style_traits::{CssWriter, ToCss};
17
18#[derive(
22 Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
23)]
24#[repr(C, u8)]
25pub enum GenericAnimationDuration<T> {
26 Auto,
28 Time(T),
30}
31
32pub use self::GenericAnimationDuration as AnimationDuration;
33
34impl<T> AnimationDuration<T> {
35 pub fn auto() -> Self {
37 Self::Auto
38 }
39
40 pub fn is_auto(&self) -> bool {
42 matches!(*self, Self::Auto)
43 }
44}
45
46impl<T: Zero> Zero for AnimationDuration<T> {
47 fn zero() -> Self {
48 Self::Time(T::zero())
49 }
50
51 fn is_zero(&self) -> bool {
52 match *self {
53 Self::Time(ref t) => t.is_zero(),
54 _ => false,
55 }
56 }
57}
58
59impl<T: ToCss + Zero> ToCss for AnimationDuration<T> {
60 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
61 where
62 W: Write,
63 {
64 match *self {
65 Self::Auto => {
66 if static_prefs::pref!("layout.css.scroll-driven-animations.enabled") {
67 dest.write_str("auto")
68 } else {
69 Self::Time(T::zero()).to_css(dest)
70 }
71 },
72 Self::Time(ref t) => t.to_css(dest),
73 }
74 }
75}
76
77#[derive(
80 Clone,
81 Debug,
82 MallocSizeOf,
83 PartialEq,
84 SpecifiedValueInfo,
85 ToComputedValue,
86 ToCss,
87 ToResolvedValue,
88 ToShmem,
89)]
90#[css(function = "view")]
91#[repr(C)]
92pub struct GenericViewFunction<LengthPercent> {
93 #[css(skip_if = "ScrollAxis::is_default")]
95 pub axis: ScrollAxis,
96 #[css(skip_if = "GenericViewTimelineInset::is_auto")]
98 #[css(field_bound)]
99 pub inset: GenericViewTimelineInset<LengthPercent>,
100}
101
102pub use self::GenericViewFunction as ViewFunction;
103
104#[derive(
108 Clone,
109 Debug,
110 MallocSizeOf,
111 PartialEq,
112 SpecifiedValueInfo,
113 ToComputedValue,
114 ToCss,
115 ToResolvedValue,
116 ToShmem,
117)]
118#[repr(C, u8)]
119pub enum GenericAnimationTimeline<LengthPercent> {
120 Auto,
122 Timeline(TimelineName),
127 Scroll(ScrollFunction),
130 View(#[css(field_bound)] GenericViewFunction<LengthPercent>),
133}
134
135pub use self::GenericAnimationTimeline as AnimationTimeline;
136
137impl<LengthPercent> AnimationTimeline<LengthPercent> {
138 pub fn auto() -> Self {
140 Self::Auto
141 }
142
143 pub fn is_auto(&self) -> bool {
145 matches!(self, Self::Auto)
146 }
147}
148
149#[derive(
153 Clone,
154 Copy,
155 Debug,
156 MallocSizeOf,
157 PartialEq,
158 SpecifiedValueInfo,
159 ToComputedValue,
160 ToResolvedValue,
161 ToShmem,
162)]
163#[repr(C)]
164pub struct GenericViewTimelineInset<LengthPercent> {
165 pub start: GenericLengthPercentageOrAuto<LengthPercent>,
167 pub end: GenericLengthPercentageOrAuto<LengthPercent>,
169}
170
171pub use self::GenericViewTimelineInset as ViewTimelineInset;
172
173impl<LengthPercent> ViewTimelineInset<LengthPercent> {
174 #[inline]
176 fn is_auto(&self) -> bool {
177 self.start.is_auto() && self.end.is_auto()
178 }
179}
180
181impl<LengthPercent> ToCss for ViewTimelineInset<LengthPercent>
182where
183 LengthPercent: PartialEq + ToCss,
184{
185 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
186 where
187 W: Write,
188 {
189 self.start.to_css(dest)?;
190 if self.end != self.start {
191 dest.write_char(' ')?;
192 self.end.to_css(dest)?;
193 }
194 Ok(())
195 }
196}
197
198impl<LengthPercent> Default for ViewTimelineInset<LengthPercent> {
199 fn default() -> Self {
200 Self {
201 start: GenericLengthPercentageOrAuto::auto(),
202 end: GenericLengthPercentageOrAuto::auto(),
203 }
204 }
205}
206
207#[derive(
212 Clone,
213 Debug,
214 MallocSizeOf,
215 PartialEq,
216 SpecifiedValueInfo,
217 ToComputedValue,
218 ToResolvedValue,
219 ToShmem,
220)]
221#[repr(C)]
222pub struct GenericAnimationRangeValue<LengthPercent> {
223 pub name: TimelineRangeName,
226 pub lp: Optional<LengthPercent>,
229}
230
231pub use self::GenericAnimationRangeValue as AnimationRangeValue;
232
233impl<LengthPercent> Default for AnimationRangeValue<LengthPercent> {
234 fn default() -> Self {
235 Self {
236 name: TimelineRangeName::None,
237 lp: Optional::None,
238 }
239 }
240}
241
242impl<LengthPercent> AnimationRangeValue<LengthPercent> {
243 #[inline]
245 pub fn length_percentage(lp: LengthPercent) -> Self {
246 Self {
247 name: TimelineRangeName::None,
248 lp: Optional::Some(lp),
249 }
250 }
251
252 #[inline]
254 pub fn timeline_range(name: TimelineRangeName, lp: LengthPercent) -> Self {
255 Self {
256 name,
257 lp: Optional::Some(lp),
258 }
259 }
260}
261
262#[derive(
266 Clone,
267 Debug,
268 MallocSizeOf,
269 PartialEq,
270 SpecifiedValueInfo,
271 ToComputedValue,
272 ToResolvedValue,
273 ToShmem,
274)]
275#[repr(C)]
276pub struct GenericAnimationRangeStart<LengthPercent>(pub GenericAnimationRangeValue<LengthPercent>);
277
278pub use self::GenericAnimationRangeStart as AnimationRangeStart;
279
280impl<LengthPercent> Default for AnimationRangeStart<LengthPercent> {
281 fn default() -> Self {
282 Self(AnimationRangeValue::default())
283 }
284}
285
286fn to_css_with_default<LengthPercent, W>(
287 value: &AnimationRangeValue<LengthPercent>,
288 dest: &mut CssWriter<W>,
289 default: crate::values::CSSFloat,
290) -> fmt::Result
291where
292 LengthPercent: ToCss + EqualsPercentage,
293 W: Write,
294{
295 if matches!(value.name, TimelineRangeName::None) {
296 return match value.lp {
297 Optional::None => dest.write_str("normal"),
299 Optional::Some(ref lp) => lp.to_css(dest),
301 };
302 }
303
304 value.name.to_css(dest)?;
306 match value.lp {
307 Optional::Some(ref lp) if !lp.equals_percentage(default) => {
308 dest.write_char(' ')?;
309 lp.to_css(dest)
310 },
311 _ => Ok(()),
312 }
313}
314
315impl<LengthPercent: ToCss + EqualsPercentage> ToCss for AnimationRangeStart<LengthPercent> {
316 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
317 where
318 W: Write,
319 {
320 to_css_with_default(&self.0, dest, 0.0)
321 }
322}
323
324#[derive(
328 Clone,
329 Debug,
330 MallocSizeOf,
331 PartialEq,
332 SpecifiedValueInfo,
333 ToComputedValue,
334 ToResolvedValue,
335 ToShmem,
336)]
337#[repr(C)]
338pub struct GenericAnimationRangeEnd<LengthPercent>(pub GenericAnimationRangeValue<LengthPercent>);
339
340pub use self::GenericAnimationRangeEnd as AnimationRangeEnd;
341
342impl<LengthPercent> Default for AnimationRangeEnd<LengthPercent> {
343 fn default() -> Self {
344 Self(AnimationRangeValue::default())
345 }
346}
347
348impl<LengthPercent: ToCss + EqualsPercentage> ToCss for AnimationRangeEnd<LengthPercent> {
349 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
350 where
351 W: Write,
352 {
353 to_css_with_default(&self.0, dest, 1.0)
354 }
355}