1use super::prelude::*;
2use crate::{AngleOrZero, CalcableValue, Length, LengthPercentage, NoneOr, NumberOrPercentage, NumericValue};
3use css_parse::Box;
4
5#[node]
7#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
9#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
10#[derive(csskit_derives::NodeWithMetadata)]
11pub enum TransformFunction<'a> {
12 Matrix(Box<'a, MatrixFunction<'a>>),
13 Matrix3d(Box<'a, Matrix3dFunction<'a>>),
14 Translate(TranslateFunction<'a>),
15 Translate3d(Translate3dFunction<'a>),
16 TranslateX(TranslatexFunction<'a>),
17 TranslateY(TranslateyFunction<'a>),
18 TranslateZ(TranslatezFunction<'a>),
19 Scale(ScaleFunction<'a>),
20 Scale3d(Scale3dFunction<'a>),
21 ScaleX(ScalexFunction<'a>),
22 ScaleY(ScaleyFunction<'a>),
23 ScaleZ(ScalezFunction<'a>),
24 Rotate(RotateFunction<'a>),
25 Rotate3d(Rotate3dFunction<'a>),
26 RotateX(RotatexFunction<'a>),
27 RotateY(RotateyFunction<'a>),
28 RotateZ(RotatezFunction<'a>),
29 Skew(SkewFunction<'a>),
30 SkewX(SkewxFunction<'a>),
31 SkewY(SkewyFunction<'a>),
32 Perspective(PerspectiveFunction<'a>),
33}
34
35#[node]
41#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
43#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
44#[derive(csskit_derives::NodeWithMetadata)]
45pub struct MatrixFunction<'a> {
46 #[atom(CssAtomSet::Matrix)]
47 pub name: T![Function],
48 pub params: MatrixFunctionParams<'a>,
49 #[semantic_eq(skip)]
50 pub close: T![')'],
51}
52
53#[node]
54#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
55#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
56#[derive(csskit_derives::NodeWithMetadata)]
57pub struct MatrixFunctionParams<'a>(
58 pub NumericValue<'a, T![Number]>,
59 #[semantic_eq(skip)] pub Option<T![,]>,
60 pub NumericValue<'a, T![Number]>,
61 #[semantic_eq(skip)] pub Option<T![,]>,
62 pub NumericValue<'a, T![Number]>,
63 #[semantic_eq(skip)] pub Option<T![,]>,
64 pub NumericValue<'a, T![Number]>,
65 #[semantic_eq(skip)] pub Option<T![,]>,
66 pub NumericValue<'a, T![Number]>,
67 #[semantic_eq(skip)] pub Option<T![,]>,
68 pub NumericValue<'a, T![Number]>,
69);
70
71#[node]
77#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
78#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
79#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
80#[derive(csskit_derives::NodeWithMetadata)]
81pub struct Matrix3dFunction<'a> {
82 #[atom(CssAtomSet::Matrix3d)]
83 pub name: T![Function],
84 pub params: Matrix3dFunctionParams<'a>,
85 #[semantic_eq(skip)]
86 pub close: T![')'],
87}
88
89#[node]
90#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
91#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
92#[allow(clippy::type_complexity)] #[derive(csskit_derives::NodeWithMetadata)]
94pub struct Matrix3dFunctionParams<'a>(
95 pub NumericValue<'a, T![Number]>,
96 #[semantic_eq(skip)] pub Option<T![,]>,
97 pub NumericValue<'a, T![Number]>,
98 #[semantic_eq(skip)] pub Option<T![,]>,
99 pub NumericValue<'a, T![Number]>,
100 #[semantic_eq(skip)] pub Option<T![,]>,
101 pub NumericValue<'a, T![Number]>,
102 #[semantic_eq(skip)] pub Option<T![,]>,
103 pub NumericValue<'a, T![Number]>,
104 #[semantic_eq(skip)] pub Option<T![,]>,
105 pub NumericValue<'a, T![Number]>,
106 #[semantic_eq(skip)] pub Option<T![,]>,
107 pub NumericValue<'a, T![Number]>,
108 #[semantic_eq(skip)] pub Option<T![,]>,
109 pub NumericValue<'a, T![Number]>,
110 #[semantic_eq(skip)] pub Option<T![,]>,
111 pub NumericValue<'a, T![Number]>,
112 #[semantic_eq(skip)] pub Option<T![,]>,
113 pub NumericValue<'a, T![Number]>,
114 #[semantic_eq(skip)] pub Option<T![,]>,
115 pub NumericValue<'a, T![Number]>,
116 #[semantic_eq(skip)] pub Option<T![,]>,
117 pub NumericValue<'a, T![Number]>,
118 #[semantic_eq(skip)] pub Option<T![,]>,
119 pub NumericValue<'a, T![Number]>,
120 #[semantic_eq(skip)] pub Option<T![,]>,
121 pub NumericValue<'a, T![Number]>,
122 #[semantic_eq(skip)] pub Option<T![,]>,
123 pub NumericValue<'a, T![Number]>,
124 #[semantic_eq(skip)] pub Option<T![,]>,
125 pub NumericValue<'a, T![Number]>,
126);
127
128#[node]
134#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
135#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
136#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
137#[derive(csskit_derives::NodeWithMetadata)]
138pub struct TranslateFunction<'a> {
139 #[atom(CssAtomSet::Translate)]
140 pub name: T![Function],
141 pub x: CalcableValue<'a, LengthPercentage>,
142 #[semantic_eq(skip)]
143 pub comma: Option<T![,]>,
144 pub y: Option<CalcableValue<'a, LengthPercentage>>,
145 #[semantic_eq(skip)]
146 pub close: T![')'],
147}
148
149#[node]
155#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
156#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
157#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
158#[derive(csskit_derives::NodeWithMetadata)]
159pub struct Translate3dFunction<'a> {
160 #[atom(CssAtomSet::Translate3d)]
161 pub name: T![Function],
162 pub params: Translate3dFunctionParams<'a>,
163 #[semantic_eq(skip)]
164 pub close: T![')'],
165}
166
167#[node]
168#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
169#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
170#[derive(csskit_derives::NodeWithMetadata)]
171pub struct Translate3dFunctionParams<'a>(
172 pub CalcableValue<'a, LengthPercentage>,
173 #[semantic_eq(skip)] pub Option<T![,]>,
174 pub CalcableValue<'a, LengthPercentage>,
175 #[semantic_eq(skip)] pub Option<T![,]>,
176 pub CalcableValue<'a, Length>,
177);
178
179#[node]
185#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
186#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
187#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
188#[derive(csskit_derives::NodeWithMetadata)]
189pub struct TranslatexFunction<'a> {
190 #[atom(CssAtomSet::Translatex)]
191 pub name: T![Function],
192 pub params: CalcableValue<'a, LengthPercentage>,
193 #[semantic_eq(skip)]
194 pub close: T![')'],
195}
196
197#[node]
203#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
204#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
205#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
206#[derive(csskit_derives::NodeWithMetadata)]
207pub struct TranslateyFunction<'a> {
208 #[atom(CssAtomSet::Translatey)]
209 pub name: T![Function],
210 pub params: CalcableValue<'a, LengthPercentage>,
211 #[semantic_eq(skip)]
212 pub close: T![')'],
213}
214
215#[node]
221#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
222#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
223#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
224#[derive(csskit_derives::NodeWithMetadata)]
225pub struct TranslatezFunction<'a> {
226 #[atom(CssAtomSet::Translatez)]
227 pub name: T![Function],
228 pub params: CalcableValue<'a, Length>,
229 #[semantic_eq(skip)]
230 pub close: T![')'],
231}
232
233#[node]
239#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
240#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
241#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
242#[derive(csskit_derives::NodeWithMetadata)]
243pub struct ScaleFunction<'a> {
244 #[atom(CssAtomSet::Scale)]
245 pub name: T![Function],
246 #[semantic_eq(skip)]
247 pub params: (NumericValue<'a, NumberOrPercentage>, Option<T![,]>, Option<NumericValue<'a, NumberOrPercentage>>),
248 #[semantic_eq(skip)]
249 pub close: T![')'],
250}
251
252#[node]
258#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
259#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
260#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
261#[derive(csskit_derives::NodeWithMetadata)]
262pub struct Scale3dFunction<'a> {
263 #[atom(CssAtomSet::Scale3d)]
264 pub name: T![Function],
265 pub params: Scale3dFunctionParams<'a>,
266 #[semantic_eq(skip)]
267 pub close: T![')'],
268}
269
270#[node]
271#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
272#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
273#[derive(csskit_derives::NodeWithMetadata)]
274pub struct Scale3dFunctionParams<'a>(
275 pub NumericValue<'a, NumberOrPercentage>,
276 #[semantic_eq(skip)] pub Option<T![,]>,
277 pub NumericValue<'a, NumberOrPercentage>,
278 #[semantic_eq(skip)] pub Option<T![,]>,
279 pub NumericValue<'a, NumberOrPercentage>,
280);
281
282#[node]
288#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
289#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
290#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
291#[derive(csskit_derives::NodeWithMetadata)]
292pub struct ScalexFunction<'a> {
293 #[atom(CssAtomSet::Scalex)]
294 pub name: T![Function],
295 pub params: NumericValue<'a, NumberOrPercentage>,
296 #[semantic_eq(skip)]
297 pub close: T![')'],
298}
299
300#[node]
306#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
307#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
308#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
309#[derive(csskit_derives::NodeWithMetadata)]
310pub struct ScaleyFunction<'a> {
311 #[atom(CssAtomSet::Scaley)]
312 pub name: T![Function],
313 pub params: NumericValue<'a, NumberOrPercentage>,
314 #[semantic_eq(skip)]
315 pub close: T![')'],
316}
317
318#[node]
324#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
325#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
326#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
327#[derive(csskit_derives::NodeWithMetadata)]
328pub struct ScalezFunction<'a> {
329 #[atom(CssAtomSet::Scalez)]
330 pub name: T![Function],
331 pub params: NumericValue<'a, NumberOrPercentage>,
332 #[semantic_eq(skip)]
333 pub close: T![')'],
334}
335
336#[node]
342#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
343#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
344#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
345#[derive(csskit_derives::NodeWithMetadata)]
346pub struct RotateFunction<'a> {
347 #[atom(CssAtomSet::Rotate)]
348 pub name: T![Function],
349 pub params: CalcableValue<'a, AngleOrZero>,
350 #[semantic_eq(skip)]
351 pub close: T![')'],
352}
353
354#[node]
360#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
361#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
362#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
363#[derive(csskit_derives::NodeWithMetadata)]
364pub struct Rotate3dFunction<'a> {
365 #[atom(CssAtomSet::Rotate3d)]
366 pub name: T![Function],
367 pub params: Rotate3dFunctionParams<'a>,
368 #[semantic_eq(skip)]
369 pub close: T![')'],
370}
371
372#[node]
373#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
374#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
375#[derive(csskit_derives::NodeWithMetadata)]
376pub struct Rotate3dFunctionParams<'a>(
377 pub NumericValue<'a, T![Number]>,
378 #[semantic_eq(skip)] pub Option<T![,]>,
379 pub NumericValue<'a, T![Number]>,
380 #[semantic_eq(skip)] pub Option<T![,]>,
381 pub NumericValue<'a, T![Number]>,
382 #[semantic_eq(skip)] pub Option<T![,]>,
383 pub CalcableValue<'a, AngleOrZero>,
384);
385
386#[node]
392#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
393#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
394#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
395#[derive(csskit_derives::NodeWithMetadata)]
396pub struct RotatexFunction<'a> {
397 #[atom(CssAtomSet::Rotatex)]
398 pub name: T![Function],
399 pub params: CalcableValue<'a, AngleOrZero>,
400 #[semantic_eq(skip)]
401 pub close: T![')'],
402}
403
404#[node]
410#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
411#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
412#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
413#[derive(csskit_derives::NodeWithMetadata)]
414pub struct RotateyFunction<'a> {
415 #[atom(CssAtomSet::Rotatey)]
416 pub name: T![Function],
417 pub params: CalcableValue<'a, AngleOrZero>,
418 #[semantic_eq(skip)]
419 pub close: T![')'],
420}
421
422#[node]
428#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
429#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
430#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
431#[derive(csskit_derives::NodeWithMetadata)]
432pub struct RotatezFunction<'a> {
433 #[atom(CssAtomSet::Rotatez)]
434 pub name: T![Function],
435 pub params: CalcableValue<'a, AngleOrZero>,
436 #[semantic_eq(skip)]
437 pub close: T![')'],
438}
439
440#[node]
446#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
447#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
448#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
449#[derive(csskit_derives::NodeWithMetadata)]
450pub struct SkewFunction<'a> {
451 #[atom(CssAtomSet::Skew)]
452 pub name: T![Function],
453 #[semantic_eq(skip)]
454 pub params: (CalcableValue<'a, AngleOrZero>, Option<T![,]>, Option<CalcableValue<'a, AngleOrZero>>),
455 #[semantic_eq(skip)]
456 pub close: T![')'],
457}
458
459#[node]
465#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
466#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
467#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
468#[derive(csskit_derives::NodeWithMetadata)]
469pub struct SkewxFunction<'a> {
470 #[atom(CssAtomSet::Skewx)]
471 pub name: T![Function],
472 pub params: CalcableValue<'a, AngleOrZero>,
473 #[semantic_eq(skip)]
474 pub close: T![')'],
475}
476
477#[node]
483#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
484#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
485#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
486#[derive(csskit_derives::NodeWithMetadata)]
487pub struct SkewyFunction<'a> {
488 #[atom(CssAtomSet::Skewy)]
489 pub name: T![Function],
490 pub params: CalcableValue<'a, AngleOrZero>,
491 #[semantic_eq(skip)]
492 pub close: T![')'],
493}
494
495#[node]
501#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
502#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
503#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
504#[derive(csskit_derives::NodeWithMetadata)]
505pub struct PerspectiveFunction<'a> {
506 #[atom(CssAtomSet::Perspective)]
507 pub name: T![Function],
508 pub params: NoneOr<CalcableValue<'a, Length>>,
509 #[semantic_eq(skip)]
510 pub close: T![')'],
511}
512
513#[cfg(test)]
514mod tests {
515 use super::*;
516 use crate::CssAtomSet;
517 use css_parse::{assert_parse, assert_parse_error, assert_parse_span};
518
519 #[test]
520 fn test_writes() {
521 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1,2,3,4,5,6)");
522 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1 2 3 4 5 6)");
523 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(0,0,0,0,0,0)");
524 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(-1,-2,-3,-4,-5,-6)");
525 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1.5,2.5,3.5,4.5,5.5,6.5)");
526
527 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(10px)");
528 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(10px,20px)");
529 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(45%)");
530 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(2rem)");
531 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateX(1rem)");
532 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateY(1rem)");
533
534 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1,2)");
535 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(0,0)");
536 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1)");
537 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1.5,2.5)");
538 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scaleX(2)");
539 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scaleY(2)");
540
541 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(45deg)");
542 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(0)");
543 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(2turn)");
544 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(20rad)");
545
546 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(1deg,2deg)");
547 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(0,0)");
548 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(1deg)");
549 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewX(1deg)");
550 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewX(0)");
551 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewY(1deg)");
552 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewY(0)");
553
554 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale3d(10%,10%,10%)");
555 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate3d(1,2,3,10deg)");
556 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,10,20,30,1)");
557 }
558
559 #[test]
560 fn test_substitution() {
561 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(calc(10px + 5%))");
563 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(var(--x),var(--y))");
564 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateX(calc(1rem * 2))");
565 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateZ(var(--z))");
566 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "perspective(calc(100px))");
567 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(calc(45deg))");
569 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(var(--a))");
570 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(calc(1 + 1),var(--y))");
571 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewX(calc(10deg))");
572 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(calc(1),2,3,4,5,6)");
573 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate3d(1,2,3,var(--a))");
574 }
575
576 #[test]
577 fn test_span() {
578 assert_parse_span!(
579 CssAtomSet::ATOMS,
580 TransformFunction,
581 r#"
582 matrix(1,2,3,4,5,6) translate(0)
583 ^^^^^^^^^^^^^^^^^^^
584 "#
585 );
586 assert_parse_span!(
587 CssAtomSet::ATOMS,
588 TransformFunction,
589 r#"
590 translate(0) foo
591 ^^^^^^^^^^^^
592 "#
593 );
594 assert_parse_span!(
595 CssAtomSet::ATOMS,
596 TranslateFunction,
597 r#"
598 translate(0) bar
599 ^^^^^^^^^^^^
600 "#
601 );
602 }
603
604 #[test]
605 fn test_errors() {
606 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix()");
607 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(1)");
608 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(1,2)");
609 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(one,two,three,four,five,size)");
610
611 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translate()");
612 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translate(foo)");
613 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateX()");
614 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateX(foo)");
615 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateY()");
616 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateY(foo)");
617
618 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scale()");
619 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scale(foo)");
620 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleX()");
621 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleX(foo)");
622 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleY()");
623 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleY(foo)");
624
625 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate()");
626 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate(45px)");
627 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate(all the way around)");
628
629 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skew()");
630 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skew(foo)");
631 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewX()");
632 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewX(foo)");
633 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewY()");
634 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewY(foo)");
635 }
636}