@tbela99/css-parser 0.0.1-rc3 → 0.0.1-rc5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2,1086 +2,6 @@
2
2
 
3
3
  var promises = require('fs/promises');
4
4
 
5
- // https://www.w3.org/TR/CSS21/syndata.html#syntax
6
- // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
7
- // '\\'
8
- const REVERSE_SOLIDUS = 0x5c;
9
- const dimensionUnits = [
10
- 'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
11
- 'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
12
- 'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
13
- 'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
14
- ];
15
- function isLength(dimension) {
16
- return 'unit' in dimension && dimensionUnits.includes(dimension.unit.toLowerCase());
17
- }
18
- function isResolution(dimension) {
19
- return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
20
- }
21
- function isAngle(dimension) {
22
- return 'unit' in dimension && ['rad', 'turn', 'deg', 'grad'].includes(dimension.unit.toLowerCase());
23
- }
24
- function isTime(dimension) {
25
- return 'unit' in dimension && ['ms', 's'].includes(dimension.unit.toLowerCase());
26
- }
27
- function isFrequency(dimension) {
28
- return 'unit' in dimension && ['hz', 'khz'].includes(dimension.unit.toLowerCase());
29
- }
30
- function isLetter(codepoint) {
31
- // lowercase
32
- return (codepoint >= 0x61 && codepoint <= 0x7a) ||
33
- // uppercase
34
- (codepoint >= 0x41 && codepoint <= 0x5a);
35
- }
36
- function isNonAscii(codepoint) {
37
- return codepoint >= 0x80;
38
- }
39
- function isIdentStart(codepoint) {
40
- // _
41
- return codepoint == 0x5f || isLetter(codepoint) || isNonAscii(codepoint);
42
- }
43
- function isDigit(codepoint) {
44
- return codepoint >= 0x30 && codepoint <= 0x39;
45
- }
46
- function isIdentCodepoint(codepoint) {
47
- // -
48
- return codepoint == 0x2d || isDigit(codepoint) || isIdentStart(codepoint);
49
- }
50
- function isIdent(name) {
51
- const j = name.length - 1;
52
- let i = 0;
53
- let codepoint = name.charCodeAt(0);
54
- // -
55
- if (codepoint == 0x2d) {
56
- const nextCodepoint = name.charCodeAt(1);
57
- if (Number.isNaN(nextCodepoint)) {
58
- return false;
59
- }
60
- // -
61
- if (nextCodepoint == 0x2d) {
62
- return true;
63
- }
64
- if (nextCodepoint == REVERSE_SOLIDUS) {
65
- return name.length > 2 && !isNewLine(name.charCodeAt(2));
66
- }
67
- return true;
68
- }
69
- if (!isIdentStart(codepoint)) {
70
- return false;
71
- }
72
- while (i < j) {
73
- i += codepoint < 0x80 ? 1 : String.fromCodePoint(codepoint).length;
74
- codepoint = name.charCodeAt(i);
75
- if (!isIdentCodepoint(codepoint)) {
76
- return false;
77
- }
78
- }
79
- return true;
80
- }
81
- function isPseudo(name) {
82
- if (name.charAt(0) != ':') {
83
- return false;
84
- }
85
- if (name.endsWith('(')) {
86
- return isIdent(name.charAt(1) == ':' ? name.slice(2, -1) : name.slice(1, -1));
87
- }
88
- return isIdent(name.charAt(1) == ':' ? name.slice(2) : name.slice(1));
89
- }
90
- function isHash(name) {
91
- if (name.charAt(0) != '#') {
92
- return false;
93
- }
94
- return isIdent(name.charAt(1));
95
- }
96
- function isNumber(name) {
97
- if (name.length == 0) {
98
- return false;
99
- }
100
- let codepoint = name.charCodeAt(0);
101
- let i = 0;
102
- const j = name.length;
103
- if (j == 1 && !isDigit(codepoint)) {
104
- return false;
105
- }
106
- // '+' '-'
107
- if ([0x2b, 0x2d].includes(codepoint)) {
108
- i++;
109
- }
110
- // consume digits
111
- while (i < j) {
112
- codepoint = name.charCodeAt(i);
113
- if (isDigit(codepoint)) {
114
- i++;
115
- continue;
116
- }
117
- // '.' 'E' 'e'
118
- if (codepoint == 0x2e || codepoint == 0x45 || codepoint == 0x65) {
119
- break;
120
- }
121
- return false;
122
- }
123
- // '.'
124
- if (codepoint == 0x2e) {
125
- if (!isDigit(name.charCodeAt(++i))) {
126
- return false;
127
- }
128
- }
129
- while (i < j) {
130
- codepoint = name.charCodeAt(i);
131
- if (isDigit(codepoint)) {
132
- i++;
133
- continue;
134
- }
135
- // 'E' 'e'
136
- if (codepoint == 0x45 || codepoint == 0x65) {
137
- i++;
138
- break;
139
- }
140
- return false;
141
- }
142
- // 'E' 'e'
143
- if (codepoint == 0x45 || codepoint == 0x65) {
144
- if (i == j) {
145
- return false;
146
- }
147
- codepoint = name.charCodeAt(i + 1);
148
- // '+' '-'
149
- if ([0x2b, 0x2d].includes(codepoint)) {
150
- i++;
151
- }
152
- codepoint = name.charCodeAt(i + 1);
153
- if (!isDigit(codepoint)) {
154
- return false;
155
- }
156
- }
157
- while (++i < j) {
158
- codepoint = name.charCodeAt(i);
159
- if (!isDigit(codepoint)) {
160
- return false;
161
- }
162
- }
163
- return true;
164
- }
165
- function isDimension(name) {
166
- let index = 0;
167
- while (index++ < name.length) {
168
- if (isDigit(name.charCodeAt(name.length - index))) {
169
- index--;
170
- break;
171
- }
172
- if (index == 3) {
173
- break;
174
- }
175
- }
176
- if (index == 0 || index > 3) {
177
- return false;
178
- }
179
- const number = name.slice(0, -index);
180
- return number.length > 0 && isIdentStart(name.charCodeAt(name.length - index)) && isNumber(number);
181
- }
182
- function isPercentage(name) {
183
- return name.endsWith('%') && isNumber(name.slice(0, -1));
184
- }
185
- function parseDimension(name) {
186
- let index = 0;
187
- while (index++ < name.length) {
188
- if (isDigit(name.charCodeAt(name.length - index))) {
189
- index--;
190
- break;
191
- }
192
- if (index == 3) {
193
- break;
194
- }
195
- }
196
- const dimension = { typ: 'Dimension', val: name.slice(0, -index), unit: name.slice(-index) };
197
- if (isAngle(dimension)) {
198
- // @ts-ignore
199
- dimension.typ = 'Angle';
200
- }
201
- else if (isLength(dimension)) {
202
- // @ts-ignore
203
- dimension.typ = 'Length';
204
- }
205
- else if (isTime(dimension)) {
206
- // @ts-ignore
207
- dimension.typ = 'Time';
208
- }
209
- else if (isResolution(dimension)) {
210
- // @ts-ignore
211
- dimension.typ = 'Resolution';
212
- if (dimension.unit == 'dppx') {
213
- dimension.unit = 'x';
214
- }
215
- }
216
- else if (isFrequency(dimension)) {
217
- // @ts-ignore
218
- dimension.typ = 'Frequency';
219
- }
220
- return dimension;
221
- }
222
- function isHexColor(name) {
223
- if (name.charAt(0) != '#' || ![4, 5, 7, 9].includes(name.length)) {
224
- return false;
225
- }
226
- for (let chr of name.slice(1)) {
227
- let codepoint = chr.charCodeAt(0);
228
- if (!isDigit(codepoint) &&
229
- // A-F
230
- !(codepoint >= 0x41 && codepoint <= 0x46) &&
231
- // a-f
232
- !(codepoint >= 0x61 && codepoint <= 0x66)) {
233
- return false;
234
- }
235
- }
236
- return true;
237
- }
238
- function isHexDigit(name) {
239
- if (name.length || name.length > 6) {
240
- return false;
241
- }
242
- for (let chr of name) {
243
- let codepoint = chr.charCodeAt(0);
244
- if (!isDigit(codepoint) &&
245
- // A F
246
- !(codepoint >= 0x41 && codepoint <= 0x46) &&
247
- // a f
248
- !(codepoint >= 0x61 && codepoint <= 0x66)) {
249
- return false;
250
- }
251
- }
252
- return true;
253
- }
254
- function isFunction(name) {
255
- return name.endsWith('(') && isIdent(name.slice(0, -1));
256
- }
257
- function isAtKeyword(name) {
258
- return name.charCodeAt(0) == 0x40 && isIdent(name.slice(1));
259
- }
260
- function isNewLine(codepoint) {
261
- // \n \r \f
262
- return codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
263
- }
264
- function isWhiteSpace(codepoint) {
265
- return codepoint == 0x9 || codepoint == 0x20 ||
266
- // isNewLine
267
- codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
268
- }
269
-
270
- var properties = {
271
- inset: {
272
- shorthand: "inset",
273
- properties: [
274
- "top",
275
- "right",
276
- "bottom",
277
- "left"
278
- ],
279
- types: [
280
- "Length",
281
- "Perc"
282
- ],
283
- multiple: false,
284
- separator: null,
285
- keywords: [
286
- "auto"
287
- ]
288
- },
289
- top: {
290
- shorthand: "inset"
291
- },
292
- right: {
293
- shorthand: "inset"
294
- },
295
- bottom: {
296
- shorthand: "inset"
297
- },
298
- left: {
299
- shorthand: "inset"
300
- },
301
- margin: {
302
- shorthand: "margin",
303
- properties: [
304
- "margin-top",
305
- "margin-right",
306
- "margin-bottom",
307
- "margin-left"
308
- ],
309
- types: [
310
- "Length",
311
- "Perc"
312
- ],
313
- multiple: false,
314
- separator: null,
315
- keywords: [
316
- "auto"
317
- ]
318
- },
319
- "margin-top": {
320
- shorthand: "margin"
321
- },
322
- "margin-right": {
323
- shorthand: "margin"
324
- },
325
- "margin-bottom": {
326
- shorthand: "margin"
327
- },
328
- "margin-left": {
329
- shorthand: "margin"
330
- },
331
- padding: {
332
- shorthand: "padding",
333
- properties: [
334
- "padding-top",
335
- "padding-right",
336
- "padding-bottom",
337
- "padding-left"
338
- ],
339
- types: [
340
- "Length",
341
- "Perc"
342
- ],
343
- keywords: [
344
- ]
345
- },
346
- "padding-top": {
347
- shorthand: "padding"
348
- },
349
- "padding-right": {
350
- shorthand: "padding"
351
- },
352
- "padding-bottom": {
353
- shorthand: "padding"
354
- },
355
- "padding-left": {
356
- shorthand: "padding"
357
- },
358
- "border-radius": {
359
- shorthand: "border-radius",
360
- properties: [
361
- "border-top-left-radius",
362
- "border-top-right-radius",
363
- "border-bottom-right-radius",
364
- "border-bottom-left-radius"
365
- ],
366
- types: [
367
- "Length",
368
- "Perc"
369
- ],
370
- multiple: true,
371
- separator: "/",
372
- keywords: [
373
- ]
374
- },
375
- "border-top-left-radius": {
376
- shorthand: "border-radius"
377
- },
378
- "border-top-right-radius": {
379
- shorthand: "border-radius"
380
- },
381
- "border-bottom-right-radius": {
382
- shorthand: "border-radius"
383
- },
384
- "border-bottom-left-radius": {
385
- shorthand: "border-radius"
386
- },
387
- "border-width": {
388
- shorthand: "border-width",
389
- map: "border",
390
- properties: [
391
- "border-top-width",
392
- "border-right-width",
393
- "border-bottom-width",
394
- "border-left-width"
395
- ],
396
- types: [
397
- "Length",
398
- "Perc"
399
- ],
400
- "default": [
401
- "medium"
402
- ],
403
- keywords: [
404
- "thin",
405
- "medium",
406
- "thick"
407
- ]
408
- },
409
- "border-top-width": {
410
- map: "border",
411
- shorthand: "border-width"
412
- },
413
- "border-right-width": {
414
- map: "border",
415
- shorthand: "border-width"
416
- },
417
- "border-bottom-width": {
418
- map: "border",
419
- shorthand: "border-width"
420
- },
421
- "border-left-width": {
422
- map: "border",
423
- shorthand: "border-width"
424
- },
425
- "border-style": {
426
- shorthand: "border-style",
427
- map: "border",
428
- properties: [
429
- "border-top-style",
430
- "border-right-style",
431
- "border-bottom-style",
432
- "border-left-style"
433
- ],
434
- types: [
435
- ],
436
- "default": [
437
- "none"
438
- ],
439
- keywords: [
440
- "none",
441
- "hidden",
442
- "dotted",
443
- "dashed",
444
- "solid",
445
- "double",
446
- "groove",
447
- "ridge",
448
- "inset",
449
- "outset"
450
- ]
451
- },
452
- "border-top-style": {
453
- map: "border",
454
- shorthand: "border-style"
455
- },
456
- "border-right-style": {
457
- map: "border",
458
- shorthand: "border-style"
459
- },
460
- "border-bottom-style": {
461
- map: "border",
462
- shorthand: "border-style"
463
- },
464
- "border-left-style": {
465
- map: "border",
466
- shorthand: "border-style"
467
- },
468
- "border-color": {
469
- shorthand: "border-color",
470
- map: "border",
471
- properties: [
472
- "border-top-color",
473
- "border-right-color",
474
- "border-bottom-color",
475
- "border-left-color"
476
- ],
477
- types: [
478
- "Color"
479
- ],
480
- "default": [
481
- "currentcolor"
482
- ],
483
- keywords: [
484
- ]
485
- },
486
- "border-top-color": {
487
- map: "border",
488
- shorthand: "border-color"
489
- },
490
- "border-right-color": {
491
- map: "border",
492
- shorthand: "border-color"
493
- },
494
- "border-bottom-color": {
495
- map: "border",
496
- shorthand: "border-color"
497
- },
498
- "border-left-color": {
499
- map: "border",
500
- shorthand: "border-color"
501
- }
502
- };
503
- var map = {
504
- border: {
505
- shorthand: "border",
506
- pattern: "border-color border-style border-width",
507
- keywords: [
508
- "none"
509
- ],
510
- "default": [
511
- "0",
512
- "none"
513
- ],
514
- properties: {
515
- "border-color": {
516
- types: [
517
- "Color"
518
- ],
519
- "default": [
520
- "currentcolor"
521
- ],
522
- keywords: [
523
- ]
524
- },
525
- "border-style": {
526
- types: [
527
- ],
528
- "default": [
529
- "none"
530
- ],
531
- keywords: [
532
- "none",
533
- "hidden",
534
- "dotted",
535
- "dashed",
536
- "solid",
537
- "double",
538
- "groove",
539
- "ridge",
540
- "inset",
541
- "outset"
542
- ]
543
- },
544
- "border-width": {
545
- types: [
546
- "Length",
547
- "Perc"
548
- ],
549
- "default": [
550
- "medium"
551
- ],
552
- keywords: [
553
- "thin",
554
- "medium",
555
- "thick"
556
- ]
557
- }
558
- }
559
- },
560
- "border-color": {
561
- shorthand: "border"
562
- },
563
- "border-style": {
564
- shorthand: "border"
565
- },
566
- "border-width": {
567
- shorthand: "border"
568
- },
569
- outline: {
570
- shorthand: "outline",
571
- pattern: "outline-color outline-style outline-width",
572
- keywords: [
573
- "none"
574
- ],
575
- "default": [
576
- "0",
577
- "none"
578
- ],
579
- properties: {
580
- "outline-color": {
581
- types: [
582
- "Color"
583
- ],
584
- "default": [
585
- "currentColor"
586
- ],
587
- keywords: [
588
- "currentColor"
589
- ]
590
- },
591
- "outline-style": {
592
- types: [
593
- ],
594
- "default": [
595
- "none"
596
- ],
597
- keywords: [
598
- "auto",
599
- "none",
600
- "dotted",
601
- "dashed",
602
- "solid",
603
- "double",
604
- "groove",
605
- "ridge",
606
- "inset",
607
- "outset"
608
- ]
609
- },
610
- "outline-width": {
611
- types: [
612
- "Length",
613
- "Perc"
614
- ],
615
- "default": [
616
- "medium"
617
- ],
618
- keywords: [
619
- "thin",
620
- "medium",
621
- "thick"
622
- ]
623
- }
624
- }
625
- },
626
- "outline-color": {
627
- shorthand: "outline"
628
- },
629
- "outline-style": {
630
- shorthand: "outline"
631
- },
632
- "outline-width": {
633
- shorthand: "outline"
634
- },
635
- font: {
636
- shorthand: "font",
637
- pattern: "font-weight font-style font-size line-height font-stretch font-variant font-family",
638
- keywords: [
639
- "caption",
640
- "icon",
641
- "menu",
642
- "message-box",
643
- "small-caption",
644
- "status-bar",
645
- "-moz-window, ",
646
- "-moz-document, ",
647
- "-moz-desktop, ",
648
- "-moz-info, ",
649
- "-moz-dialog",
650
- "-moz-button",
651
- "-moz-pull-down-menu",
652
- "-moz-list",
653
- "-moz-field"
654
- ],
655
- "default": [
656
- ],
657
- properties: {
658
- "font-weight": {
659
- types: [
660
- "Number"
661
- ],
662
- "default": [
663
- "normal",
664
- "400"
665
- ],
666
- keywords: [
667
- "normal",
668
- "bold",
669
- "lighter",
670
- "bolder"
671
- ],
672
- constraints: {
673
- value: {
674
- min: "1",
675
- max: "1000"
676
- }
677
- },
678
- mapping: {
679
- thin: "100",
680
- hairline: "100",
681
- "extra light": "200",
682
- "ultra light": "200",
683
- light: "300",
684
- normal: "400",
685
- regular: "400",
686
- medium: "500",
687
- "semi bold": "600",
688
- "demi bold": "600",
689
- bold: "700",
690
- "extra bold": "800",
691
- "ultra bold": "800",
692
- black: "900",
693
- heavy: "900",
694
- "extra black": "950",
695
- "ultra black": "950"
696
- }
697
- },
698
- "font-style": {
699
- types: [
700
- "Angle"
701
- ],
702
- "default": [
703
- "normal"
704
- ],
705
- keywords: [
706
- "normal",
707
- "italic",
708
- "oblique"
709
- ]
710
- },
711
- "font-size": {
712
- types: [
713
- "Length",
714
- "Perc"
715
- ],
716
- "default": [
717
- ],
718
- keywords: [
719
- "xx-small",
720
- "x-small",
721
- "small",
722
- "medium",
723
- "large",
724
- "x-large",
725
- "xx-large",
726
- "xxx-large",
727
- "larger",
728
- "smaller"
729
- ],
730
- required: true
731
- },
732
- "line-height": {
733
- types: [
734
- "Length",
735
- "Perc",
736
- "Number"
737
- ],
738
- "default": [
739
- "normal"
740
- ],
741
- keywords: [
742
- "normal"
743
- ],
744
- previous: "font-size",
745
- prefix: {
746
- typ: "Literal",
747
- val: "/"
748
- }
749
- },
750
- "font-stretch": {
751
- types: [
752
- "Perc"
753
- ],
754
- "default": [
755
- "normal"
756
- ],
757
- keywords: [
758
- "ultra-condensed",
759
- "extra-condensed",
760
- "condensed",
761
- "semi-condensed",
762
- "normal",
763
- "semi-expanded",
764
- "expanded",
765
- "extra-expanded",
766
- "ultra-expanded"
767
- ],
768
- mapping: {
769
- "ultra-condensed": "50%",
770
- "extra-condensed": "62.5%",
771
- condensed: "75%",
772
- "semi-condensed": "87.5%",
773
- normal: "100%",
774
- "semi-expanded": "112.5%",
775
- expanded: "125%",
776
- "extra-expanded": "150%",
777
- "ultra-expanded": "200%"
778
- }
779
- },
780
- "font-variant": {
781
- types: [
782
- ],
783
- "default": [
784
- "normal"
785
- ],
786
- keywords: [
787
- "normal",
788
- "none",
789
- "common-ligatures",
790
- "no-common-ligatures",
791
- "discretionary-ligatures",
792
- "no-discretionary-ligatures",
793
- "historical-ligatures",
794
- "no-historical-ligatures",
795
- "contextual",
796
- "no-contextual",
797
- "historical-forms",
798
- "small-caps",
799
- "all-small-caps",
800
- "petite-caps",
801
- "all-petite-caps",
802
- "unicase",
803
- "titling-caps",
804
- "ordinal",
805
- "slashed-zero",
806
- "lining-nums",
807
- "oldstyle-nums",
808
- "proportional-nums",
809
- "tabular-nums",
810
- "diagonal-fractions",
811
- "stacked-fractions",
812
- "ordinal",
813
- "slashed-zero",
814
- "ruby",
815
- "jis78",
816
- "jis83",
817
- "jis90",
818
- "jis04",
819
- "simplified",
820
- "traditional",
821
- "full-width",
822
- "proportional-width",
823
- "ruby",
824
- "sub",
825
- "super",
826
- "text",
827
- "emoji",
828
- "unicode"
829
- ]
830
- },
831
- "font-family": {
832
- types: [
833
- "String",
834
- "Iden"
835
- ],
836
- "default": [
837
- ],
838
- keywords: [
839
- "serif",
840
- "sans-serif",
841
- "monospace",
842
- "cursive",
843
- "fantasy",
844
- "system-ui",
845
- "ui-serif",
846
- "ui-sans-serif",
847
- "ui-monospace",
848
- "ui-rounded",
849
- "math",
850
- "emoji",
851
- "fangsong"
852
- ],
853
- required: true,
854
- multiple: true,
855
- separator: {
856
- typ: "Comma"
857
- }
858
- }
859
- }
860
- },
861
- "font-weight": {
862
- shorthand: "font"
863
- },
864
- "font-style": {
865
- shorthand: "font"
866
- },
867
- "font-size": {
868
- shorthand: "font"
869
- },
870
- "line-height": {
871
- shorthand: "font"
872
- },
873
- "font-stretch": {
874
- shorthand: "font"
875
- },
876
- "font-variant": {
877
- shorthand: "font"
878
- },
879
- "font-family": {
880
- shorthand: "font"
881
- },
882
- background: {
883
- shorthand: "background",
884
- pattern: "background-repeat background-color background-image background-attachment background-clip background-origin background-position background-size",
885
- keywords: [
886
- "none"
887
- ],
888
- "default": [
889
- ],
890
- multiple: true,
891
- separator: {
892
- typ: "Comma"
893
- },
894
- properties: {
895
- "background-repeat": {
896
- types: [
897
- ],
898
- "default": [
899
- "repeat"
900
- ],
901
- multiple: true,
902
- keywords: [
903
- "repeat-x",
904
- "repeat-y",
905
- "repeat",
906
- "space",
907
- "round",
908
- "no-repeat"
909
- ],
910
- mapping: {
911
- "repeat no-repeat": "repeat-x",
912
- "no-repeat repeat": "repeat-y",
913
- "repeat repeat": "repeat",
914
- "space space": "space",
915
- "round round": "round",
916
- "no-repeat no-repeat": "no-repeat"
917
- }
918
- },
919
- "background-color": {
920
- types: [
921
- "Color"
922
- ],
923
- "default": [
924
- "transparent"
925
- ],
926
- multiple: true,
927
- keywords: [
928
- ]
929
- },
930
- "background-image": {
931
- types: [
932
- "UrlFunc"
933
- ],
934
- "default": [
935
- "none"
936
- ],
937
- keywords: [
938
- "none"
939
- ]
940
- },
941
- "background-attachment": {
942
- types: [
943
- ],
944
- "default": [
945
- "scroll"
946
- ],
947
- multiple: true,
948
- keywords: [
949
- "scroll",
950
- "fixed",
951
- "local"
952
- ]
953
- },
954
- "background-clip": {
955
- types: [
956
- ],
957
- "default": [
958
- "border-box"
959
- ],
960
- multiple: true,
961
- keywords: [
962
- "border-box",
963
- "padding-box",
964
- "content-box",
965
- "text"
966
- ]
967
- },
968
- "background-origin": {
969
- types: [
970
- ],
971
- "default": [
972
- "padding-box"
973
- ],
974
- multiple: true,
975
- keywords: [
976
- "border-box",
977
- "padding-box",
978
- "content-box"
979
- ]
980
- },
981
- "background-position": {
982
- multiple: true,
983
- types: [
984
- "Perc",
985
- "Length"
986
- ],
987
- "default": [
988
- "0 0",
989
- "top left",
990
- "left top"
991
- ],
992
- keywords: [
993
- "top",
994
- "left",
995
- "center",
996
- "bottom",
997
- "right"
998
- ],
999
- mapping: {
1000
- left: "0",
1001
- top: "0",
1002
- center: "50%",
1003
- bottom: "100%",
1004
- right: "100%"
1005
- },
1006
- constraints: {
1007
- mapping: {
1008
- max: 2
1009
- }
1010
- }
1011
- },
1012
- "background-size": {
1013
- multiple: true,
1014
- previous: "background-position",
1015
- prefix: {
1016
- typ: "Literal",
1017
- val: "/"
1018
- },
1019
- types: [
1020
- "Perc",
1021
- "Length"
1022
- ],
1023
- "default": [
1024
- "auto",
1025
- "auto auto"
1026
- ],
1027
- keywords: [
1028
- "auto",
1029
- "cover",
1030
- "contain"
1031
- ],
1032
- mapping: {
1033
- "auto auto": "auto"
1034
- }
1035
- }
1036
- }
1037
- },
1038
- "background-repeat": {
1039
- shorthand: "background"
1040
- },
1041
- "background-color": {
1042
- shorthand: "background"
1043
- },
1044
- "background-image": {
1045
- shorthand: "background"
1046
- },
1047
- "background-attachment": {
1048
- shorthand: "background"
1049
- },
1050
- "background-clip": {
1051
- shorthand: "background"
1052
- },
1053
- "background-origin": {
1054
- shorthand: "background"
1055
- },
1056
- "background-position": {
1057
- shorthand: "background"
1058
- },
1059
- "background-size": {
1060
- shorthand: "background"
1061
- }
1062
- };
1063
- var config$1 = {
1064
- properties: properties,
1065
- map: map
1066
- };
1067
-
1068
- const getConfig = () => config$1;
1069
-
1070
- const funcList = ['clamp', 'calc'];
1071
- function matchType(val, properties) {
1072
- if (val.typ == 'Iden' && properties.keywords.includes(val.val) ||
1073
- (properties.types.includes(val.typ))) {
1074
- return true;
1075
- }
1076
- if (val.typ == 'Number' && val.val == '0') {
1077
- return properties.types.some(type => type == 'Length' || type == 'Angle');
1078
- }
1079
- if (val.typ == 'Func' && funcList.includes(val.val)) {
1080
- return val.chi.every((t => ['Literal', 'Comma', 'Whitespace', 'Start-parens', 'End-parens'].includes(t.typ) || matchType(t, properties)));
1081
- }
1082
- return false;
1083
- }
1084
-
1085
5
  // name to color
1086
6
  const COLORS_NAMES = Object.seal({
1087
7
  'aliceblue': '#f0f8ff',
@@ -1394,426 +314,1575 @@ function rgb2Hex(token) {
1394
314
  // @ts-ignore
1395
315
  t = token.chi[i];
1396
316
  // @ts-ignore
1397
- value += Math.round(t.typ == 'Perc' ? 255 * t.val / 100 : t.val).toString(16).padStart(2, '0');
317
+ value += Math.round(t.typ == 'Perc' ? 255 * t.val / 100 : t.val).toString(16).padStart(2, '0');
318
+ }
319
+ // @ts-ignore
320
+ if (token.chi.length == 7) {
321
+ // @ts-ignore
322
+ t = token.chi[6];
323
+ // @ts-ignore
324
+ if ((t.typ == 'Number' && t.val < 1) ||
325
+ // @ts-ignore
326
+ (t.typ == 'Perc' && t.val < 100)) {
327
+ // @ts-ignore
328
+ value += Math.round(255 * (t.typ == 'Perc' ? t.val / 100 : t.val)).toString(16).padStart(2, '0');
329
+ }
330
+ }
331
+ return value;
332
+ }
333
+ function hsl2Hex(token) {
334
+ let t;
335
+ // @ts-ignore
336
+ let h = getAngle(token.chi[0]);
337
+ // @ts-ignore
338
+ t = token.chi[2];
339
+ // @ts-ignore
340
+ let s = t.typ == 'Perc' ? t.val / 100 : t.val;
341
+ // @ts-ignore
342
+ t = token.chi[4];
343
+ // @ts-ignore
344
+ let l = t.typ == 'Perc' ? t.val / 100 : t.val;
345
+ let a = null;
346
+ if (token.chi?.length == 7) {
347
+ // @ts-ignore
348
+ t = token.chi[6];
349
+ // @ts-ignore
350
+ if ((t.typ == 'Perc' && t.val < 100) ||
351
+ // @ts-ignore
352
+ (t.typ == 'Number' && t.val < 1)) {
353
+ // @ts-ignore
354
+ a = (t.typ == 'Perc' ? t.val / 100 : t.val);
355
+ }
356
+ }
357
+ return `#${hsl2rgb(h, s, l, a).reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
358
+ }
359
+ function hwb2hex(token) {
360
+ let t;
361
+ // @ts-ignore
362
+ let h = getAngle(token.chi[0]);
363
+ // @ts-ignore
364
+ t = token.chi[2];
365
+ // @ts-ignore
366
+ let white = t.typ == 'Perc' ? t.val / 100 : t.val;
367
+ // @ts-ignore
368
+ t = token.chi[4];
369
+ // @ts-ignore
370
+ let black = t.typ == 'Perc' ? t.val / 100 : t.val;
371
+ let a = null;
372
+ if (token.chi?.length == 7) {
373
+ // @ts-ignore
374
+ t = token.chi[6];
375
+ // @ts-ignore
376
+ if ((t.typ == 'Perc' && t.val < 100) ||
377
+ // @ts-ignore
378
+ (t.typ == 'Number' && t.val < 1)) {
379
+ // @ts-ignore
380
+ a = (t.typ == 'Perc' ? t.val / 100 : t.val);
381
+ }
382
+ }
383
+ const rgb = hsl2rgb(h, 1, .5, a);
384
+ let value;
385
+ for (let i = 0; i < 3; i++) {
386
+ value = rgb[i] / 255;
387
+ value *= (1 - white - black);
388
+ value += white;
389
+ rgb[i] = Math.round(value * 255);
390
+ }
391
+ return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
392
+ }
393
+ function cmyk2hex(token) {
394
+ // @ts-ignore
395
+ let t = token.chi[0];
396
+ // @ts-ignore
397
+ const c = t.typ == 'Perc' ? t.val / 100 : t.val;
398
+ // @ts-ignore
399
+ t = token.chi[2];
400
+ // @ts-ignore
401
+ const m = t.typ == 'Perc' ? t.val / 100 : t.val;
402
+ // @ts-ignore
403
+ t = token.chi[4];
404
+ // @ts-ignore
405
+ const y = t.typ == 'Perc' ? t.val / 100 : t.val;
406
+ // @ts-ignore
407
+ t = token.chi[6];
408
+ // @ts-ignore
409
+ const k = t.typ == 'Perc' ? t.val / 100 : t.val;
410
+ const rgb = [
411
+ Math.round(255 * (1 - Math.min(1, c * (1 - k) + k))),
412
+ Math.round(255 * (1 - Math.min(1, m * (1 - k) + k))),
413
+ Math.round(255 * (1 - Math.min(1, y * (1 - k) + k)))
414
+ ];
415
+ // @ts-ignore
416
+ if (token.chi.length >= 9) {
417
+ // @ts-ignore
418
+ t = token.chi[8];
419
+ // @ts-ignore
420
+ rgb.push(Math.round(255 * (t.typ == 'Perc' ? t.val / 100 : t.val)));
421
+ }
422
+ return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
423
+ }
424
+ function getAngle(token) {
425
+ if (token.typ == 'Angle') {
426
+ switch (token.unit) {
427
+ case 'deg':
428
+ // @ts-ignore
429
+ return token.val / 360;
430
+ case 'rad':
431
+ // @ts-ignore
432
+ return token.val / (2 * Math.PI);
433
+ case 'grad':
434
+ // @ts-ignore
435
+ return token.val / 400;
436
+ case 'turn':
437
+ // @ts-ignore
438
+ return +token.val;
439
+ }
440
+ }
441
+ // @ts-ignore
442
+ return token.val / 360;
443
+ }
444
+ function hsl2rgb(h, s, l, a = null) {
445
+ let v = l <= .5 ? l * (1.0 + s) : l + s - l * s;
446
+ let r = l;
447
+ let g = l;
448
+ let b = l;
449
+ if (v > 0) {
450
+ let m = l + l - v;
451
+ let sv = (v - m) / v;
452
+ h *= 6.0;
453
+ let sextant = Math.floor(h);
454
+ let fract = h - sextant;
455
+ let vsf = v * sv * fract;
456
+ let mid1 = m + vsf;
457
+ let mid2 = v - vsf;
458
+ switch (sextant) {
459
+ case 0:
460
+ r = v;
461
+ g = mid1;
462
+ b = m;
463
+ break;
464
+ case 1:
465
+ r = mid2;
466
+ g = v;
467
+ b = m;
468
+ break;
469
+ case 2:
470
+ r = m;
471
+ g = v;
472
+ b = mid1;
473
+ break;
474
+ case 3:
475
+ r = m;
476
+ g = mid2;
477
+ b = v;
478
+ break;
479
+ case 4:
480
+ r = mid1;
481
+ g = m;
482
+ b = v;
483
+ break;
484
+ case 5:
485
+ r = v;
486
+ g = m;
487
+ b = mid2;
488
+ break;
489
+ }
490
+ }
491
+ const values = [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
492
+ if (a != null && a != 1) {
493
+ values.push(Math.round(a * 255));
494
+ }
495
+ return values;
496
+ }
497
+
498
+ const colorsFunc = ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk'];
499
+ function reduceNumber(val) {
500
+ val = (+val).toString();
501
+ if (val === '0') {
502
+ return '0';
503
+ }
504
+ const chr = val.charAt(0);
505
+ if (chr == '-') {
506
+ const slice = val.slice(0, 2);
507
+ if (slice == '-0') {
508
+ return val.length == 2 ? '0' : '-' + val.slice(2);
509
+ }
510
+ }
511
+ if (chr == '0') {
512
+ return val.slice(1);
513
+ }
514
+ return val;
515
+ }
516
+ function render(data, opt = {}) {
517
+ const startTime = performance.now();
518
+ const options = Object.assign(opt.minify ?? true ? {
519
+ indent: '',
520
+ newLine: '',
521
+ removeComments: true
522
+ } : {
523
+ indent: ' ',
524
+ newLine: '\n',
525
+ compress: false,
526
+ removeComments: false,
527
+ }, { colorConvert: true, preserveLicense: false }, opt);
528
+ return {
529
+ code: doRender(data, options, function reducer(acc, curr) {
530
+ if (curr.typ == 'Comment' && options.removeComments) {
531
+ if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
532
+ return acc;
533
+ }
534
+ return acc + curr.val;
535
+ }
536
+ return acc + renderToken(curr, options, reducer);
537
+ }, 0), stats: {
538
+ total: `${(performance.now() - startTime).toFixed(2)}ms`
539
+ }
540
+ };
541
+ }
542
+ // @ts-ignore
543
+ function doRender(data, options, reducer, level = 0, indents = []) {
544
+ if (indents.length < level + 1) {
545
+ indents.push(options.indent.repeat(level));
546
+ }
547
+ if (indents.length < level + 2) {
548
+ indents.push(options.indent.repeat(level + 1));
549
+ }
550
+ const indent = indents[level];
551
+ const indentSub = indents[level + 1];
552
+ switch (data.typ) {
553
+ case 'Declaration':
554
+ return `${data.nam}:${options.indent}${data.val.reduce(reducer, '')}`;
555
+ case 'Comment':
556
+ return !options.removeComments || (options.preserveLicense && data.val.startsWith('/*!')) ? data.val : '';
557
+ case 'StyleSheet':
558
+ return data.chi.reduce((css, node) => {
559
+ const str = doRender(node, options, reducer, level, indents);
560
+ if (str === '') {
561
+ return css;
562
+ }
563
+ if (css === '') {
564
+ return str;
565
+ }
566
+ return `${css}${options.newLine}${str}`;
567
+ }, '');
568
+ case 'AtRule':
569
+ case 'Rule':
570
+ if (data.typ == 'AtRule' && !('chi' in data)) {
571
+ return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
572
+ }
573
+ // @ts-ignore
574
+ let children = data.chi.reduce((css, node) => {
575
+ let str;
576
+ if (node.typ == 'Comment') {
577
+ str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
578
+ }
579
+ else if (node.typ == 'Declaration') {
580
+ if (node.val.length == 0) {
581
+ console.error(`invalid declaration`, node);
582
+ return '';
583
+ }
584
+ str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`;
585
+ }
586
+ else if (node.typ == 'AtRule' && !('chi' in node)) {
587
+ str = `${data.val === '' ? '' : options.indent || ' '}${data.val};`;
588
+ }
589
+ else {
590
+ str = doRender(node, options, reducer, level + 1, indents);
591
+ }
592
+ if (css === '') {
593
+ return str;
594
+ }
595
+ if (str === '') {
596
+ return css;
597
+ }
598
+ return `${css}${options.newLine}${indentSub}${str}`;
599
+ }, '');
600
+ if (children.endsWith(';')) {
601
+ children = children.slice(0, -1);
602
+ }
603
+ if (data.typ == 'AtRule') {
604
+ return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
605
+ }
606
+ return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
607
+ }
608
+ return '';
609
+ }
610
+ function renderToken(token, options = {}, reducer) {
611
+ if (reducer == null) {
612
+ reducer = function (acc, curr) {
613
+ if (curr.typ == 'Comment' && options.removeComments) {
614
+ if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
615
+ return acc;
616
+ }
617
+ return acc + curr.val;
618
+ }
619
+ return acc + renderToken(curr, options, reducer);
620
+ };
621
+ }
622
+ switch (token.typ) {
623
+ case 'Color':
624
+ if (options.minify || options.colorConvert) {
625
+ if (token.kin == 'lit' && token.val.toLowerCase() == 'currentcolor') {
626
+ return 'currentcolor';
627
+ }
628
+ let value = token.kin == 'hex' ? token.val.toLowerCase() : (token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : '');
629
+ if (token.val == 'rgb' || token.val == 'rgba') {
630
+ value = rgb2Hex(token);
631
+ }
632
+ else if (token.val == 'hsl' || token.val == 'hsla') {
633
+ value = hsl2Hex(token);
634
+ }
635
+ else if (token.val == 'hwb') {
636
+ value = hwb2hex(token);
637
+ }
638
+ else if (token.val == 'device-cmyk') {
639
+ value = cmyk2hex(token);
640
+ }
641
+ const named_color = NAMES_COLORS[value];
642
+ if (value !== '') {
643
+ if (value.length == 7) {
644
+ if (value[1] == value[2] &&
645
+ value[3] == value[4] &&
646
+ value[5] == value[6]) {
647
+ value = `#${value[1]}${value[3]}${value[5]}`;
648
+ }
649
+ }
650
+ else if (value.length == 9) {
651
+ if (value[1] == value[2] &&
652
+ value[3] == value[4] &&
653
+ value[5] == value[6] &&
654
+ value[7] == value[8]) {
655
+ value = `#${value[1]}${value[3]}${value[5]}${value[7]}`;
656
+ }
657
+ }
658
+ return named_color != null && named_color.length <= value.length ? named_color : value;
659
+ }
660
+ }
661
+ if (token.kin == 'hex' || token.kin == 'lit') {
662
+ return token.val;
663
+ }
664
+ case 'Start-parens':
665
+ if (!('chi' in token)) {
666
+ return '(';
667
+ }
668
+ case 'Func':
669
+ case 'UrlFunc':
670
+ case 'Pseudo-class-func':
671
+ // @ts-ignore
672
+ return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
673
+ case 'Includes':
674
+ return '~=';
675
+ case 'Dash-match':
676
+ return '|=';
677
+ case 'Lt':
678
+ return '<';
679
+ case 'Lte':
680
+ return '<=';
681
+ case 'Gt':
682
+ return '>';
683
+ case 'Gte':
684
+ return '>=';
685
+ case 'End-parens':
686
+ return ')';
687
+ case 'Attr-start':
688
+ return '[';
689
+ case 'Attr-end':
690
+ return ']';
691
+ case 'Whitespace':
692
+ return ' ';
693
+ case 'Colon':
694
+ return ':';
695
+ case 'Semi-colon':
696
+ return ';';
697
+ case 'Comma':
698
+ return ',';
699
+ case 'Important':
700
+ return '!important';
701
+ case 'Attr':
702
+ return '[' + token.chi.reduce(reducer, '') + ']';
703
+ case 'Time':
704
+ case 'Angle':
705
+ case 'Length':
706
+ case 'Dimension':
707
+ case 'Frequency':
708
+ case 'Resolution':
709
+ let val = reduceNumber(token.val);
710
+ let unit = token.unit;
711
+ if (token.typ == 'Angle') {
712
+ const angle = getAngle(token);
713
+ let v;
714
+ let value = val + unit;
715
+ for (const u of ['turn', 'deg', 'rad', 'grad']) {
716
+ if (token.unit == u) {
717
+ continue;
718
+ }
719
+ switch (u) {
720
+ case 'turn':
721
+ v = reduceNumber(angle);
722
+ if (v.length + 4 < value.length) {
723
+ val = v;
724
+ unit = u;
725
+ value = v + u;
726
+ }
727
+ break;
728
+ case 'deg':
729
+ v = reduceNumber(angle * 360);
730
+ if (v.length + 3 < value.length) {
731
+ val = v;
732
+ unit = u;
733
+ value = v + u;
734
+ }
735
+ break;
736
+ case 'rad':
737
+ v = reduceNumber(angle * (2 * Math.PI));
738
+ if (v.length + 3 < value.length) {
739
+ val = v;
740
+ unit = u;
741
+ value = v + u;
742
+ }
743
+ break;
744
+ case 'grad':
745
+ v = reduceNumber(angle * 400);
746
+ if (v.length + 4 < value.length) {
747
+ val = v;
748
+ unit = u;
749
+ value = v + u;
750
+ }
751
+ break;
752
+ }
753
+ }
754
+ }
755
+ if (val === '0') {
756
+ if (token.typ == 'Time') {
757
+ return '0s';
758
+ }
759
+ if (token.typ == 'Frequency') {
760
+ return '0Hz';
761
+ }
762
+ // @ts-ignore
763
+ if (token.typ == 'Resolution') {
764
+ return '0x';
765
+ }
766
+ return '0';
767
+ }
768
+ return val + unit;
769
+ case 'Perc':
770
+ return token.val + '%';
771
+ case 'Number':
772
+ const num = (+token.val).toString();
773
+ if (token.val.length < num.length) {
774
+ return token.val;
775
+ }
776
+ if (num.charAt(0) === '0' && num.length > 1) {
777
+ return num.slice(1);
778
+ }
779
+ const slice = num.slice(0, 2);
780
+ if (slice == '-0') {
781
+ return '-' + num.slice(2);
782
+ }
783
+ return num;
784
+ case 'Comment':
785
+ if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
786
+ return '';
787
+ }
788
+ case 'Url-token':
789
+ case 'At-rule':
790
+ case 'Hash':
791
+ case 'Pseudo-class':
792
+ case 'Literal':
793
+ case 'String':
794
+ case 'Iden':
795
+ case 'Delim':
796
+ return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
1398
797
  }
1399
- // @ts-ignore
1400
- if (token.chi.length == 7) {
1401
- // @ts-ignore
1402
- t = token.chi[6];
798
+ console.error(`unexpected token ${JSON.stringify(token, null, 1)}`);
799
+ // throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
800
+ return '';
801
+ }
802
+
803
+ // https://www.w3.org/TR/CSS21/syndata.html#syntax
804
+ // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
805
+ // '\\'
806
+ const REVERSE_SOLIDUS = 0x5c;
807
+ const dimensionUnits = [
808
+ 'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
809
+ 'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
810
+ 'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
811
+ 'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
812
+ ];
813
+ function isLength(dimension) {
814
+ return 'unit' in dimension && dimensionUnits.includes(dimension.unit.toLowerCase());
815
+ }
816
+ function isResolution(dimension) {
817
+ return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
818
+ }
819
+ function isAngle(dimension) {
820
+ return 'unit' in dimension && ['rad', 'turn', 'deg', 'grad'].includes(dimension.unit.toLowerCase());
821
+ }
822
+ function isTime(dimension) {
823
+ return 'unit' in dimension && ['ms', 's'].includes(dimension.unit.toLowerCase());
824
+ }
825
+ function isFrequency(dimension) {
826
+ return 'unit' in dimension && ['hz', 'khz'].includes(dimension.unit.toLowerCase());
827
+ }
828
+ function isColor(token) {
829
+ if (token.typ == 'Color') {
830
+ return true;
831
+ }
832
+ if (token.typ == 'Iden') {
833
+ // named color
834
+ return token.val.toLowerCase() in COLORS_NAMES;
835
+ }
836
+ if (token.typ == 'Func' && token.chi.length > 0 && colorsFunc.includes(token.val)) {
1403
837
  // @ts-ignore
1404
- if ((t.typ == 'Number' && t.val < 1) ||
1405
- // @ts-ignore
1406
- (t.typ == 'Perc' && t.val < 100)) {
1407
- // @ts-ignore
1408
- value += Math.round(255 * (t.typ == 'Perc' ? t.val / 100 : t.val)).toString(16).padStart(2, '0');
838
+ for (const v of token.chi) {
839
+ if (!['Number', 'Perc', 'Comma', 'Whitespace'].includes(v.typ)) {
840
+ return false;
841
+ }
1409
842
  }
843
+ return true;
1410
844
  }
1411
- return value;
845
+ return false;
1412
846
  }
1413
- function hsl2Hex(token) {
1414
- let t;
1415
- // @ts-ignore
1416
- let h = getAngle(token.chi[0]);
1417
- // @ts-ignore
1418
- t = token.chi[2];
1419
- // @ts-ignore
1420
- let s = t.typ == 'Perc' ? t.val / 100 : t.val;
1421
- // @ts-ignore
1422
- t = token.chi[4];
1423
- // @ts-ignore
1424
- let l = t.typ == 'Perc' ? t.val / 100 : t.val;
1425
- let a = null;
1426
- if (token.chi?.length == 7) {
1427
- // @ts-ignore
1428
- t = token.chi[6];
1429
- // @ts-ignore
1430
- if ((t.typ == 'Perc' && t.val < 100) ||
1431
- // @ts-ignore
1432
- (t.typ == 'Number' && t.val < 1)) {
1433
- // @ts-ignore
1434
- a = (t.typ == 'Perc' ? t.val / 100 : t.val);
847
+ function isLetter(codepoint) {
848
+ // lowercase
849
+ return (codepoint >= 0x61 && codepoint <= 0x7a) ||
850
+ // uppercase
851
+ (codepoint >= 0x41 && codepoint <= 0x5a);
852
+ }
853
+ function isNonAscii(codepoint) {
854
+ return codepoint >= 0x80;
855
+ }
856
+ function isIdentStart(codepoint) {
857
+ // _
858
+ return codepoint == 0x5f || isLetter(codepoint) || isNonAscii(codepoint);
859
+ }
860
+ function isDigit(codepoint) {
861
+ return codepoint >= 0x30 && codepoint <= 0x39;
862
+ }
863
+ function isIdentCodepoint(codepoint) {
864
+ // -
865
+ return codepoint == 0x2d || isDigit(codepoint) || isIdentStart(codepoint);
866
+ }
867
+ function isIdent(name) {
868
+ const j = name.length - 1;
869
+ let i = 0;
870
+ let codepoint = name.charCodeAt(0);
871
+ // -
872
+ if (codepoint == 0x2d) {
873
+ const nextCodepoint = name.charCodeAt(1);
874
+ if (Number.isNaN(nextCodepoint)) {
875
+ return false;
876
+ }
877
+ // -
878
+ if (nextCodepoint == 0x2d) {
879
+ return true;
1435
880
  }
881
+ if (nextCodepoint == REVERSE_SOLIDUS) {
882
+ return name.length > 2 && !isNewLine(name.charCodeAt(2));
883
+ }
884
+ return true;
1436
885
  }
1437
- return `#${hsl2rgb(h, s, l, a).reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
886
+ if (!isIdentStart(codepoint)) {
887
+ return false;
888
+ }
889
+ while (i < j) {
890
+ i += codepoint < 0x80 ? 1 : String.fromCodePoint(codepoint).length;
891
+ codepoint = name.charCodeAt(i);
892
+ if (!isIdentCodepoint(codepoint)) {
893
+ return false;
894
+ }
895
+ }
896
+ return true;
1438
897
  }
1439
- function hwb2hex(token) {
1440
- let t;
1441
- // @ts-ignore
1442
- let h = getAngle(token.chi[0]);
1443
- // @ts-ignore
1444
- t = token.chi[2];
1445
- // @ts-ignore
1446
- let white = t.typ == 'Perc' ? t.val / 100 : t.val;
1447
- // @ts-ignore
1448
- t = token.chi[4];
1449
- // @ts-ignore
1450
- let black = t.typ == 'Perc' ? t.val / 100 : t.val;
1451
- let a = null;
1452
- if (token.chi?.length == 7) {
1453
- // @ts-ignore
1454
- t = token.chi[6];
1455
- // @ts-ignore
1456
- if ((t.typ == 'Perc' && t.val < 100) ||
1457
- // @ts-ignore
1458
- (t.typ == 'Number' && t.val < 1)) {
1459
- // @ts-ignore
1460
- a = (t.typ == 'Perc' ? t.val / 100 : t.val);
898
+ function isPseudo(name) {
899
+ return name.charAt(0) == ':' &&
900
+ ((name.endsWith('(') && isIdent(name.charAt(1) == ':' ? name.slice(2, -1) : name.slice(1, -1))) ||
901
+ isIdent(name.charAt(1) == ':' ? name.slice(2) : name.slice(1)));
902
+ }
903
+ function isHash(name) {
904
+ return name.charAt(0) == '#' && isIdent(name.charAt(1));
905
+ }
906
+ function isNumber(name) {
907
+ if (name.length == 0) {
908
+ return false;
909
+ }
910
+ let codepoint = name.charCodeAt(0);
911
+ let i = 0;
912
+ const j = name.length;
913
+ if (j == 1 && !isDigit(codepoint)) {
914
+ return false;
915
+ }
916
+ // '+' '-'
917
+ if ([0x2b, 0x2d].includes(codepoint)) {
918
+ i++;
919
+ }
920
+ // consume digits
921
+ while (i < j) {
922
+ codepoint = name.charCodeAt(i);
923
+ if (isDigit(codepoint)) {
924
+ i++;
925
+ continue;
926
+ }
927
+ // '.' 'E' 'e'
928
+ if (codepoint == 0x2e || codepoint == 0x45 || codepoint == 0x65) {
929
+ break;
930
+ }
931
+ return false;
932
+ }
933
+ // '.'
934
+ if (codepoint == 0x2e) {
935
+ if (!isDigit(name.charCodeAt(++i))) {
936
+ return false;
937
+ }
938
+ }
939
+ while (i < j) {
940
+ codepoint = name.charCodeAt(i);
941
+ if (isDigit(codepoint)) {
942
+ i++;
943
+ continue;
944
+ }
945
+ // 'E' 'e'
946
+ if (codepoint == 0x45 || codepoint == 0x65) {
947
+ i++;
948
+ break;
949
+ }
950
+ return false;
951
+ }
952
+ // 'E' 'e'
953
+ if (codepoint == 0x45 || codepoint == 0x65) {
954
+ if (i == j) {
955
+ return false;
956
+ }
957
+ codepoint = name.charCodeAt(i + 1);
958
+ // '+' '-'
959
+ if ([0x2b, 0x2d].includes(codepoint)) {
960
+ i++;
961
+ }
962
+ codepoint = name.charCodeAt(i + 1);
963
+ if (!isDigit(codepoint)) {
964
+ return false;
965
+ }
966
+ }
967
+ while (++i < j) {
968
+ codepoint = name.charCodeAt(i);
969
+ if (!isDigit(codepoint)) {
970
+ return false;
1461
971
  }
1462
972
  }
1463
- const rgb = hsl2rgb(h, 1, .5, a);
1464
- let value;
1465
- for (let i = 0; i < 3; i++) {
1466
- value = rgb[i] / 255;
1467
- value *= (1 - white - black);
1468
- value += white;
1469
- rgb[i] = Math.round(value * 255);
973
+ return true;
974
+ }
975
+ function isDimension(name) {
976
+ let index = name.length;
977
+ while (index--) {
978
+ if (isLetter(name.charCodeAt(index))) {
979
+ continue;
980
+ }
981
+ index++;
982
+ break;
1470
983
  }
1471
- return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
984
+ const number = name.slice(0, index);
985
+ return number.length > 0 && isIdentStart(name.charCodeAt(index)) && isNumber(number);
1472
986
  }
1473
- function cmyk2hex(token) {
1474
- // @ts-ignore
1475
- let t = token.chi[0];
1476
- // @ts-ignore
1477
- const c = t.typ == 'Perc' ? t.val / 100 : t.val;
1478
- // @ts-ignore
1479
- t = token.chi[2];
1480
- // @ts-ignore
1481
- const m = t.typ == 'Perc' ? t.val / 100 : t.val;
1482
- // @ts-ignore
1483
- t = token.chi[4];
1484
- // @ts-ignore
1485
- const y = t.typ == 'Perc' ? t.val / 100 : t.val;
1486
- // @ts-ignore
1487
- t = token.chi[6];
1488
- // @ts-ignore
1489
- const k = t.typ == 'Perc' ? t.val / 100 : t.val;
1490
- const rgb = [
1491
- Math.round(255 * (1 - Math.min(1, c * (1 - k) + k))),
1492
- Math.round(255 * (1 - Math.min(1, m * (1 - k) + k))),
1493
- Math.round(255 * (1 - Math.min(1, y * (1 - k) + k)))
1494
- ];
1495
- // @ts-ignore
1496
- if (token.chi.length >= 9) {
987
+ function isPercentage(name) {
988
+ return name.endsWith('%') && isNumber(name.slice(0, -1));
989
+ }
990
+ function parseDimension(name) {
991
+ let index = name.length;
992
+ while (index--) {
993
+ if (isLetter(name.charCodeAt(index))) {
994
+ continue;
995
+ }
996
+ index++;
997
+ break;
998
+ }
999
+ const dimension = { typ: 'Dimension', val: name.slice(0, index), unit: name.slice(index) };
1000
+ if (isAngle(dimension)) {
1497
1001
  // @ts-ignore
1498
- t = token.chi[8];
1002
+ dimension.typ = 'Angle';
1003
+ }
1004
+ else if (isLength(dimension)) {
1499
1005
  // @ts-ignore
1500
- rgb.push(Math.round(255 * (t.typ == 'Perc' ? t.val / 100 : t.val)));
1006
+ dimension.typ = 'Length';
1501
1007
  }
1502
- return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
1503
- }
1504
- function getAngle(token) {
1505
- if (token.typ == 'Dimension') {
1506
- switch (token.unit) {
1507
- case 'deg':
1508
- // @ts-ignore
1509
- return token.val / 360;
1510
- case 'rad':
1511
- // @ts-ignore
1512
- return token.val / (2 * Math.PI);
1513
- case 'grad':
1514
- // @ts-ignore
1515
- return token.val / 400;
1516
- case 'turn':
1517
- // @ts-ignore
1518
- return +token.val;
1519
- }
1008
+ else if (isTime(dimension)) {
1009
+ // @ts-ignore
1010
+ dimension.typ = 'Time';
1520
1011
  }
1521
- // @ts-ignore
1522
- return token.val / 360;
1523
- }
1524
- function hsl2rgb(h, s, l, a = null) {
1525
- let v = l <= .5 ? l * (1.0 + s) : l + s - l * s;
1526
- let r = l;
1527
- let g = l;
1528
- let b = l;
1529
- if (v > 0) {
1530
- let m = l + l - v;
1531
- let sv = (v - m) / v;
1532
- h *= 6.0;
1533
- let sextant = Math.floor(h);
1534
- let fract = h - sextant;
1535
- let vsf = v * sv * fract;
1536
- let mid1 = m + vsf;
1537
- let mid2 = v - vsf;
1538
- switch (sextant) {
1539
- case 0:
1540
- r = v;
1541
- g = mid1;
1542
- b = m;
1543
- break;
1544
- case 1:
1545
- r = mid2;
1546
- g = v;
1547
- b = m;
1548
- break;
1549
- case 2:
1550
- r = m;
1551
- g = v;
1552
- b = mid1;
1553
- break;
1554
- case 3:
1555
- r = m;
1556
- g = mid2;
1557
- b = v;
1558
- break;
1559
- case 4:
1560
- r = mid1;
1561
- g = m;
1562
- b = v;
1563
- break;
1564
- case 5:
1565
- r = v;
1566
- g = m;
1567
- b = mid2;
1568
- break;
1012
+ else if (isResolution(dimension)) {
1013
+ // @ts-ignore
1014
+ dimension.typ = 'Resolution';
1015
+ if (dimension.unit == 'dppx') {
1016
+ dimension.unit = 'x';
1569
1017
  }
1570
1018
  }
1571
- const values = [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
1572
- if (a != null && a != 1) {
1573
- values.push(Math.round(a * 255));
1019
+ else if (isFrequency(dimension)) {
1020
+ // @ts-ignore
1021
+ dimension.typ = 'Frequency';
1574
1022
  }
1575
- return values;
1023
+ return dimension;
1576
1024
  }
1577
-
1578
- function render(data, opt = {}) {
1579
- const startTime = performance.now();
1580
- const options = Object.assign(opt.minify ?? true ? {
1581
- indent: '',
1582
- newLine: '',
1583
- removeComments: true
1584
- } : {
1585
- indent: ' ',
1586
- newLine: '\n',
1587
- compress: false,
1588
- removeComments: false,
1589
- }, { colorConvert: true, preserveLicense: false }, opt);
1590
- function reducer(acc, curr, index, original) {
1591
- if (curr.typ == 'Comment' && options.removeComments) {
1592
- if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1593
- return acc;
1594
- }
1025
+ function isHexColor(name) {
1026
+ if (name.charAt(0) != '#' || ![4, 5, 7, 9].includes(name.length)) {
1027
+ return false;
1028
+ }
1029
+ for (let chr of name.slice(1)) {
1030
+ let codepoint = chr.charCodeAt(0);
1031
+ if (!isDigit(codepoint) &&
1032
+ // A-F
1033
+ !(codepoint >= 0x41 && codepoint <= 0x46) &&
1034
+ // a-f
1035
+ !(codepoint >= 0x61 && codepoint <= 0x66)) {
1036
+ return false;
1595
1037
  }
1596
- return acc + renderToken(curr, options);
1597
1038
  }
1598
- return { code: doRender(data, options, reducer, 0), stats: {
1599
- total: `${(performance.now() - startTime).toFixed(2)}ms`
1600
- } };
1039
+ return true;
1601
1040
  }
1602
- // @ts-ignore
1603
- function doRender(data, options, reducer, level = 0, indents = []) {
1604
- if (indents.length < level + 1) {
1605
- indents.push(options.indent.repeat(level));
1041
+ function isHexDigit(name) {
1042
+ if (name.length || name.length > 6) {
1043
+ return false;
1606
1044
  }
1607
- if (indents.length < level + 2) {
1608
- indents.push(options.indent.repeat(level + 1));
1045
+ for (let chr of name) {
1046
+ let codepoint = chr.charCodeAt(0);
1047
+ if (!isDigit(codepoint) &&
1048
+ // A F
1049
+ !(codepoint >= 0x41 && codepoint <= 0x46) &&
1050
+ // a f
1051
+ !(codepoint >= 0x61 && codepoint <= 0x66)) {
1052
+ return false;
1053
+ }
1609
1054
  }
1610
- const indent = indents[level];
1611
- const indentSub = indents[level + 1];
1612
- switch (data.typ) {
1613
- case 'Declaration':
1614
- return `${data.nam}:${options.indent}${data.val.reduce((acc, curr) => acc + renderToken(curr), '')}`;
1615
- case 'Comment':
1616
- return options.removeComments ? '' : data.val;
1617
- case 'StyleSheet':
1618
- return data.chi.reduce((css, node) => {
1619
- const str = doRender(node, options, reducer, level, indents);
1620
- if (str === '') {
1621
- return css;
1622
- }
1623
- if (css === '') {
1624
- return str;
1625
- }
1626
- return `${css}${options.newLine}${str}`;
1627
- }, '');
1628
- case 'AtRule':
1629
- case 'Rule':
1630
- if (data.typ == 'AtRule' && !('chi' in data)) {
1631
- return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
1632
- }
1633
- // @ts-ignore
1634
- let children = data.chi.reduce((css, node) => {
1635
- let str;
1636
- if (node.typ == 'Comment') {
1637
- str = options.removeComments ? '' : node.val;
1638
- }
1639
- else if (node.typ == 'Declaration') {
1640
- if (node.val.length == 0) {
1641
- console.error(`invalid declaration`, node);
1642
- return '';
1643
- }
1644
- str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`;
1645
- }
1646
- else if (node.typ == 'AtRule' && !('chi' in node)) {
1647
- str = `${data.val === '' ? '' : options.indent || ' '}${data.val};`;
1648
- }
1649
- else {
1650
- str = doRender(node, options, reducer, level + 1, indents);
1651
- }
1652
- if (css === '') {
1653
- return str;
1654
- }
1655
- if (str === '') {
1656
- return css;
1657
- }
1658
- return `${css}${options.newLine}${indentSub}${str}`;
1659
- }, '');
1660
- if (children.endsWith(';')) {
1661
- children = children.slice(0, -1);
1662
- }
1663
- if (data.typ == 'AtRule') {
1664
- return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
1665
- }
1666
- return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
1055
+ return true;
1056
+ }
1057
+ function isFunction(name) {
1058
+ return name.endsWith('(') && isIdent(name.slice(0, -1));
1059
+ }
1060
+ function isAtKeyword(name) {
1061
+ return name.charCodeAt(0) == 0x40 && isIdent(name.slice(1));
1062
+ }
1063
+ function isNewLine(codepoint) {
1064
+ // \n \r \f
1065
+ return codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
1066
+ }
1067
+ function isWhiteSpace(codepoint) {
1068
+ return codepoint == 0x9 || codepoint == 0x20 ||
1069
+ // isNewLine
1070
+ codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
1071
+ }
1072
+
1073
+ var properties = {
1074
+ inset: {
1075
+ shorthand: "inset",
1076
+ properties: [
1077
+ "top",
1078
+ "right",
1079
+ "bottom",
1080
+ "left"
1081
+ ],
1082
+ types: [
1083
+ "Length",
1084
+ "Perc"
1085
+ ],
1086
+ multiple: false,
1087
+ separator: null,
1088
+ keywords: [
1089
+ "auto"
1090
+ ]
1091
+ },
1092
+ top: {
1093
+ shorthand: "inset"
1094
+ },
1095
+ right: {
1096
+ shorthand: "inset"
1097
+ },
1098
+ bottom: {
1099
+ shorthand: "inset"
1100
+ },
1101
+ left: {
1102
+ shorthand: "inset"
1103
+ },
1104
+ margin: {
1105
+ shorthand: "margin",
1106
+ properties: [
1107
+ "margin-top",
1108
+ "margin-right",
1109
+ "margin-bottom",
1110
+ "margin-left"
1111
+ ],
1112
+ types: [
1113
+ "Length",
1114
+ "Perc"
1115
+ ],
1116
+ multiple: false,
1117
+ separator: null,
1118
+ keywords: [
1119
+ "auto"
1120
+ ]
1121
+ },
1122
+ "margin-top": {
1123
+ shorthand: "margin"
1124
+ },
1125
+ "margin-right": {
1126
+ shorthand: "margin"
1127
+ },
1128
+ "margin-bottom": {
1129
+ shorthand: "margin"
1130
+ },
1131
+ "margin-left": {
1132
+ shorthand: "margin"
1133
+ },
1134
+ padding: {
1135
+ shorthand: "padding",
1136
+ properties: [
1137
+ "padding-top",
1138
+ "padding-right",
1139
+ "padding-bottom",
1140
+ "padding-left"
1141
+ ],
1142
+ types: [
1143
+ "Length",
1144
+ "Perc"
1145
+ ],
1146
+ keywords: [
1147
+ ]
1148
+ },
1149
+ "padding-top": {
1150
+ shorthand: "padding"
1151
+ },
1152
+ "padding-right": {
1153
+ shorthand: "padding"
1154
+ },
1155
+ "padding-bottom": {
1156
+ shorthand: "padding"
1157
+ },
1158
+ "padding-left": {
1159
+ shorthand: "padding"
1160
+ },
1161
+ "border-radius": {
1162
+ shorthand: "border-radius",
1163
+ properties: [
1164
+ "border-top-left-radius",
1165
+ "border-top-right-radius",
1166
+ "border-bottom-right-radius",
1167
+ "border-bottom-left-radius"
1168
+ ],
1169
+ types: [
1170
+ "Length",
1171
+ "Perc"
1172
+ ],
1173
+ multiple: true,
1174
+ separator: "/",
1175
+ keywords: [
1176
+ ]
1177
+ },
1178
+ "border-top-left-radius": {
1179
+ shorthand: "border-radius"
1180
+ },
1181
+ "border-top-right-radius": {
1182
+ shorthand: "border-radius"
1183
+ },
1184
+ "border-bottom-right-radius": {
1185
+ shorthand: "border-radius"
1186
+ },
1187
+ "border-bottom-left-radius": {
1188
+ shorthand: "border-radius"
1189
+ },
1190
+ "border-width": {
1191
+ shorthand: "border-width",
1192
+ map: "border",
1193
+ properties: [
1194
+ "border-top-width",
1195
+ "border-right-width",
1196
+ "border-bottom-width",
1197
+ "border-left-width"
1198
+ ],
1199
+ types: [
1200
+ "Length",
1201
+ "Perc"
1202
+ ],
1203
+ "default": [
1204
+ "medium"
1205
+ ],
1206
+ keywords: [
1207
+ "thin",
1208
+ "medium",
1209
+ "thick"
1210
+ ]
1211
+ },
1212
+ "border-top-width": {
1213
+ map: "border",
1214
+ shorthand: "border-width"
1215
+ },
1216
+ "border-right-width": {
1217
+ map: "border",
1218
+ shorthand: "border-width"
1219
+ },
1220
+ "border-bottom-width": {
1221
+ map: "border",
1222
+ shorthand: "border-width"
1223
+ },
1224
+ "border-left-width": {
1225
+ map: "border",
1226
+ shorthand: "border-width"
1227
+ },
1228
+ "border-style": {
1229
+ shorthand: "border-style",
1230
+ map: "border",
1231
+ properties: [
1232
+ "border-top-style",
1233
+ "border-right-style",
1234
+ "border-bottom-style",
1235
+ "border-left-style"
1236
+ ],
1237
+ types: [
1238
+ ],
1239
+ "default": [
1240
+ "none"
1241
+ ],
1242
+ keywords: [
1243
+ "none",
1244
+ "hidden",
1245
+ "dotted",
1246
+ "dashed",
1247
+ "solid",
1248
+ "double",
1249
+ "groove",
1250
+ "ridge",
1251
+ "inset",
1252
+ "outset"
1253
+ ]
1254
+ },
1255
+ "border-top-style": {
1256
+ map: "border",
1257
+ shorthand: "border-style"
1258
+ },
1259
+ "border-right-style": {
1260
+ map: "border",
1261
+ shorthand: "border-style"
1262
+ },
1263
+ "border-bottom-style": {
1264
+ map: "border",
1265
+ shorthand: "border-style"
1266
+ },
1267
+ "border-left-style": {
1268
+ map: "border",
1269
+ shorthand: "border-style"
1270
+ },
1271
+ "border-color": {
1272
+ shorthand: "border-color",
1273
+ map: "border",
1274
+ properties: [
1275
+ "border-top-color",
1276
+ "border-right-color",
1277
+ "border-bottom-color",
1278
+ "border-left-color"
1279
+ ],
1280
+ types: [
1281
+ "Color"
1282
+ ],
1283
+ "default": [
1284
+ "currentcolor"
1285
+ ],
1286
+ keywords: [
1287
+ ]
1288
+ },
1289
+ "border-top-color": {
1290
+ map: "border",
1291
+ shorthand: "border-color"
1292
+ },
1293
+ "border-right-color": {
1294
+ map: "border",
1295
+ shorthand: "border-color"
1296
+ },
1297
+ "border-bottom-color": {
1298
+ map: "border",
1299
+ shorthand: "border-color"
1300
+ },
1301
+ "border-left-color": {
1302
+ map: "border",
1303
+ shorthand: "border-color"
1304
+ }
1305
+ };
1306
+ var map = {
1307
+ border: {
1308
+ shorthand: "border",
1309
+ pattern: "border-color border-style border-width",
1310
+ keywords: [
1311
+ "none"
1312
+ ],
1313
+ "default": [
1314
+ "0",
1315
+ "none"
1316
+ ],
1317
+ properties: {
1318
+ "border-color": {
1319
+ types: [
1320
+ "Color"
1321
+ ],
1322
+ "default": [
1323
+ "currentcolor"
1324
+ ],
1325
+ keywords: [
1326
+ ]
1327
+ },
1328
+ "border-style": {
1329
+ types: [
1330
+ ],
1331
+ "default": [
1332
+ "none"
1333
+ ],
1334
+ keywords: [
1335
+ "none",
1336
+ "hidden",
1337
+ "dotted",
1338
+ "dashed",
1339
+ "solid",
1340
+ "double",
1341
+ "groove",
1342
+ "ridge",
1343
+ "inset",
1344
+ "outset"
1345
+ ]
1346
+ },
1347
+ "border-width": {
1348
+ types: [
1349
+ "Length",
1350
+ "Perc"
1351
+ ],
1352
+ "default": [
1353
+ "medium"
1354
+ ],
1355
+ keywords: [
1356
+ "thin",
1357
+ "medium",
1358
+ "thick"
1359
+ ]
1360
+ }
1361
+ }
1362
+ },
1363
+ "border-color": {
1364
+ shorthand: "border"
1365
+ },
1366
+ "border-style": {
1367
+ shorthand: "border"
1368
+ },
1369
+ "border-width": {
1370
+ shorthand: "border"
1371
+ },
1372
+ outline: {
1373
+ shorthand: "outline",
1374
+ pattern: "outline-color outline-style outline-width",
1375
+ keywords: [
1376
+ "none"
1377
+ ],
1378
+ "default": [
1379
+ "0",
1380
+ "none"
1381
+ ],
1382
+ properties: {
1383
+ "outline-color": {
1384
+ types: [
1385
+ "Color"
1386
+ ],
1387
+ "default": [
1388
+ "currentColor"
1389
+ ],
1390
+ keywords: [
1391
+ "currentColor"
1392
+ ]
1393
+ },
1394
+ "outline-style": {
1395
+ types: [
1396
+ ],
1397
+ "default": [
1398
+ "none"
1399
+ ],
1400
+ keywords: [
1401
+ "auto",
1402
+ "none",
1403
+ "dotted",
1404
+ "dashed",
1405
+ "solid",
1406
+ "double",
1407
+ "groove",
1408
+ "ridge",
1409
+ "inset",
1410
+ "outset"
1411
+ ]
1412
+ },
1413
+ "outline-width": {
1414
+ types: [
1415
+ "Length",
1416
+ "Perc"
1417
+ ],
1418
+ "default": [
1419
+ "medium"
1420
+ ],
1421
+ keywords: [
1422
+ "thin",
1423
+ "medium",
1424
+ "thick"
1425
+ ]
1426
+ }
1427
+ }
1428
+ },
1429
+ "outline-color": {
1430
+ shorthand: "outline"
1431
+ },
1432
+ "outline-style": {
1433
+ shorthand: "outline"
1434
+ },
1435
+ "outline-width": {
1436
+ shorthand: "outline"
1437
+ },
1438
+ font: {
1439
+ shorthand: "font",
1440
+ pattern: "font-weight font-style font-size line-height font-stretch font-variant font-family",
1441
+ keywords: [
1442
+ "caption",
1443
+ "icon",
1444
+ "menu",
1445
+ "message-box",
1446
+ "small-caption",
1447
+ "status-bar",
1448
+ "-moz-window, ",
1449
+ "-moz-document, ",
1450
+ "-moz-desktop, ",
1451
+ "-moz-info, ",
1452
+ "-moz-dialog",
1453
+ "-moz-button",
1454
+ "-moz-pull-down-menu",
1455
+ "-moz-list",
1456
+ "-moz-field"
1457
+ ],
1458
+ "default": [
1459
+ ],
1460
+ properties: {
1461
+ "font-weight": {
1462
+ types: [
1463
+ "Number"
1464
+ ],
1465
+ "default": [
1466
+ "normal",
1467
+ "400"
1468
+ ],
1469
+ keywords: [
1470
+ "normal",
1471
+ "bold",
1472
+ "lighter",
1473
+ "bolder"
1474
+ ],
1475
+ constraints: {
1476
+ value: {
1477
+ min: "1",
1478
+ max: "1000"
1479
+ }
1480
+ },
1481
+ mapping: {
1482
+ thin: "100",
1483
+ hairline: "100",
1484
+ "extra light": "200",
1485
+ "ultra light": "200",
1486
+ light: "300",
1487
+ normal: "400",
1488
+ regular: "400",
1489
+ medium: "500",
1490
+ "semi bold": "600",
1491
+ "demi bold": "600",
1492
+ bold: "700",
1493
+ "extra bold": "800",
1494
+ "ultra bold": "800",
1495
+ black: "900",
1496
+ heavy: "900",
1497
+ "extra black": "950",
1498
+ "ultra black": "950"
1499
+ }
1500
+ },
1501
+ "font-style": {
1502
+ types: [
1503
+ "Angle"
1504
+ ],
1505
+ "default": [
1506
+ "normal"
1507
+ ],
1508
+ keywords: [
1509
+ "normal",
1510
+ "italic",
1511
+ "oblique"
1512
+ ]
1513
+ },
1514
+ "font-size": {
1515
+ types: [
1516
+ "Length",
1517
+ "Perc"
1518
+ ],
1519
+ "default": [
1520
+ ],
1521
+ keywords: [
1522
+ "xx-small",
1523
+ "x-small",
1524
+ "small",
1525
+ "medium",
1526
+ "large",
1527
+ "x-large",
1528
+ "xx-large",
1529
+ "xxx-large",
1530
+ "larger",
1531
+ "smaller"
1532
+ ],
1533
+ required: true
1534
+ },
1535
+ "line-height": {
1536
+ types: [
1537
+ "Length",
1538
+ "Perc",
1539
+ "Number"
1540
+ ],
1541
+ "default": [
1542
+ "normal"
1543
+ ],
1544
+ keywords: [
1545
+ "normal"
1546
+ ],
1547
+ previous: "font-size",
1548
+ prefix: {
1549
+ typ: "Literal",
1550
+ val: "/"
1551
+ }
1552
+ },
1553
+ "font-stretch": {
1554
+ types: [
1555
+ "Perc"
1556
+ ],
1557
+ "default": [
1558
+ "normal"
1559
+ ],
1560
+ keywords: [
1561
+ "ultra-condensed",
1562
+ "extra-condensed",
1563
+ "condensed",
1564
+ "semi-condensed",
1565
+ "normal",
1566
+ "semi-expanded",
1567
+ "expanded",
1568
+ "extra-expanded",
1569
+ "ultra-expanded"
1570
+ ],
1571
+ mapping: {
1572
+ "ultra-condensed": "50%",
1573
+ "extra-condensed": "62.5%",
1574
+ condensed: "75%",
1575
+ "semi-condensed": "87.5%",
1576
+ normal: "100%",
1577
+ "semi-expanded": "112.5%",
1578
+ expanded: "125%",
1579
+ "extra-expanded": "150%",
1580
+ "ultra-expanded": "200%"
1581
+ }
1582
+ },
1583
+ "font-variant": {
1584
+ types: [
1585
+ ],
1586
+ "default": [
1587
+ "normal"
1588
+ ],
1589
+ keywords: [
1590
+ "normal",
1591
+ "none",
1592
+ "common-ligatures",
1593
+ "no-common-ligatures",
1594
+ "discretionary-ligatures",
1595
+ "no-discretionary-ligatures",
1596
+ "historical-ligatures",
1597
+ "no-historical-ligatures",
1598
+ "contextual",
1599
+ "no-contextual",
1600
+ "historical-forms",
1601
+ "small-caps",
1602
+ "all-small-caps",
1603
+ "petite-caps",
1604
+ "all-petite-caps",
1605
+ "unicase",
1606
+ "titling-caps",
1607
+ "ordinal",
1608
+ "slashed-zero",
1609
+ "lining-nums",
1610
+ "oldstyle-nums",
1611
+ "proportional-nums",
1612
+ "tabular-nums",
1613
+ "diagonal-fractions",
1614
+ "stacked-fractions",
1615
+ "ordinal",
1616
+ "slashed-zero",
1617
+ "ruby",
1618
+ "jis78",
1619
+ "jis83",
1620
+ "jis90",
1621
+ "jis04",
1622
+ "simplified",
1623
+ "traditional",
1624
+ "full-width",
1625
+ "proportional-width",
1626
+ "ruby",
1627
+ "sub",
1628
+ "super",
1629
+ "text",
1630
+ "emoji",
1631
+ "unicode"
1632
+ ]
1633
+ },
1634
+ "font-family": {
1635
+ types: [
1636
+ "String",
1637
+ "Iden"
1638
+ ],
1639
+ "default": [
1640
+ ],
1641
+ keywords: [
1642
+ "serif",
1643
+ "sans-serif",
1644
+ "monospace",
1645
+ "cursive",
1646
+ "fantasy",
1647
+ "system-ui",
1648
+ "ui-serif",
1649
+ "ui-sans-serif",
1650
+ "ui-monospace",
1651
+ "ui-rounded",
1652
+ "math",
1653
+ "emoji",
1654
+ "fangsong"
1655
+ ],
1656
+ required: true,
1657
+ multiple: true,
1658
+ separator: {
1659
+ typ: "Comma"
1660
+ }
1661
+ }
1662
+ }
1663
+ },
1664
+ "font-weight": {
1665
+ shorthand: "font"
1666
+ },
1667
+ "font-style": {
1668
+ shorthand: "font"
1669
+ },
1670
+ "font-size": {
1671
+ shorthand: "font"
1672
+ },
1673
+ "line-height": {
1674
+ shorthand: "font"
1675
+ },
1676
+ "font-stretch": {
1677
+ shorthand: "font"
1678
+ },
1679
+ "font-variant": {
1680
+ shorthand: "font"
1681
+ },
1682
+ "font-family": {
1683
+ shorthand: "font"
1684
+ },
1685
+ background: {
1686
+ shorthand: "background",
1687
+ pattern: "background-repeat background-color background-image background-attachment background-clip background-origin background-position background-size",
1688
+ keywords: [
1689
+ "none"
1690
+ ],
1691
+ "default": [
1692
+ ],
1693
+ multiple: true,
1694
+ separator: {
1695
+ typ: "Comma"
1696
+ },
1697
+ properties: {
1698
+ "background-repeat": {
1699
+ types: [
1700
+ ],
1701
+ "default": [
1702
+ "repeat"
1703
+ ],
1704
+ multiple: true,
1705
+ keywords: [
1706
+ "repeat-x",
1707
+ "repeat-y",
1708
+ "repeat",
1709
+ "space",
1710
+ "round",
1711
+ "no-repeat"
1712
+ ],
1713
+ mapping: {
1714
+ "repeat no-repeat": "repeat-x",
1715
+ "no-repeat repeat": "repeat-y",
1716
+ "repeat repeat": "repeat",
1717
+ "space space": "space",
1718
+ "round round": "round",
1719
+ "no-repeat no-repeat": "no-repeat"
1720
+ }
1721
+ },
1722
+ "background-color": {
1723
+ types: [
1724
+ "Color"
1725
+ ],
1726
+ "default": [
1727
+ "transparent"
1728
+ ],
1729
+ multiple: true,
1730
+ keywords: [
1731
+ ]
1732
+ },
1733
+ "background-image": {
1734
+ types: [
1735
+ "UrlFunc"
1736
+ ],
1737
+ "default": [
1738
+ "none"
1739
+ ],
1740
+ keywords: [
1741
+ "none"
1742
+ ]
1743
+ },
1744
+ "background-attachment": {
1745
+ types: [
1746
+ ],
1747
+ "default": [
1748
+ "scroll"
1749
+ ],
1750
+ multiple: true,
1751
+ keywords: [
1752
+ "scroll",
1753
+ "fixed",
1754
+ "local"
1755
+ ]
1756
+ },
1757
+ "background-clip": {
1758
+ types: [
1759
+ ],
1760
+ "default": [
1761
+ "border-box"
1762
+ ],
1763
+ multiple: true,
1764
+ keywords: [
1765
+ "border-box",
1766
+ "padding-box",
1767
+ "content-box",
1768
+ "text"
1769
+ ]
1770
+ },
1771
+ "background-origin": {
1772
+ types: [
1773
+ ],
1774
+ "default": [
1775
+ "padding-box"
1776
+ ],
1777
+ multiple: true,
1778
+ keywords: [
1779
+ "border-box",
1780
+ "padding-box",
1781
+ "content-box"
1782
+ ]
1783
+ },
1784
+ "background-position": {
1785
+ multiple: true,
1786
+ types: [
1787
+ "Perc",
1788
+ "Length"
1789
+ ],
1790
+ "default": [
1791
+ "0 0",
1792
+ "top left",
1793
+ "left top"
1794
+ ],
1795
+ keywords: [
1796
+ "top",
1797
+ "left",
1798
+ "center",
1799
+ "bottom",
1800
+ "right"
1801
+ ],
1802
+ mapping: {
1803
+ left: "0",
1804
+ top: "0",
1805
+ center: "50%",
1806
+ bottom: "100%",
1807
+ right: "100%"
1808
+ },
1809
+ constraints: {
1810
+ mapping: {
1811
+ max: 2
1812
+ }
1813
+ }
1814
+ },
1815
+ "background-size": {
1816
+ multiple: true,
1817
+ previous: "background-position",
1818
+ prefix: {
1819
+ typ: "Literal",
1820
+ val: "/"
1821
+ },
1822
+ types: [
1823
+ "Perc",
1824
+ "Length"
1825
+ ],
1826
+ "default": [
1827
+ "auto",
1828
+ "auto auto"
1829
+ ],
1830
+ keywords: [
1831
+ "auto",
1832
+ "cover",
1833
+ "contain"
1834
+ ],
1835
+ mapping: {
1836
+ "auto auto": "auto"
1837
+ }
1838
+ }
1839
+ }
1840
+ },
1841
+ "background-repeat": {
1842
+ shorthand: "background"
1843
+ },
1844
+ "background-color": {
1845
+ shorthand: "background"
1846
+ },
1847
+ "background-image": {
1848
+ shorthand: "background"
1849
+ },
1850
+ "background-attachment": {
1851
+ shorthand: "background"
1852
+ },
1853
+ "background-clip": {
1854
+ shorthand: "background"
1855
+ },
1856
+ "background-origin": {
1857
+ shorthand: "background"
1858
+ },
1859
+ "background-position": {
1860
+ shorthand: "background"
1861
+ },
1862
+ "background-size": {
1863
+ shorthand: "background"
1864
+ }
1865
+ };
1866
+ var config$1 = {
1867
+ properties: properties,
1868
+ map: map
1869
+ };
1870
+
1871
+ const getConfig = () => config$1;
1872
+
1873
+ const funcList = ['clamp', 'calc'];
1874
+ function matchType(val, properties) {
1875
+ if (val.typ == 'Iden' && properties.keywords.includes(val.val) ||
1876
+ (properties.types.includes(val.typ))) {
1877
+ return true;
1667
1878
  }
1668
- return '';
1669
- }
1670
- function renderToken(token, options = {}) {
1671
- switch (token.typ) {
1672
- case 'Color':
1673
- if (options.minify || options.colorConvert) {
1674
- if (token.kin == 'lit' && token.val.toLowerCase() == 'currentcolor') {
1675
- return 'currentcolor';
1676
- }
1677
- let value = token.kin == 'hex' ? token.val.toLowerCase() : (token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : '');
1678
- if (token.val == 'rgb' || token.val == 'rgba') {
1679
- value = rgb2Hex(token);
1680
- }
1681
- else if (token.val == 'hsl' || token.val == 'hsla') {
1682
- value = hsl2Hex(token);
1683
- }
1684
- else if (token.val == 'hwb') {
1685
- value = hwb2hex(token);
1686
- }
1687
- else if (token.val == 'device-cmyk') {
1688
- value = cmyk2hex(token);
1689
- }
1690
- const named_color = NAMES_COLORS[value];
1691
- if (value !== '') {
1692
- if (value.length == 7) {
1693
- if (value[1] == value[2] &&
1694
- value[3] == value[4] &&
1695
- value[5] == value[6]) {
1696
- value = `#${value[1]}${value[3]}${value[5]}`;
1697
- }
1698
- }
1699
- else if (value.length == 9) {
1700
- if (value[1] == value[2] &&
1701
- value[3] == value[4] &&
1702
- value[5] == value[6] &&
1703
- value[7] == value[8]) {
1704
- value = `#${value[1]}${value[3]}${value[5]}${value[7]}`;
1705
- }
1706
- }
1707
- return named_color != null && named_color.length <= value.length ? named_color : value;
1708
- }
1709
- }
1710
- if (token.kin == 'hex' || token.kin == 'lit') {
1711
- return token.val;
1712
- }
1713
- case 'Start-parens':
1714
- if (!('chi' in token)) {
1715
- return '(';
1716
- }
1717
- case 'Func':
1718
- case 'UrlFunc':
1719
- case 'Pseudo-class-func':
1720
- // @ts-ignore
1721
- return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
1722
- if (options.removeComments && curr.typ == 'Comment') {
1723
- if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1724
- return acc;
1725
- }
1726
- }
1727
- return acc + renderToken(curr, options);
1728
- }, '') + ')';
1729
- case 'Includes':
1730
- return '~=';
1731
- case 'Dash-match':
1732
- return '|=';
1733
- case 'Lt':
1734
- return '<';
1735
- case 'Gt':
1736
- return '>';
1737
- case 'End-parens':
1738
- return ')';
1739
- case 'Attr-start':
1740
- return '[';
1741
- case 'Attr-end':
1742
- return ']';
1743
- case 'Whitespace':
1744
- return ' ';
1745
- case 'Colon':
1746
- return ':';
1747
- case 'Semi-colon':
1748
- return ';';
1749
- case 'Comma':
1750
- return ',';
1751
- case 'Important':
1752
- return '!important';
1753
- case 'Attr':
1754
- return '[' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options), '') + ']';
1755
- case 'Time':
1756
- case 'Frequency':
1757
- case 'Angle':
1758
- case 'Length':
1759
- case 'Dimension':
1760
- const val = (+token.val).toString();
1761
- if (val === '0') {
1762
- if (token.typ == 'Time') {
1763
- return '0s';
1764
- }
1765
- if (token.typ == 'Frequency') {
1766
- return '0Hz';
1767
- }
1768
- // @ts-ignore
1769
- if (token.typ == 'Resolution') {
1770
- return '0x';
1771
- }
1772
- return '0';
1773
- }
1774
- const chr = val.charAt(0);
1775
- if (chr == '-') {
1776
- const slice = val.slice(0, 2);
1777
- if (slice == '-0') {
1778
- return (val.length == 2 ? '0' : '-' + val.slice(2)) + token.unit;
1779
- }
1780
- }
1781
- else if (chr == '0') {
1782
- return val.slice(1) + token.unit;
1783
- }
1784
- return val + token.unit;
1785
- case 'Perc':
1786
- return token.val + '%';
1787
- case 'Number':
1788
- const num = (+token.val).toString();
1789
- if (token.val.length < num.length) {
1790
- return token.val;
1791
- }
1792
- if (num.charAt(0) === '0' && num.length > 1) {
1793
- return num.slice(1);
1794
- }
1795
- const slice = num.slice(0, 2);
1796
- if (slice == '-0') {
1797
- return '-' + num.slice(2);
1798
- }
1799
- return num;
1800
- case 'Comment':
1801
- if (options.removeComments) {
1802
- return '';
1803
- }
1804
- case 'Url-token':
1805
- case 'At-rule':
1806
- case 'Hash':
1807
- case 'Pseudo-class':
1808
- case 'Literal':
1809
- case 'String':
1810
- case 'Iden':
1811
- case 'Delim':
1812
- return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
1879
+ if (val.typ == 'Number' && val.val == '0') {
1880
+ return properties.types.some(type => type == 'Length' || type == 'Angle');
1813
1881
  }
1814
- console.error(`unexpected token ${JSON.stringify(token, null, 1)}`);
1815
- // throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
1816
- return '';
1882
+ if (val.typ == 'Func' && funcList.includes(val.val)) {
1883
+ return val.chi.every((t => ['Literal', 'Comma', 'Whitespace', 'Start-parens', 'End-parens'].includes(t.typ) || matchType(t, properties)));
1884
+ }
1885
+ return false;
1817
1886
  }
1818
1887
 
1819
1888
  function eq(a, b) {
@@ -2069,6 +2138,7 @@ class PropertyMap {
2069
2138
  i--;
2070
2139
  continue;
2071
2140
  }
2141
+ // @ts-ignore
2072
2142
  if (('propertyName' in acc[i] && acc[i].propertyName == property) || matchType(acc[i], props)) {
2073
2143
  if ('prefix' in props && props.previous != null && !(props.previous in tokens)) {
2074
2144
  return acc;
@@ -2234,17 +2304,18 @@ class PropertyMap {
2234
2304
  if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
2235
2305
  continue;
2236
2306
  }
2237
- match = matchType(val, curr[1]);
2307
+ // @ts-ignore
2308
+ match = val.typ == 'Comment' || matchType(val, curr[1]);
2238
2309
  if (isShorthand) {
2239
2310
  isShorthand = match;
2240
2311
  }
2312
+ // @ts-ignore
2241
2313
  if (('propertyName' in val && val.propertyName == property) || match) {
2242
2314
  if (!(curr[0] in tokens)) {
2243
2315
  tokens[curr[0]] = [[]];
2244
2316
  }
2245
2317
  // is default value
2246
2318
  tokens[curr[0]][current].push(val);
2247
- // continue;
2248
2319
  }
2249
2320
  else {
2250
2321
  acc.push(curr[0]);
@@ -2261,7 +2332,9 @@ class PropertyMap {
2261
2332
  if (!isShorthand || Object.entries(this.config.properties).some(entry => {
2262
2333
  // missing required property
2263
2334
  return entry[1].required && !(entry[0] in tokens);
2264
- }) || !Object.values(tokens).every(v => v.length == count)) {
2335
+ }) ||
2336
+ // @ts-ignore
2337
+ !Object.values(tokens).every(v => v.filter(t => t.typ != 'Comment').length == count)) {
2265
2338
  // @ts-ignore
2266
2339
  iterable = this.declarations.values();
2267
2340
  }
@@ -2814,6 +2887,17 @@ function minify(ast, options = {}, recursive = false) {
2814
2887
  continue;
2815
2888
  // }
2816
2889
  }
2890
+ // @ts-ignore
2891
+ if (hasDeclaration(node)) {
2892
+ // @ts-ignore
2893
+ minifyRule(node);
2894
+ }
2895
+ else {
2896
+ minify(node, options, recursive);
2897
+ }
2898
+ previous = node;
2899
+ nodeIndex = i;
2900
+ continue;
2817
2901
  }
2818
2902
  // @ts-ignore
2819
2903
  if (node.typ == 'Rule') {
@@ -3328,11 +3412,6 @@ function* tokenize(iterator) {
3328
3412
  }
3329
3413
  buffer += quoteStr;
3330
3414
  while (value = peek()) {
3331
- // if (ind >= iterator.length) {
3332
- //
3333
- // yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
3334
- // break;
3335
- // }
3336
3415
  if (value == '\\') {
3337
3416
  const sequence = peek(6);
3338
3417
  let escapeSequence = '';
@@ -3352,9 +3431,23 @@ function* tokenize(iterator) {
3352
3431
  }
3353
3432
  break;
3354
3433
  }
3434
+ // @ts-ignore
3435
+ if (isNewLine(codepoint)) {
3436
+ if (i == 1) {
3437
+ buffer += value + escapeSequence.slice(0, i);
3438
+ next(i + 1);
3439
+ continue;
3440
+ }
3441
+ // else {
3442
+ yield pushToken(buffer + value + escapeSequence.slice(0, i), 'Bad-string');
3443
+ buffer = '';
3444
+ // }
3445
+ next(i + 1);
3446
+ break;
3447
+ }
3355
3448
  // not hex or new line
3356
3449
  // @ts-ignore
3357
- if (i == 1 && !isNewLine(codepoint)) {
3450
+ else if (i == 1) {
3358
3451
  buffer += value + sequence[i];
3359
3452
  next(2);
3360
3453
  continue;
@@ -3374,13 +3467,6 @@ function* tokenize(iterator) {
3374
3467
  next(escapeSequence.length + 1);
3375
3468
  continue;
3376
3469
  }
3377
- // buffer += value;
3378
- // if (ind >= iterator.length) {
3379
- //
3380
- // // drop '\\' at the end
3381
- // yield pushToken(buffer);
3382
- // break;
3383
- // }
3384
3470
  buffer += next(2);
3385
3471
  continue;
3386
3472
  }
@@ -3390,20 +3476,28 @@ function* tokenize(iterator) {
3390
3476
  next();
3391
3477
  // i += value.length;
3392
3478
  buffer = '';
3393
- break;
3479
+ return;
3394
3480
  }
3395
3481
  if (isNewLine(value.charCodeAt(0))) {
3396
3482
  hasNewLine = true;
3397
3483
  }
3398
3484
  if (hasNewLine && value == ';') {
3399
- yield pushToken(buffer, 'Bad-string');
3485
+ yield pushToken(buffer + value, 'Bad-string');
3400
3486
  buffer = '';
3487
+ next();
3401
3488
  break;
3402
3489
  }
3403
3490
  buffer += value;
3404
- // i += value.length;
3405
3491
  next();
3406
3492
  }
3493
+ if (hasNewLine) {
3494
+ yield pushToken(buffer, 'Bad-string');
3495
+ }
3496
+ else {
3497
+ // EOF - 'Unclosed-string' fixed
3498
+ yield pushToken(buffer + quote, 'String');
3499
+ }
3500
+ buffer = '';
3407
3501
  }
3408
3502
  function peek(count = 1) {
3409
3503
  if (count == 1) {
@@ -3436,31 +3530,18 @@ function* tokenize(iterator) {
3436
3530
  return char;
3437
3531
  }
3438
3532
  while (value = next()) {
3439
- if (ind >= iterator.length) {
3440
- if (buffer.length > 0) {
3441
- yield pushToken(buffer);
3442
- buffer = '';
3443
- }
3444
- break;
3445
- }
3446
3533
  if (isWhiteSpace(value.charCodeAt(0))) {
3447
3534
  if (buffer.length > 0) {
3448
3535
  yield pushToken(buffer);
3449
3536
  buffer = '';
3450
3537
  }
3451
3538
  while (value = next()) {
3452
- if (ind >= iterator.length) {
3453
- break;
3454
- }
3455
3539
  if (!isWhiteSpace(value.charCodeAt(0))) {
3456
3540
  break;
3457
3541
  }
3458
3542
  }
3459
3543
  yield pushToken('', 'Whitespace');
3460
3544
  buffer = '';
3461
- if (ind >= iterator.length) {
3462
- break;
3463
- }
3464
3545
  }
3465
3546
  switch (value) {
3466
3547
  case '/':
@@ -3474,34 +3555,12 @@ function* tokenize(iterator) {
3474
3555
  }
3475
3556
  buffer += value;
3476
3557
  if (peek() == '*') {
3477
- buffer += '*';
3478
- // i++;
3479
- next();
3558
+ buffer += next();
3480
3559
  while (value = next()) {
3481
- if (ind >= iterator.length) {
3482
- yield pushToken(buffer, 'Bad-comment');
3483
- break;
3484
- }
3485
- if (value == '\\') {
3486
- buffer += value;
3487
- value = next();
3488
- if (ind >= iterator.length) {
3489
- yield pushToken(buffer, 'Bad-comment');
3490
- break;
3491
- }
3492
- buffer += value;
3493
- continue;
3494
- }
3495
3560
  if (value == '*') {
3496
3561
  buffer += value;
3497
- value = next();
3498
- if (ind >= iterator.length) {
3499
- yield pushToken(buffer, 'Bad-comment');
3500
- break;
3501
- }
3502
- buffer += value;
3503
- if (value == '/') {
3504
- yield pushToken(buffer, 'Comment');
3562
+ if (peek() == '/') {
3563
+ yield pushToken(buffer + next(), 'Comment');
3505
3564
  buffer = '';
3506
3565
  break;
3507
3566
  }
@@ -3510,6 +3569,8 @@ function* tokenize(iterator) {
3510
3569
  buffer += value;
3511
3570
  }
3512
3571
  }
3572
+ yield pushToken(buffer, 'Bad-comment');
3573
+ buffer = '';
3513
3574
  }
3514
3575
  break;
3515
3576
  case '<':
@@ -3517,16 +3578,15 @@ function* tokenize(iterator) {
3517
3578
  yield pushToken(buffer);
3518
3579
  buffer = '';
3519
3580
  }
3520
- buffer += value;
3521
- value = next();
3522
- if (ind >= iterator.length) {
3581
+ if (peek() == '=') {
3582
+ yield pushToken('', 'Lte');
3583
+ next();
3523
3584
  break;
3524
3585
  }
3586
+ buffer += value;
3525
3587
  if (peek(3) == '!--') {
3588
+ buffer += next(3);
3526
3589
  while (value = next()) {
3527
- if (ind >= iterator.length) {
3528
- break;
3529
- }
3530
3590
  buffer += value;
3531
3591
  if (value == '>' && prev(2) == '--') {
3532
3592
  yield pushToken(buffer, 'CDOCOMM');
@@ -3535,15 +3595,14 @@ function* tokenize(iterator) {
3535
3595
  }
3536
3596
  }
3537
3597
  }
3538
- if (ind >= iterator.length) {
3539
- yield pushToken(buffer, 'BADCDO');
3540
- buffer = '';
3541
- }
3598
+ // if (!peek()) {
3599
+ yield pushToken(buffer, 'Bad-cdo');
3600
+ buffer = '';
3601
+ // }
3542
3602
  break;
3543
3603
  case '\\':
3544
- value = next();
3545
3604
  // EOF
3546
- if (ind + 1 >= iterator.length) {
3605
+ if (!(value = next())) {
3547
3606
  // end of stream ignore \\
3548
3607
  yield pushToken(buffer);
3549
3608
  buffer = '';
@@ -3562,8 +3621,7 @@ function* tokenize(iterator) {
3562
3621
  buffer = '';
3563
3622
  }
3564
3623
  buffer += value;
3565
- value = next();
3566
- if (ind >= iterator.length) {
3624
+ if (!(value = next())) {
3567
3625
  yield pushToken(buffer);
3568
3626
  buffer = '';
3569
3627
  break;
@@ -3585,7 +3643,13 @@ function* tokenize(iterator) {
3585
3643
  yield pushToken(buffer);
3586
3644
  buffer = '';
3587
3645
  }
3588
- yield pushToken('', 'Gt');
3646
+ if (peek() == '=') {
3647
+ yield pushToken('', 'Gte');
3648
+ next();
3649
+ }
3650
+ else {
3651
+ yield pushToken('', 'Gt');
3652
+ }
3589
3653
  consumeWhiteSpace();
3590
3654
  break;
3591
3655
  case '.':
@@ -3627,7 +3691,7 @@ function* tokenize(iterator) {
3627
3691
  break;
3628
3692
  case '(':
3629
3693
  if (buffer.length == 0) {
3630
- yield pushToken('', 'Start-parens');
3694
+ yield pushToken(value);
3631
3695
  break;
3632
3696
  }
3633
3697
  buffer += value;
@@ -3724,8 +3788,7 @@ function* tokenize(iterator) {
3724
3788
  yield pushToken(buffer);
3725
3789
  buffer = '';
3726
3790
  }
3727
- const important = peek(9);
3728
- if (important == 'important') {
3791
+ if (peek(9) == 'important') {
3729
3792
  yield pushToken('', 'Important');
3730
3793
  next(9);
3731
3794
  buffer = '';
@@ -3741,9 +3804,11 @@ function* tokenize(iterator) {
3741
3804
  if (buffer.length > 0) {
3742
3805
  yield pushToken(buffer);
3743
3806
  }
3807
+ // yield pushToken('', 'EOF');
3744
3808
  }
3745
3809
 
3746
3810
  const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
3811
+ const trimWhiteSpace = ['Gt', 'Gte', 'Lt', 'Lte'];
3747
3812
  const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
3748
3813
  /**
3749
3814
  *
@@ -3908,7 +3973,7 @@ async function parse$1(iterator, opt = {}) {
3908
3973
  // https://www.w3.org/TR/css-nesting-1/#conditionals
3909
3974
  // allowed nesting at-rules
3910
3975
  // there must be a top level rule in the stack
3911
- const raw = tokens.reduce((acc, curr) => {
3976
+ const raw = parseTokens(tokens, { minify: options.minify }).reduce((acc, curr) => {
3912
3977
  acc.push(renderToken(curr, { removeComments: true }));
3913
3978
  return acc;
3914
3979
  }, []);
@@ -3939,8 +4004,8 @@ async function parse$1(iterator, opt = {}) {
3939
4004
  const uniq = new Map;
3940
4005
  parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
3941
4006
  if (curr.typ == 'Whitespace') {
3942
- if (array[index - 1]?.typ == 'Gt' ||
3943
- array[index + 1]?.typ == 'Gt' ||
4007
+ if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
4008
+ trimWhiteSpace.includes(array[index + 1]?.typ) ||
3944
4009
  combinators.includes(array[index - 1]?.val) ||
3945
4010
  combinators.includes(array[index + 1]?.val)) {
3946
4011
  return acc;
@@ -4066,6 +4131,11 @@ async function parse$1(iterator, opt = {}) {
4066
4131
  if (item == null) {
4067
4132
  break;
4068
4133
  }
4134
+ // console.debug({item});
4135
+ if (item.hint != null && item.hint.startsWith('Bad-')) {
4136
+ // bad token
4137
+ continue;
4138
+ }
4069
4139
  tokens.push(item);
4070
4140
  bytesIn = item.bytesIn;
4071
4141
  if (item.token == ';' || item.token == '{') {
@@ -4144,7 +4214,7 @@ function getTokenType(val, hint) {
4144
4214
  return ([
4145
4215
  'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
4146
4216
  'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
4147
- 'Comma', 'Gt', 'Lt'
4217
+ 'Comma', 'Gt', 'Lt', 'Gte', 'Lte', 'EOF'
4148
4218
  ].includes(hint) ? { typ: hint } : { typ: hint, val });
4149
4219
  }
4150
4220
  if (val == ' ') {
@@ -4272,11 +4342,12 @@ function parseTokens(tokens, options = {}) {
4272
4342
  const t = tokens[i];
4273
4343
  if (t.typ == 'Whitespace' && ((i == 0 ||
4274
4344
  i + 1 == tokens.length ||
4275
- ['Comma'].includes(tokens[i + 1].typ) ||
4345
+ ['Comma', 'Gte', 'Lte'].includes(tokens[i + 1].typ)) ||
4276
4346
  (i > 0 &&
4277
- tokens[i + 1]?.typ != 'Literal' &&
4278
- funcLike.includes(tokens[i - 1].typ) &&
4279
- !['var', 'calc'].includes(tokens[i - 1].val))))) {
4347
+ // tokens[i + 1]?.typ != 'Literal' ||
4348
+ // funcLike.includes(tokens[i - 1].typ) &&
4349
+ // !['var', 'calc'].includes((<FunctionToken>tokens[i - 1]).val)))) &&
4350
+ trimWhiteSpace.includes(tokens[i - 1].typ)))) {
4280
4351
  tokens.splice(i--, 1);
4281
4352
  continue;
4282
4353
  }
@@ -4374,41 +4445,33 @@ function parseTokens(tokens, options = {}) {
4374
4445
  // @ts-ignore
4375
4446
  t.chi.pop();
4376
4447
  }
4377
- let isColor = true;
4378
4448
  // @ts-ignore
4379
- if (options.parseColor && ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk'].includes(t.val)) {
4449
+ if (options.parseColor && t.typ == 'Func' && isColor(t)) {
4450
+ // if (isColor) {
4380
4451
  // @ts-ignore
4381
- for (const v of t.chi) {
4382
- if (v.typ == 'Func' && v.val == 'var') {
4383
- isColor = false;
4384
- break;
4385
- }
4386
- }
4387
- if (isColor) {
4388
- // @ts-ignore
4389
- t.typ = 'Color';
4390
- // @ts-ignore
4391
- t.kin = t.val;
4452
+ t.typ = 'Color';
4453
+ // @ts-ignore
4454
+ t.kin = t.val;
4455
+ // @ts-ignore
4456
+ let m = t.chi.length;
4457
+ while (m-- > 0) {
4392
4458
  // @ts-ignore
4393
- let m = t.chi.length;
4394
- while (m-- > 0) {
4459
+ if (['Literal'].concat(trimWhiteSpace).includes(t.chi[m].typ)) {
4395
4460
  // @ts-ignore
4396
- if (t.chi[m].typ == 'Literal') {
4461
+ if (t.chi[m + 1]?.typ == 'Whitespace') {
4397
4462
  // @ts-ignore
4398
- if (t.chi[m + 1]?.typ == 'Whitespace') {
4399
- // @ts-ignore
4400
- t.chi.splice(m + 1, 1);
4401
- }
4463
+ t.chi.splice(m + 1, 1);
4464
+ }
4465
+ // @ts-ignore
4466
+ if (t.chi[m - 1]?.typ == 'Whitespace') {
4402
4467
  // @ts-ignore
4403
- if (t.chi[m - 1]?.typ == 'Whitespace') {
4404
- // @ts-ignore
4405
- t.chi.splice(m - 1, 1);
4406
- m--;
4407
- }
4468
+ t.chi.splice(m - 1, 1);
4469
+ m--;
4408
4470
  }
4409
4471
  }
4410
- continue;
4411
4472
  }
4473
+ continue;
4474
+ // }
4412
4475
  }
4413
4476
  if (t.typ == 'UrlFunc') {
4414
4477
  // @ts-ignore
@@ -4433,7 +4496,7 @@ function parseTokens(tokens, options = {}) {
4433
4496
  // @ts-ignore
4434
4497
  if (t.chi.length > 0) {
4435
4498
  // @ts-ignore
4436
- parseTokens(t.chi, t.typ);
4499
+ parseTokens(t.chi, options);
4437
4500
  if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.minify) {
4438
4501
  //
4439
4502
  const count = t.chi.filter(t => t.typ != 'Comment').length;
@@ -4452,7 +4515,7 @@ function parseTokens(tokens, options = {}) {
4452
4515
  if (t.typ == 'Iden') {
4453
4516
  // named color
4454
4517
  const value = t.val.toLowerCase();
4455
- if (COLORS_NAMES[value] != null) {
4518
+ if (value in COLORS_NAMES) {
4456
4519
  Object.assign(t, {
4457
4520
  typ: 'Color',
4458
4521
  val: COLORS_NAMES[value].length < value.length ? COLORS_NAMES[value] : value,
@@ -4599,19 +4662,22 @@ async function load(url, currentFile) {
4599
4662
  return matchUrl.test(resolved.absolute) ? fetch(resolved.absolute).then(parseResponse) : promises.readFile(resolved.absolute, { encoding: 'utf-8' });
4600
4663
  }
4601
4664
 
4602
- function parse(iterator, opt = {}) {
4665
+ async function parse(iterator, opt = {}) {
4603
4666
  return parse$1(iterator, Object.assign(opt, { load, resolve, cwd: opt.cwd ?? process.cwd() }));
4604
4667
  }
4605
- function transform(css, options = {}) {
4668
+ async function transform(css, options = {}) {
4606
4669
  return transform$1(css, Object.assign(options, { load, resolve, cwd: options.cwd ?? process.cwd() }));
4607
4670
  }
4608
4671
 
4672
+ exports.colorsFunc = colorsFunc;
4609
4673
  exports.combinators = combinators;
4610
4674
  exports.dirname = dirname;
4675
+ exports.funcList = funcList;
4611
4676
  exports.getConfig = getConfig;
4612
4677
  exports.hasDeclaration = hasDeclaration;
4613
4678
  exports.isAngle = isAngle;
4614
4679
  exports.isAtKeyword = isAtKeyword;
4680
+ exports.isColor = isColor;
4615
4681
  exports.isDigit = isDigit;
4616
4682
  exports.isDimension = isDimension;
4617
4683
  exports.isFrequency = isFrequency;