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 pub params: (NumericValue<'a, NumberOrPercentage>, Option<T![,]>, Option<NumericValue<'a, NumberOrPercentage>>),
247 #[semantic_eq(skip)]
248 pub close: T![')'],
249}
250
251#[node]
257#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
258#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
259#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
260#[derive(csskit_derives::NodeWithMetadata)]
261pub struct Scale3dFunction<'a> {
262 #[atom(CssAtomSet::Scale3d)]
263 pub name: T![Function],
264 pub params: Scale3dFunctionParams<'a>,
265 #[semantic_eq(skip)]
266 pub close: T![')'],
267}
268
269#[node]
270#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
271#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
272#[derive(csskit_derives::NodeWithMetadata)]
273pub struct Scale3dFunctionParams<'a>(
274 pub NumericValue<'a, NumberOrPercentage>,
275 #[semantic_eq(skip)] pub Option<T![,]>,
276 pub NumericValue<'a, NumberOrPercentage>,
277 #[semantic_eq(skip)] pub Option<T![,]>,
278 pub NumericValue<'a, NumberOrPercentage>,
279);
280
281#[node]
287#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
288#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
289#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
290#[derive(csskit_derives::NodeWithMetadata)]
291pub struct ScalexFunction<'a> {
292 #[atom(CssAtomSet::Scalex)]
293 pub name: T![Function],
294 pub params: NumericValue<'a, NumberOrPercentage>,
295 #[semantic_eq(skip)]
296 pub close: T![')'],
297}
298
299#[node]
305#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
306#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
307#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
308#[derive(csskit_derives::NodeWithMetadata)]
309pub struct ScaleyFunction<'a> {
310 #[atom(CssAtomSet::Scaley)]
311 pub name: T![Function],
312 pub params: NumericValue<'a, NumberOrPercentage>,
313 #[semantic_eq(skip)]
314 pub close: T![')'],
315}
316
317#[node]
323#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
324#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
325#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
326#[derive(csskit_derives::NodeWithMetadata)]
327pub struct ScalezFunction<'a> {
328 #[atom(CssAtomSet::Scalez)]
329 pub name: T![Function],
330 pub params: NumericValue<'a, NumberOrPercentage>,
331 #[semantic_eq(skip)]
332 pub close: T![')'],
333}
334
335#[node]
341#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
342#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
343#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
344#[derive(csskit_derives::NodeWithMetadata)]
345pub struct RotateFunction<'a> {
346 #[atom(CssAtomSet::Rotate)]
347 pub name: T![Function],
348 pub params: CalcableValue<'a, AngleOrZero>,
349 #[semantic_eq(skip)]
350 pub close: T![')'],
351}
352
353#[node]
359#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
360#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
361#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
362#[derive(csskit_derives::NodeWithMetadata)]
363pub struct Rotate3dFunction<'a> {
364 #[atom(CssAtomSet::Rotate3d)]
365 pub name: T![Function],
366 pub params: Rotate3dFunctionParams<'a>,
367 #[semantic_eq(skip)]
368 pub close: T![')'],
369}
370
371#[node]
372#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
373#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
374#[derive(csskit_derives::NodeWithMetadata)]
375pub struct Rotate3dFunctionParams<'a>(
376 pub NumericValue<'a, T![Number]>,
377 #[semantic_eq(skip)] pub Option<T![,]>,
378 pub NumericValue<'a, T![Number]>,
379 #[semantic_eq(skip)] pub Option<T![,]>,
380 pub NumericValue<'a, T![Number]>,
381 #[semantic_eq(skip)] pub Option<T![,]>,
382 pub CalcableValue<'a, AngleOrZero>,
383);
384
385#[node]
391#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
392#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
393#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
394#[derive(csskit_derives::NodeWithMetadata)]
395pub struct RotatexFunction<'a> {
396 #[atom(CssAtomSet::Rotatex)]
397 pub name: T![Function],
398 pub params: CalcableValue<'a, AngleOrZero>,
399 #[semantic_eq(skip)]
400 pub close: T![')'],
401}
402
403#[node]
409#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
410#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
411#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
412#[derive(csskit_derives::NodeWithMetadata)]
413pub struct RotateyFunction<'a> {
414 #[atom(CssAtomSet::Rotatey)]
415 pub name: T![Function],
416 pub params: CalcableValue<'a, AngleOrZero>,
417 #[semantic_eq(skip)]
418 pub close: T![')'],
419}
420
421#[node]
427#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
428#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
429#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
430#[derive(csskit_derives::NodeWithMetadata)]
431pub struct RotatezFunction<'a> {
432 #[atom(CssAtomSet::Rotatez)]
433 pub name: T![Function],
434 pub params: CalcableValue<'a, AngleOrZero>,
435 #[semantic_eq(skip)]
436 pub close: T![')'],
437}
438
439#[node]
445#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
446#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
447#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
448#[derive(csskit_derives::NodeWithMetadata)]
449pub struct SkewFunction<'a> {
450 #[atom(CssAtomSet::Skew)]
451 pub name: T![Function],
452 pub params: (CalcableValue<'a, AngleOrZero>, Option<T![,]>, Option<CalcableValue<'a, AngleOrZero>>),
453 #[semantic_eq(skip)]
454 pub close: T![')'],
455}
456
457#[node]
463#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
464#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
465#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
466#[derive(csskit_derives::NodeWithMetadata)]
467pub struct SkewxFunction<'a> {
468 #[atom(CssAtomSet::Skewx)]
469 pub name: T![Function],
470 pub params: CalcableValue<'a, AngleOrZero>,
471 #[semantic_eq(skip)]
472 pub close: T![')'],
473}
474
475#[node]
481#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
482#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
483#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
484#[derive(csskit_derives::NodeWithMetadata)]
485pub struct SkewyFunction<'a> {
486 #[atom(CssAtomSet::Skewy)]
487 pub name: T![Function],
488 pub params: CalcableValue<'a, AngleOrZero>,
489 #[semantic_eq(skip)]
490 pub close: T![')'],
491}
492
493#[node]
499#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
500#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
501#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
502#[derive(csskit_derives::NodeWithMetadata)]
503pub struct PerspectiveFunction<'a> {
504 #[atom(CssAtomSet::Perspective)]
505 pub name: T![Function],
506 pub params: NoneOr<CalcableValue<'a, Length>>,
507 #[semantic_eq(skip)]
508 pub close: T![')'],
509}
510
511#[cfg(test)]
512mod tests {
513 use super::*;
514 use crate::CssAtomSet;
515 use css_parse::{assert_parse, assert_parse_error, assert_parse_span, assert_semantic_eq, assert_semantic_ne};
516
517 #[test]
518 fn test_writes() {
519 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1,2,3,4,5,6)");
520 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1 2 3 4 5 6)");
521 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(0,0,0,0,0,0)");
522 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(-1,-2,-3,-4,-5,-6)");
523 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1.5,2.5,3.5,4.5,5.5,6.5)");
524
525 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(10px)");
526 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(10px,20px)");
527 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(45%)");
528 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(2rem)");
529 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateX(1rem)");
530 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateY(1rem)");
531
532 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1,2)");
533 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(0,0)");
534 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1)");
535 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1.5,2.5)");
536 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scaleX(2)");
537 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scaleY(2)");
538
539 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(45deg)");
540 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(0)");
541 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(2turn)");
542 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(20rad)");
543
544 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(1deg,2deg)");
545 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(0,0)");
546 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(1deg)");
547 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewX(1deg)");
548 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewX(0)");
549 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewY(1deg)");
550 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewY(0)");
551
552 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale3d(10%,10%,10%)");
553 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate3d(1,2,3,10deg)");
554 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,10,20,30,1)");
555 }
556
557 #[test]
558 fn test_substitution() {
559 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(calc(10px + 5%))");
561 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(var(--x),var(--y))");
562 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateX(calc(1rem * 2))");
563 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateZ(var(--z))");
564 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "perspective(calc(100px))");
565 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(calc(45deg))");
567 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(var(--a))");
568 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(calc(1 + 1),var(--y))");
569 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewX(calc(10deg))");
570 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(calc(1),2,3,4,5,6)");
571 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate3d(1,2,3,var(--a))");
572 }
573
574 #[test]
575 fn test_span() {
576 assert_parse_span!(
577 CssAtomSet::ATOMS,
578 TransformFunction,
579 r#"
580 matrix(1,2,3,4,5,6) translate(0)
581 ^^^^^^^^^^^^^^^^^^^
582 "#
583 );
584 assert_parse_span!(
585 CssAtomSet::ATOMS,
586 TransformFunction,
587 r#"
588 translate(0) foo
589 ^^^^^^^^^^^^
590 "#
591 );
592 assert_parse_span!(
593 CssAtomSet::ATOMS,
594 TranslateFunction,
595 r#"
596 translate(0) bar
597 ^^^^^^^^^^^^
598 "#
599 );
600 }
601
602 #[test]
603 fn test_errors() {
604 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix()");
605 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(1)");
606 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(1,2)");
607 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(one,two,three,four,five,size)");
608
609 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translate()");
610 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translate(foo)");
611 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateX()");
612 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateX(foo)");
613 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateY()");
614 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateY(foo)");
615
616 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scale()");
617 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scale(foo)");
618 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleX()");
619 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleX(foo)");
620 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleY()");
621 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleY(foo)");
622
623 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate()");
624 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate(45px)");
625 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate(all the way around)");
626
627 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skew()");
628 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skew(foo)");
629 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewX()");
630 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewX(foo)");
631 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewY()");
632 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewY(foo)");
633 }
634
635 #[test]
636 fn test_semantic_eq_reads_parameters() {
637 assert_semantic_eq!(CssAtomSet::ATOMS, TransformFunction, "scale(2)", "scale(2)");
638 assert_semantic_ne!(CssAtomSet::ATOMS, TransformFunction, "scale(.5)", "scale(1.5)");
639 assert_semantic_ne!(CssAtomSet::ATOMS, TransformFunction, "scale(2,3)", "scale(3,2)");
640 assert_semantic_ne!(CssAtomSet::ATOMS, TransformFunction, "scale(-1,-1)", "scale(1,-1)");
641 assert_semantic_ne!(CssAtomSet::ATOMS, TransformFunction, "scale(1)", "scale(1,2)");
642 assert_semantic_eq!(CssAtomSet::ATOMS, TransformFunction, "skew(1deg)", "skew(1deg)");
643 assert_semantic_ne!(CssAtomSet::ATOMS, TransformFunction, "skew(1deg)", "skew(2deg)");
644 }
645}