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