@tbela99/css-parser 1.3.0 → 1.3.2

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
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var process = require('node:process');
4
- var promises = require('node:fs/promises');
4
+ var node_stream = require('node:stream');
5
+ var node_fs = require('node:fs');
5
6
 
6
7
  /**
7
8
  * syntax validation enum
@@ -16,7 +17,7 @@ var SyntaxValidationResult;
16
17
  SyntaxValidationResult[SyntaxValidationResult["Lenient"] = 2] = "Lenient";
17
18
  })(SyntaxValidationResult || (SyntaxValidationResult = {}));
18
19
  /**
19
- * validation level enum
20
+ * enum of validation levels
20
21
  */
21
22
  exports.ValidationLevel = void 0;
22
23
  (function (ValidationLevel) {
@@ -34,139 +35,504 @@ exports.ValidationLevel = void 0;
34
35
  ValidationLevel[ValidationLevel["All"] = 2] = "All"; // selectors + at-rules + declarations
35
36
  })(exports.ValidationLevel || (exports.ValidationLevel = {}));
36
37
  /**
37
- * token types enum
38
+ * enum of all token types
38
39
  */
39
40
  exports.EnumToken = void 0;
40
41
  (function (EnumToken) {
42
+ /**
43
+ * comment token
44
+ */
41
45
  EnumToken[EnumToken["CommentTokenType"] = 0] = "CommentTokenType";
46
+ /**
47
+ * cdata section token
48
+ */
42
49
  EnumToken[EnumToken["CDOCOMMTokenType"] = 1] = "CDOCOMMTokenType";
50
+ /**
51
+ * style sheet node type
52
+ */
43
53
  EnumToken[EnumToken["StyleSheetNodeType"] = 2] = "StyleSheetNodeType";
54
+ /**
55
+ * at-rule node type
56
+ */
44
57
  EnumToken[EnumToken["AtRuleNodeType"] = 3] = "AtRuleNodeType";
58
+ /**
59
+ * rule node type
60
+ */
45
61
  EnumToken[EnumToken["RuleNodeType"] = 4] = "RuleNodeType";
62
+ /**
63
+ * declaration node type
64
+ */
46
65
  EnumToken[EnumToken["DeclarationNodeType"] = 5] = "DeclarationNodeType";
66
+ /**
67
+ * literal token type
68
+ */
47
69
  EnumToken[EnumToken["LiteralTokenType"] = 6] = "LiteralTokenType";
70
+ /**
71
+ * identifier token type
72
+ */
48
73
  EnumToken[EnumToken["IdenTokenType"] = 7] = "IdenTokenType";
74
+ /**
75
+ * dashed identifier token type
76
+ */
49
77
  EnumToken[EnumToken["DashedIdenTokenType"] = 8] = "DashedIdenTokenType";
78
+ /**
79
+ * comma token type
80
+ */
50
81
  EnumToken[EnumToken["CommaTokenType"] = 9] = "CommaTokenType";
82
+ /**
83
+ * colon token type
84
+ */
51
85
  EnumToken[EnumToken["ColonTokenType"] = 10] = "ColonTokenType";
86
+ /**
87
+ * semicolon token type
88
+ */
52
89
  EnumToken[EnumToken["SemiColonTokenType"] = 11] = "SemiColonTokenType";
90
+ /**
91
+ * number token type
92
+ */
53
93
  EnumToken[EnumToken["NumberTokenType"] = 12] = "NumberTokenType";
94
+ /**
95
+ * at-rule token type
96
+ */
54
97
  EnumToken[EnumToken["AtRuleTokenType"] = 13] = "AtRuleTokenType";
98
+ /**
99
+ * percentage token type
100
+ */
55
101
  EnumToken[EnumToken["PercentageTokenType"] = 14] = "PercentageTokenType";
102
+ /**
103
+ * function token type
104
+ */
56
105
  EnumToken[EnumToken["FunctionTokenType"] = 15] = "FunctionTokenType";
106
+ /**
107
+ * timeline function token type
108
+ */
57
109
  EnumToken[EnumToken["TimelineFunctionTokenType"] = 16] = "TimelineFunctionTokenType";
110
+ /**
111
+ * timing function token type
112
+ */
58
113
  EnumToken[EnumToken["TimingFunctionTokenType"] = 17] = "TimingFunctionTokenType";
114
+ /**
115
+ * url function token type
116
+ */
59
117
  EnumToken[EnumToken["UrlFunctionTokenType"] = 18] = "UrlFunctionTokenType";
118
+ /**
119
+ * image function token type
120
+ */
60
121
  EnumToken[EnumToken["ImageFunctionTokenType"] = 19] = "ImageFunctionTokenType";
122
+ /**
123
+ * string token type
124
+ */
61
125
  EnumToken[EnumToken["StringTokenType"] = 20] = "StringTokenType";
126
+ /**
127
+ * unclosed string token type
128
+ */
62
129
  EnumToken[EnumToken["UnclosedStringTokenType"] = 21] = "UnclosedStringTokenType";
130
+ /**
131
+ * dimension token type
132
+ */
63
133
  EnumToken[EnumToken["DimensionTokenType"] = 22] = "DimensionTokenType";
134
+ /**
135
+ * length token type
136
+ */
64
137
  EnumToken[EnumToken["LengthTokenType"] = 23] = "LengthTokenType";
138
+ /**
139
+ * angle token type
140
+ */
65
141
  EnumToken[EnumToken["AngleTokenType"] = 24] = "AngleTokenType";
142
+ /**
143
+ * time token type
144
+ */
66
145
  EnumToken[EnumToken["TimeTokenType"] = 25] = "TimeTokenType";
146
+ /**
147
+ * frequency token type
148
+ */
67
149
  EnumToken[EnumToken["FrequencyTokenType"] = 26] = "FrequencyTokenType";
150
+ /**
151
+ * resolution token type
152
+ */
68
153
  EnumToken[EnumToken["ResolutionTokenType"] = 27] = "ResolutionTokenType";
154
+ /**
155
+ * hash token type
156
+ */
69
157
  EnumToken[EnumToken["HashTokenType"] = 28] = "HashTokenType";
158
+ /**
159
+ * block start token type
160
+ */
70
161
  EnumToken[EnumToken["BlockStartTokenType"] = 29] = "BlockStartTokenType";
162
+ /**
163
+ * block end token type
164
+ */
71
165
  EnumToken[EnumToken["BlockEndTokenType"] = 30] = "BlockEndTokenType";
166
+ /**
167
+ * attribute start token type
168
+ */
72
169
  EnumToken[EnumToken["AttrStartTokenType"] = 31] = "AttrStartTokenType";
170
+ /**
171
+ * attribute end token type
172
+ */
73
173
  EnumToken[EnumToken["AttrEndTokenType"] = 32] = "AttrEndTokenType";
174
+ /**
175
+ * start parentheses token type
176
+ */
74
177
  EnumToken[EnumToken["StartParensTokenType"] = 33] = "StartParensTokenType";
178
+ /**
179
+ * end parentheses token type
180
+ */
75
181
  EnumToken[EnumToken["EndParensTokenType"] = 34] = "EndParensTokenType";
182
+ /**
183
+ * parentheses token type
184
+ */
76
185
  EnumToken[EnumToken["ParensTokenType"] = 35] = "ParensTokenType";
186
+ /**
187
+ * whitespace token type
188
+ */
77
189
  EnumToken[EnumToken["WhitespaceTokenType"] = 36] = "WhitespaceTokenType";
190
+ /**
191
+ * include match token type
192
+ */
78
193
  EnumToken[EnumToken["IncludeMatchTokenType"] = 37] = "IncludeMatchTokenType";
194
+ /**
195
+ * dash match token type
196
+ */
79
197
  EnumToken[EnumToken["DashMatchTokenType"] = 38] = "DashMatchTokenType";
198
+ /**
199
+ * equal match token type
200
+ */
80
201
  EnumToken[EnumToken["EqualMatchTokenType"] = 39] = "EqualMatchTokenType";
202
+ /**
203
+ * less than token type
204
+ */
81
205
  EnumToken[EnumToken["LtTokenType"] = 40] = "LtTokenType";
206
+ /**
207
+ * less than or equal to token type
208
+ */
82
209
  EnumToken[EnumToken["LteTokenType"] = 41] = "LteTokenType";
210
+ /**
211
+ * greater than token type
212
+ */
83
213
  EnumToken[EnumToken["GtTokenType"] = 42] = "GtTokenType";
214
+ /**
215
+ * greater than or equal to token type
216
+ */
84
217
  EnumToken[EnumToken["GteTokenType"] = 43] = "GteTokenType";
218
+ /**
219
+ * pseudo-class token type
220
+ */
85
221
  EnumToken[EnumToken["PseudoClassTokenType"] = 44] = "PseudoClassTokenType";
222
+ /**
223
+ * pseudo-class function token type
224
+ */
86
225
  EnumToken[EnumToken["PseudoClassFuncTokenType"] = 45] = "PseudoClassFuncTokenType";
226
+ /**
227
+ * delimiter token type
228
+ */
87
229
  EnumToken[EnumToken["DelimTokenType"] = 46] = "DelimTokenType";
230
+ /**
231
+ * URL token type
232
+ */
88
233
  EnumToken[EnumToken["UrlTokenTokenType"] = 47] = "UrlTokenTokenType";
234
+ /**
235
+ * end of file token type
236
+ */
89
237
  EnumToken[EnumToken["EOFTokenType"] = 48] = "EOFTokenType";
238
+ /**
239
+ * important token type
240
+ */
90
241
  EnumToken[EnumToken["ImportantTokenType"] = 49] = "ImportantTokenType";
242
+ /**
243
+ * color token type
244
+ */
91
245
  EnumToken[EnumToken["ColorTokenType"] = 50] = "ColorTokenType";
246
+ /**
247
+ * attribute token type
248
+ */
92
249
  EnumToken[EnumToken["AttrTokenType"] = 51] = "AttrTokenType";
250
+ /**
251
+ * bad comment token type
252
+ */
93
253
  EnumToken[EnumToken["BadCommentTokenType"] = 52] = "BadCommentTokenType";
254
+ /**
255
+ * bad cdo token type
256
+ */
94
257
  EnumToken[EnumToken["BadCdoTokenType"] = 53] = "BadCdoTokenType";
258
+ /**
259
+ * bad URL token type
260
+ */
95
261
  EnumToken[EnumToken["BadUrlTokenType"] = 54] = "BadUrlTokenType";
262
+ /**
263
+ * bad string token type
264
+ */
96
265
  EnumToken[EnumToken["BadStringTokenType"] = 55] = "BadStringTokenType";
266
+ /**
267
+ * binary expression token type
268
+ */
97
269
  EnumToken[EnumToken["BinaryExpressionTokenType"] = 56] = "BinaryExpressionTokenType";
270
+ /**
271
+ * unary expression token type
272
+ */
98
273
  EnumToken[EnumToken["UnaryExpressionTokenType"] = 57] = "UnaryExpressionTokenType";
274
+ /**
275
+ * flex token type
276
+ */
99
277
  EnumToken[EnumToken["FlexTokenType"] = 58] = "FlexTokenType";
100
- /* catch all */
278
+ /**
279
+ * token list token type
280
+ */
101
281
  EnumToken[EnumToken["ListToken"] = 59] = "ListToken";
102
282
  /* arithmetic tokens */
283
+ /**
284
+ * addition token type
285
+ */
103
286
  EnumToken[EnumToken["Add"] = 60] = "Add";
287
+ /**
288
+ * multiplication token type
289
+ */
104
290
  EnumToken[EnumToken["Mul"] = 61] = "Mul";
291
+ /**
292
+ * division token type
293
+ */
105
294
  EnumToken[EnumToken["Div"] = 62] = "Div";
295
+ /**
296
+ * subtraction token type
297
+ */
106
298
  EnumToken[EnumToken["Sub"] = 63] = "Sub";
107
299
  /* new tokens */
300
+ /**
301
+ * column combinator token type
302
+ */
108
303
  EnumToken[EnumToken["ColumnCombinatorTokenType"] = 64] = "ColumnCombinatorTokenType";
304
+ /**
305
+ * contain match token type
306
+ */
109
307
  EnumToken[EnumToken["ContainMatchTokenType"] = 65] = "ContainMatchTokenType";
308
+ /**
309
+ * start match token type
310
+ */
110
311
  EnumToken[EnumToken["StartMatchTokenType"] = 66] = "StartMatchTokenType";
312
+ /**
313
+ * end match token type
314
+ */
111
315
  EnumToken[EnumToken["EndMatchTokenType"] = 67] = "EndMatchTokenType";
316
+ /**
317
+ * match expression token type
318
+ */
112
319
  EnumToken[EnumToken["MatchExpressionTokenType"] = 68] = "MatchExpressionTokenType";
320
+ /**
321
+ * namespace attribute token type
322
+ */
113
323
  EnumToken[EnumToken["NameSpaceAttributeTokenType"] = 69] = "NameSpaceAttributeTokenType";
324
+ /**
325
+ * fraction token type
326
+ */
114
327
  EnumToken[EnumToken["FractionTokenType"] = 70] = "FractionTokenType";
328
+ /**
329
+ * identifier list token type
330
+ */
115
331
  EnumToken[EnumToken["IdenListTokenType"] = 71] = "IdenListTokenType";
332
+ /**
333
+ * grid template function token type
334
+ */
116
335
  EnumToken[EnumToken["GridTemplateFuncTokenType"] = 72] = "GridTemplateFuncTokenType";
336
+ /**
337
+ * keyframe rule node type
338
+ */
117
339
  EnumToken[EnumToken["KeyFrameRuleNodeType"] = 73] = "KeyFrameRuleNodeType";
340
+ /**
341
+ * class selector token type
342
+ */
118
343
  EnumToken[EnumToken["ClassSelectorTokenType"] = 74] = "ClassSelectorTokenType";
344
+ /**
345
+ * universal selector token type
346
+ */
119
347
  EnumToken[EnumToken["UniversalSelectorTokenType"] = 75] = "UniversalSelectorTokenType";
348
+ /**
349
+ * child combinator token type
350
+ */
120
351
  EnumToken[EnumToken["ChildCombinatorTokenType"] = 76] = "ChildCombinatorTokenType";
352
+ /**
353
+ * descendant combinator token type
354
+ */
121
355
  EnumToken[EnumToken["DescendantCombinatorTokenType"] = 77] = "DescendantCombinatorTokenType";
356
+ /**
357
+ * next sibling combinator token type
358
+ */
122
359
  EnumToken[EnumToken["NextSiblingCombinatorTokenType"] = 78] = "NextSiblingCombinatorTokenType";
360
+ /**
361
+ * subsequent sibling combinator token type
362
+ */
123
363
  EnumToken[EnumToken["SubsequentSiblingCombinatorTokenType"] = 79] = "SubsequentSiblingCombinatorTokenType";
364
+ /**
365
+ * nesting selector token type
366
+ */
124
367
  EnumToken[EnumToken["NestingSelectorTokenType"] = 80] = "NestingSelectorTokenType";
368
+ /**
369
+ * invalid rule token type
370
+ */
125
371
  EnumToken[EnumToken["InvalidRuleTokenType"] = 81] = "InvalidRuleTokenType";
372
+ /**
373
+ * invalid class selector token type
374
+ */
126
375
  EnumToken[EnumToken["InvalidClassSelectorTokenType"] = 82] = "InvalidClassSelectorTokenType";
376
+ /**
377
+ * invalid attribute token type
378
+ */
127
379
  EnumToken[EnumToken["InvalidAttrTokenType"] = 83] = "InvalidAttrTokenType";
380
+ /**
381
+ * invalid at rule token type
382
+ */
128
383
  EnumToken[EnumToken["InvalidAtRuleTokenType"] = 84] = "InvalidAtRuleTokenType";
384
+ /**
385
+ * media query condition token type
386
+ */
129
387
  EnumToken[EnumToken["MediaQueryConditionTokenType"] = 85] = "MediaQueryConditionTokenType";
388
+ /**
389
+ * media feature token type
390
+ */
130
391
  EnumToken[EnumToken["MediaFeatureTokenType"] = 86] = "MediaFeatureTokenType";
392
+ /**
393
+ * media feature only token type
394
+ */
131
395
  EnumToken[EnumToken["MediaFeatureOnlyTokenType"] = 87] = "MediaFeatureOnlyTokenType";
396
+ /**
397
+ * media feature not token type
398
+ */
132
399
  EnumToken[EnumToken["MediaFeatureNotTokenType"] = 88] = "MediaFeatureNotTokenType";
400
+ /**
401
+ * media feature and token type
402
+ */
133
403
  EnumToken[EnumToken["MediaFeatureAndTokenType"] = 89] = "MediaFeatureAndTokenType";
404
+ /**
405
+ * media feature or token type
406
+ */
134
407
  EnumToken[EnumToken["MediaFeatureOrTokenType"] = 90] = "MediaFeatureOrTokenType";
408
+ /**
409
+ * pseudo page token type
410
+ */
135
411
  EnumToken[EnumToken["PseudoPageTokenType"] = 91] = "PseudoPageTokenType";
412
+ /**
413
+ * pseudo element token type
414
+ */
136
415
  EnumToken[EnumToken["PseudoElementTokenType"] = 92] = "PseudoElementTokenType";
416
+ /**
417
+ * keyframe at rule node type
418
+ */
137
419
  EnumToken[EnumToken["KeyframeAtRuleNodeType"] = 93] = "KeyframeAtRuleNodeType";
420
+ /**
421
+ * invalid declaration node type
422
+ */
138
423
  EnumToken[EnumToken["InvalidDeclarationNodeType"] = 94] = "InvalidDeclarationNodeType";
139
424
  /* aliases */
425
+ /**
426
+ * alias for time token type
427
+ */
140
428
  EnumToken[EnumToken["Time"] = 25] = "Time";
429
+ /**
430
+ * alias for identifier token type
431
+ */
141
432
  EnumToken[EnumToken["Iden"] = 7] = "Iden";
433
+ /**
434
+ * alias for end of file token type
435
+ */
142
436
  EnumToken[EnumToken["EOF"] = 48] = "EOF";
437
+ /**
438
+ * alias for hash token type
439
+ */
143
440
  EnumToken[EnumToken["Hash"] = 28] = "Hash";
441
+ /**
442
+ * alias for flex token type
443
+ */
144
444
  EnumToken[EnumToken["Flex"] = 58] = "Flex";
445
+ /**
446
+ * alias for angle token type
447
+ */
145
448
  EnumToken[EnumToken["Angle"] = 24] = "Angle";
449
+ /**
450
+ * alias for color token type
451
+ */
146
452
  EnumToken[EnumToken["Color"] = 50] = "Color";
453
+ /**
454
+ * alias for comma token type
455
+ */
147
456
  EnumToken[EnumToken["Comma"] = 9] = "Comma";
457
+ /**
458
+ * alias for string token type
459
+ */
148
460
  EnumToken[EnumToken["String"] = 20] = "String";
461
+ /**
462
+ * alias for length token type
463
+ */
149
464
  EnumToken[EnumToken["Length"] = 23] = "Length";
465
+ /**
466
+ * alias for number token type
467
+ */
150
468
  EnumToken[EnumToken["Number"] = 12] = "Number";
469
+ /**
470
+ * alias for percentage token type
471
+ */
151
472
  EnumToken[EnumToken["Perc"] = 14] = "Perc";
473
+ /**
474
+ * alias for literal token type
475
+ */
152
476
  EnumToken[EnumToken["Literal"] = 6] = "Literal";
477
+ /**
478
+ * alias for comment token type
479
+ */
153
480
  EnumToken[EnumToken["Comment"] = 0] = "Comment";
481
+ /**
482
+ * alias for url function token type
483
+ */
154
484
  EnumToken[EnumToken["UrlFunc"] = 18] = "UrlFunc";
485
+ /**
486
+ * alias for dimension token type
487
+ */
155
488
  EnumToken[EnumToken["Dimension"] = 22] = "Dimension";
489
+ /**
490
+ * alias for frequency token type
491
+ */
156
492
  EnumToken[EnumToken["Frequency"] = 26] = "Frequency";
493
+ /**
494
+ * alias for resolution token type
495
+ */
157
496
  EnumToken[EnumToken["Resolution"] = 27] = "Resolution";
497
+ /**
498
+ * alias for whitespace token type
499
+ */
158
500
  EnumToken[EnumToken["Whitespace"] = 36] = "Whitespace";
501
+ /**
502
+ * alias for identifier list token type
503
+ */
159
504
  EnumToken[EnumToken["IdenList"] = 71] = "IdenList";
505
+ /**
506
+ * alias for dashed identifier token type
507
+ */
160
508
  EnumToken[EnumToken["DashedIden"] = 8] = "DashedIden";
509
+ /**
510
+ * alias for grid template function token type
511
+ */
161
512
  EnumToken[EnumToken["GridTemplateFunc"] = 72] = "GridTemplateFunc";
513
+ /**
514
+ * alias for image function token type
515
+ */
162
516
  EnumToken[EnumToken["ImageFunc"] = 19] = "ImageFunc";
517
+ /**
518
+ * alias for comment node type
519
+ */
163
520
  EnumToken[EnumToken["CommentNodeType"] = 0] = "CommentNodeType";
521
+ /**
522
+ * alias for cdata section node type
523
+ */
164
524
  EnumToken[EnumToken["CDOCOMMNodeType"] = 1] = "CDOCOMMNodeType";
525
+ /**
526
+ * alias for timing function token type
527
+ */
165
528
  EnumToken[EnumToken["TimingFunction"] = 17] = "TimingFunction";
529
+ /**
530
+ * alias for timeline function token type
531
+ */
166
532
  EnumToken[EnumToken["TimelineFunction"] = 16] = "TimelineFunction";
167
533
  })(exports.EnumToken || (exports.EnumToken = {}));
168
534
  /**
169
- * color types enum
535
+ * supported color types enum
170
536
  */
171
537
  exports.ColorType = void 0;
172
538
  (function (ColorType) {
@@ -1888,15 +2254,19 @@ function getComponents(token) {
1888
2254
  * Calculate the distance between two okLab colors.
1889
2255
  * @param okLab1
1890
2256
  * @param okLab2
2257
+ *
2258
+ * @private
1891
2259
  */
1892
2260
  function okLabDistance(okLab1, okLab2) {
1893
2261
  return Math.sqrt(Math.pow(okLab1[0] - okLab2[0], 2) + Math.pow(okLab1[1] - okLab2[1], 2) + Math.pow(okLab1[2] - okLab2[2], 2));
1894
2262
  }
1895
2263
  /**
1896
- * Check if two colors are close.
2264
+ * Check if two colors are close in okLab space.
1897
2265
  * @param color1
1898
2266
  * @param color2
1899
2267
  * @param threshold
2268
+ *
2269
+ * @private
1900
2270
  */
1901
2271
  function isOkLabClose(color1, color2, threshold = .01) {
1902
2272
  color1 = convertColor(color1, exports.ColorType.OKLAB);
@@ -3755,6 +4125,13 @@ function xyz2la98rgb(x, y, z, a = null) {
3755
4125
  * Converts a color to another color space
3756
4126
  * @param token
3757
4127
  * @param to
4128
+ *
4129
+ * <code>
4130
+ *
4131
+ * const token = {typ: EnumToken.ColorTokenType, kin: ColorType.HEX, val: '#F00'}
4132
+ * const result = convertColor(token, ColorType.LCH);
4133
+ *
4134
+ * </code>
3758
4135
  */
3759
4136
  function convertColor(token, to) {
3760
4137
  if (token.kin == exports.ColorType.SYS ||
@@ -4302,692 +4679,6 @@ function toPrecisionAngle(angle) {
4302
4679
  return angle;
4303
4680
  }
4304
4681
 
4305
- // from https://github.com/Rich-Harris/vlq/tree/master
4306
- // credit: Rich Harris
4307
- const integer_to_char = {};
4308
- let i = 0;
4309
- for (const char of 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=') {
4310
- integer_to_char[i++] = char;
4311
- }
4312
- function encode(value) {
4313
- if (typeof value === 'number') {
4314
- return encode_integer(value);
4315
- }
4316
- let result = '';
4317
- for (let i = 0; i < value.length; i += 1) {
4318
- result += encode_integer(value[i]);
4319
- }
4320
- return result;
4321
- }
4322
- function encode_integer(num) {
4323
- let result = '';
4324
- if (num < 0) {
4325
- num = (-num << 1) | 1;
4326
- }
4327
- else {
4328
- num <<= 1;
4329
- }
4330
- do {
4331
- let clamped = num & 31;
4332
- num >>>= 5;
4333
- if (num > 0) {
4334
- clamped |= 32;
4335
- }
4336
- result += integer_to_char[clamped];
4337
- } while (num > 0);
4338
- return result;
4339
- }
4340
-
4341
- class SourceMap {
4342
- lastLocation = null;
4343
- #version = 3;
4344
- #sources = [];
4345
- #map = new Map;
4346
- #line = -1;
4347
- add(source, original) {
4348
- if (original.src !== '') {
4349
- if (!this.#sources.includes(original.src)) {
4350
- this.#sources.push(original.src);
4351
- }
4352
- const line = source.sta.lin - 1;
4353
- let record;
4354
- if (line > this.#line) {
4355
- this.#line = line;
4356
- }
4357
- if (!this.#map.has(line)) {
4358
- record = [Math.max(0, source.sta.col - 1), this.#sources.indexOf(original.src), original.sta.lin - 1, original.sta.col - 1];
4359
- this.#map.set(line, [record]);
4360
- }
4361
- else {
4362
- const arr = this.#map.get(line);
4363
- record = [Math.max(0, source.sta.col - 1 - arr[0][0]), this.#sources.indexOf(original.src) - arr[0][1], original.sta.lin - 1, original.sta.col - 1];
4364
- arr.push(record);
4365
- }
4366
- if (this.lastLocation != null) {
4367
- record[2] -= this.lastLocation.sta.lin - 1;
4368
- record[3] -= this.lastLocation.sta.col - 1;
4369
- }
4370
- this.lastLocation = original;
4371
- }
4372
- }
4373
- toUrl() {
4374
- // /*# sourceMappingURL = ${url} */
4375
- return `data:application/json,${encodeURIComponent(JSON.stringify(this.toJSON()))}`;
4376
- }
4377
- toJSON() {
4378
- const mappings = [];
4379
- let i = 0;
4380
- for (; i <= this.#line; i++) {
4381
- if (!this.#map.has(i)) {
4382
- mappings.push('');
4383
- }
4384
- else {
4385
- mappings.push(this.#map.get(i).reduce((acc, curr) => acc + (acc === '' ? '' : ',') + encode(curr), ''));
4386
- }
4387
- }
4388
- return {
4389
- version: this.#version,
4390
- sources: this.#sources.slice(),
4391
- mappings: mappings.join(';')
4392
- };
4393
- }
4394
- }
4395
-
4396
- function update(position, str) {
4397
- let i = 0;
4398
- for (; i < str.length; i++) {
4399
- if (isNewLine(str[i].charCodeAt(0))) {
4400
- position.lin++;
4401
- position.col = 0;
4402
- }
4403
- else {
4404
- position.col++;
4405
- }
4406
- }
4407
- }
4408
- /**
4409
- * render ast
4410
- * @param data
4411
- * @param options
4412
- */
4413
- function doRender(data, options = {}) {
4414
- const minify = options.minify ?? true;
4415
- const beautify = options.beautify ?? !minify;
4416
- options = {
4417
- ...(beautify ? {
4418
- indent: ' ',
4419
- newLine: '\n',
4420
- } : {
4421
- indent: '',
4422
- newLine: '',
4423
- }),
4424
- ...(minify ? {
4425
- removeEmpty: true,
4426
- removeComments: true,
4427
- minify: true
4428
- } : {
4429
- removeEmpty: false,
4430
- removeComments: false,
4431
- }), sourcemap: false, convertColor: true, expandNestingRules: false, preserveLicense: false, ...options
4432
- };
4433
- if (options.withParents) {
4434
- // @ts-ignore
4435
- let parent = data.parent;
4436
- // @ts-ignore
4437
- while (data.parent != null) {
4438
- // @ts-ignore
4439
- parent = { ...data.parent, chi: [{ ...data }] };
4440
- // @ts-ignore
4441
- parent.parent = data.parent.parent;
4442
- // @ts-ignore
4443
- data = parent;
4444
- }
4445
- }
4446
- const startTime = performance.now();
4447
- const errors = [];
4448
- const sourcemap = options.sourcemap ? new SourceMap : null;
4449
- const cache = Object.create(null);
4450
- const result = {
4451
- code: renderAstNode(options.expandNestingRules ? expand(data) : data, options, sourcemap, {
4452
- ind: 0,
4453
- lin: 1,
4454
- col: 1
4455
- }, errors, function reducer(acc, curr) {
4456
- if (curr.typ == exports.EnumToken.CommentTokenType && options.removeComments) {
4457
- if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
4458
- return acc;
4459
- }
4460
- return acc + curr.val;
4461
- }
4462
- return acc + renderToken(curr, options, cache, reducer, errors);
4463
- }, cache), errors, stats: {
4464
- total: `${(performance.now() - startTime).toFixed(2)}ms`
4465
- }
4466
- };
4467
- if (options.output != null) {
4468
- // @ts-ignore
4469
- options.output = options.resolve(options.output, options.cwd).absolute;
4470
- }
4471
- if (sourcemap != null) {
4472
- result.map = sourcemap;
4473
- if (options.sourcemap === 'inline') {
4474
- result.code += `\n/*# sourceMappingURL=data:application/json,${encodeURIComponent(JSON.stringify(result.map))} */`;
4475
- }
4476
- }
4477
- return result;
4478
- }
4479
- function updateSourceMap(node, options, cache, sourcemap, position, str) {
4480
- if ([
4481
- exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType,
4482
- exports.EnumToken.KeyFrameRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType
4483
- ].includes(node.typ)) {
4484
- let src = node.loc?.src ?? '';
4485
- let output = options.output ?? '';
4486
- if (!(src in cache)) {
4487
- // @ts-ignore
4488
- cache[src] = options.resolve(src, options.cwd ?? '').relative;
4489
- }
4490
- if (!(output in cache)) {
4491
- // @ts-ignore
4492
- cache[output] = options.resolve(output, options.cwd).relative;
4493
- }
4494
- // @ts-ignore
4495
- sourcemap.add({ src: cache[output], sta: { ...position } }, {
4496
- ...node.loc,
4497
- // @ts-ignore
4498
- src: options.resolve(cache[src], options.cwd).relative
4499
- });
4500
- }
4501
- update(position, str);
4502
- }
4503
- /**
4504
- * render ast node
4505
- * @param data
4506
- * @param options
4507
- * @param sourcemap
4508
- * @param position
4509
- * @param errors
4510
- * @param reducer
4511
- * @param cache
4512
- * @param level
4513
- * @param indents
4514
- */
4515
- function renderAstNode(data, options, sourcemap, position, errors, reducer, cache, level = 0, indents = []) {
4516
- if (indents.length < level + 1) {
4517
- indents.push(options.indent.repeat(level));
4518
- }
4519
- if (indents.length < level + 2) {
4520
- indents.push(options.indent.repeat(level + 1));
4521
- }
4522
- const indent = indents[level];
4523
- const indentSub = indents[level + 1];
4524
- switch (data.typ) {
4525
- case exports.EnumToken.DeclarationNodeType:
4526
- return `${data.nam}:${options.indent}${(options.minify ? filterValues(data.val) : data.val).reduce(reducer, '')}`;
4527
- case exports.EnumToken.CommentNodeType:
4528
- case exports.EnumToken.CDOCOMMNodeType:
4529
- if (data.val.startsWith('/*# sourceMappingURL=')) {
4530
- // ignore sourcemap
4531
- return '';
4532
- }
4533
- return !options.removeComments || (options.preserveLicense && data.val.startsWith('/*!')) ? data.val : '';
4534
- case exports.EnumToken.StyleSheetNodeType:
4535
- return data.chi.reduce((css, node) => {
4536
- const str = renderAstNode(node, options, sourcemap, { ...position }, errors, reducer, cache, level, indents);
4537
- if (str === '') {
4538
- return css;
4539
- }
4540
- if (css === '') {
4541
- if (sourcemap != null && node.loc != null) {
4542
- updateSourceMap(node, options, cache, sourcemap, position, str);
4543
- }
4544
- return str;
4545
- }
4546
- if (sourcemap != null && node.loc != null) {
4547
- update(position, options.newLine);
4548
- updateSourceMap(node, options, cache, sourcemap, position, str);
4549
- }
4550
- return `${css}${options.newLine}${str}`;
4551
- }, '');
4552
- case exports.EnumToken.AtRuleNodeType:
4553
- case exports.EnumToken.RuleNodeType:
4554
- case exports.EnumToken.KeyFrameRuleNodeType:
4555
- case exports.EnumToken.KeyframeAtRuleNodeType:
4556
- if ([exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType].includes(data.typ) && !('chi' in data)) {
4557
- return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
4558
- }
4559
- // @ts-ignore
4560
- let children = data.chi.reduce((css, node) => {
4561
- let str;
4562
- if (node.typ == exports.EnumToken.CommentNodeType) {
4563
- str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
4564
- }
4565
- else if (node.typ == exports.EnumToken.DeclarationNodeType) {
4566
- if (!node.nam.startsWith('--') && node.val.length == 0) {
4567
- // @ts-ignore
4568
- errors.push({
4569
- action: 'ignore',
4570
- message: `render: invalid declaration ${JSON.stringify(node)}`,
4571
- location: node.loc
4572
- });
4573
- return '';
4574
- }
4575
- str = `${node.nam}:${options.indent}${(options.minify ? filterValues(node.val) : node.val).reduce(reducer, '').trimEnd()};`;
4576
- }
4577
- else if (node.typ == exports.EnumToken.AtRuleNodeType && !('chi' in node)) {
4578
- str = `${data.val === '' ? '' : options.indent || ' '}${data.val};`;
4579
- }
4580
- else {
4581
- str = renderAstNode(node, options, sourcemap, { ...position }, errors, reducer, cache, level + 1, indents);
4582
- }
4583
- if (css === '') {
4584
- return str;
4585
- }
4586
- if (str === '') {
4587
- return css;
4588
- }
4589
- return `${css}${options.newLine}${indentSub}${str}`;
4590
- }, '');
4591
- if (options.removeEmpty && children === '') {
4592
- return '';
4593
- }
4594
- if (children.endsWith(';')) {
4595
- children = children.slice(0, -1);
4596
- }
4597
- if ([exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType].includes(data.typ)) {
4598
- return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
4599
- }
4600
- return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
4601
- case exports.EnumToken.InvalidDeclarationNodeType:
4602
- case exports.EnumToken.InvalidRuleTokenType:
4603
- case exports.EnumToken.InvalidAtRuleTokenType:
4604
- default:
4605
- return '';
4606
- }
4607
- }
4608
- /**
4609
- * render ast token
4610
- * @param token
4611
- * @param options
4612
- * @param cache
4613
- * @param reducer
4614
- * @param errors
4615
- */
4616
- function renderToken(token, options = {}, cache = Object.create(null), reducer, errors) {
4617
- if (reducer == null) {
4618
- reducer = function (acc, curr) {
4619
- if (curr.typ == exports.EnumToken.CommentTokenType && options.removeComments) {
4620
- if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
4621
- return acc;
4622
- }
4623
- return acc + curr.val;
4624
- }
4625
- return acc + renderToken(curr, options, cache, reducer, errors);
4626
- };
4627
- }
4628
- if (token.typ == exports.EnumToken.FunctionTokenType && colorsFunc.includes(token.val)) {
4629
- if (isColor(token)) {
4630
- // @ts-ignore
4631
- token.typ = exports.EnumToken.ColorTokenType;
4632
- // @ts-ignore
4633
- if (token.chi[0].typ == exports.EnumToken.IdenTokenType && token.chi[0].val == 'from') {
4634
- // @ts-ignore
4635
- token.cal = 'rel';
4636
- }
4637
- else { // @ts-ignore
4638
- if (token.val == 'color-mix' && token.chi[0].typ == exports.EnumToken.IdenTokenType && token.chi[0].val == 'in') {
4639
- // @ts-ignore
4640
- token.cal = 'mix';
4641
- }
4642
- else {
4643
- // @ts-ignore
4644
- if (token.val == 'color') {
4645
- // @ts-ignore
4646
- token.cal = 'col';
4647
- }
4648
- // @ts-ignore
4649
- token.chi = token.chi.filter((t) => ![exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommaTokenType, exports.EnumToken.CommentTokenType].includes(t.typ));
4650
- }
4651
- }
4652
- }
4653
- }
4654
- switch (token.typ) {
4655
- case exports.EnumToken.ListToken:
4656
- return token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
4657
- case exports.EnumToken.BinaryExpressionTokenType:
4658
- if ([exports.EnumToken.Mul, exports.EnumToken.Div].includes(token.op)) {
4659
- let result = '';
4660
- if (token.l.typ == exports.EnumToken.BinaryExpressionTokenType &&
4661
- [exports.EnumToken.Add, exports.EnumToken.Sub].includes(token.l.op)) {
4662
- result = '(' + renderToken(token.l, options, cache) + ')';
4663
- }
4664
- else {
4665
- result = renderToken(token.l, options, cache);
4666
- }
4667
- result += token.op == exports.EnumToken.Mul ? '*' : '/';
4668
- if (token.r.typ == exports.EnumToken.BinaryExpressionTokenType &&
4669
- [exports.EnumToken.Add, exports.EnumToken.Sub].includes(token.r.op)) {
4670
- result += '(' + renderToken(token.r, options, cache) + ')';
4671
- }
4672
- else {
4673
- result += renderToken(token.r, options, cache);
4674
- }
4675
- return result;
4676
- }
4677
- return renderToken(token.l, options, cache) + (token.op == exports.EnumToken.Add ? ' + ' : (token.op == exports.EnumToken.Sub ? ' - ' : (token.op == exports.EnumToken.Mul ? '*' : '/'))) + renderToken(token.r, options, cache);
4678
- case exports.EnumToken.FractionTokenType:
4679
- const fraction = renderToken(token.l) + '/' + renderToken(token.r);
4680
- if (+token.r.val != 0) {
4681
- const value = minifyNumber(+token.l.val / +token.r.val);
4682
- if (value.length <= fraction.length) {
4683
- return value;
4684
- }
4685
- }
4686
- return fraction;
4687
- case exports.EnumToken.Add:
4688
- return ' + ';
4689
- case exports.EnumToken.Sub:
4690
- return ' - ';
4691
- case exports.EnumToken.UniversalSelectorTokenType:
4692
- case exports.EnumToken.Mul:
4693
- return '*';
4694
- case exports.EnumToken.Div:
4695
- return '/';
4696
- case exports.EnumToken.ColorTokenType:
4697
- if (token.kin == exports.ColorType.LIGHT_DARK || ('chi' in token && options.convertColor === false)) {
4698
- return token.val + '(' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache), '') + ')';
4699
- }
4700
- if (options.convertColor !== false) {
4701
- const value = convertColor(token, typeof options.convertColor == 'boolean' ? exports.ColorType.HEX : exports.ColorType[exports.ColorType[options.convertColor ?? 'HEX']?.toUpperCase?.().replaceAll?.('-', '_')] ?? exports.ColorType.HEX);
4702
- //
4703
- if (value != null) {
4704
- token = value;
4705
- }
4706
- }
4707
- if ([exports.ColorType.HEX, exports.ColorType.LIT, exports.ColorType.SYS, exports.ColorType.DPSYS].includes(token.kin)) {
4708
- return token.val;
4709
- }
4710
- if (Array.isArray(token.chi)) {
4711
- const isLegacy = ['rgb', 'rgba', 'hsl', 'hsla'].includes(token.val.toLowerCase());
4712
- const useAlpha = (['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'oklab', 'oklch', 'lab', 'lch'].includes(token.val.toLowerCase()) && token.chi.length == 4) ||
4713
- ('color' == token.val.toLowerCase() && token.chi.length == 5);
4714
- return (token.val.endsWith('a') ? token.val.slice(0, -1) : token.val) + '(' + token.chi.reduce((acc, curr, index, array) => {
4715
- if (/[,/]\s*$/.test(acc)) {
4716
- if (curr.typ == exports.EnumToken.WhitespaceTokenType) {
4717
- return acc.trimEnd();
4718
- }
4719
- return acc.trimStart() + renderToken(curr, options, cache);
4720
- }
4721
- if (isLegacy && curr.typ == exports.EnumToken.CommaTokenType) {
4722
- return acc.trimEnd() + ' ';
4723
- }
4724
- if (curr.typ == exports.EnumToken.WhitespaceTokenType) {
4725
- return acc.trimEnd() + ' ';
4726
- }
4727
- if (curr.typ == exports.EnumToken.CommaTokenType || (curr.typ == exports.EnumToken.LiteralTokenType && curr.val == '/')) {
4728
- return acc.trimEnd() + (curr.typ == exports.EnumToken.CommaTokenType ? ',' : '/');
4729
- }
4730
- return acc.trimEnd() + (useAlpha && index == array.length - 1 ? '/' : ' ') + renderToken(curr, options, cache);
4731
- }, '').trimStart() + ')';
4732
- }
4733
- case exports.EnumToken.ParensTokenType:
4734
- case exports.EnumToken.FunctionTokenType:
4735
- case exports.EnumToken.UrlFunctionTokenType:
4736
- case exports.EnumToken.ImageFunctionTokenType:
4737
- case exports.EnumToken.TimingFunctionTokenType:
4738
- case exports.EnumToken.PseudoClassFuncTokenType:
4739
- case exports.EnumToken.TimelineFunctionTokenType:
4740
- case exports.EnumToken.GridTemplateFuncTokenType:
4741
- if (token.typ == exports.EnumToken.FunctionTokenType &&
4742
- mathFuncs.includes(token.val) &&
4743
- token.chi.length == 1 &&
4744
- ![exports.EnumToken.BinaryExpressionTokenType, exports.EnumToken.FractionTokenType, exports.EnumToken.IdenTokenType].includes(token.chi[0].typ) &&
4745
- // @ts-ignore
4746
- token.chi[0].val?.typ != exports.EnumToken.FractionTokenType) {
4747
- return token.val + '(' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache, reducer), '') + ')';
4748
- }
4749
- return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
4750
- case exports.EnumToken.MatchExpressionTokenType:
4751
- return renderToken(token.l, options, cache, reducer, errors) +
4752
- renderToken(token.op, options, cache, reducer, errors) +
4753
- renderToken(token.r, options, cache, reducer, errors) +
4754
- (token.attr ? ' ' + token.attr : '');
4755
- case exports.EnumToken.NameSpaceAttributeTokenType:
4756
- return (token.l == null ? '' : renderToken(token.l, options, cache, reducer, errors)) + '|' +
4757
- renderToken(token.r, options, cache, reducer, errors);
4758
- case exports.EnumToken.BlockStartTokenType:
4759
- return '{';
4760
- case exports.EnumToken.BlockEndTokenType:
4761
- return '}';
4762
- case exports.EnumToken.StartParensTokenType:
4763
- return '(';
4764
- case exports.EnumToken.DelimTokenType:
4765
- case exports.EnumToken.EqualMatchTokenType:
4766
- return '=';
4767
- case exports.EnumToken.IncludeMatchTokenType:
4768
- return '~=';
4769
- case exports.EnumToken.DashMatchTokenType:
4770
- return '|=';
4771
- case exports.EnumToken.StartMatchTokenType:
4772
- return '^=';
4773
- case exports.EnumToken.EndMatchTokenType:
4774
- return '$=';
4775
- case exports.EnumToken.ContainMatchTokenType:
4776
- return '*=';
4777
- case exports.EnumToken.LtTokenType:
4778
- return '<';
4779
- case exports.EnumToken.LteTokenType:
4780
- return '<=';
4781
- case exports.EnumToken.SubsequentSiblingCombinatorTokenType:
4782
- return '~';
4783
- case exports.EnumToken.NextSiblingCombinatorTokenType:
4784
- return '+';
4785
- case exports.EnumToken.GtTokenType:
4786
- case exports.EnumToken.ChildCombinatorTokenType:
4787
- return '>';
4788
- case exports.EnumToken.GteTokenType:
4789
- return '>=';
4790
- case exports.EnumToken.ColumnCombinatorTokenType:
4791
- return '||';
4792
- case exports.EnumToken.EndParensTokenType:
4793
- return ')';
4794
- case exports.EnumToken.AttrStartTokenType:
4795
- return '[';
4796
- case exports.EnumToken.AttrEndTokenType:
4797
- return ']';
4798
- case exports.EnumToken.DescendantCombinatorTokenType:
4799
- case exports.EnumToken.WhitespaceTokenType:
4800
- return ' ';
4801
- case exports.EnumToken.ColonTokenType:
4802
- return ':';
4803
- case exports.EnumToken.SemiColonTokenType:
4804
- return ';';
4805
- case exports.EnumToken.CommaTokenType:
4806
- return ',';
4807
- case exports.EnumToken.ImportantTokenType:
4808
- return '!important';
4809
- case exports.EnumToken.AttrTokenType:
4810
- case exports.EnumToken.IdenListTokenType:
4811
- return '[' + token.chi.reduce(reducer, '') + ']';
4812
- case exports.EnumToken.TimeTokenType:
4813
- case exports.EnumToken.AngleTokenType:
4814
- case exports.EnumToken.LengthTokenType:
4815
- case exports.EnumToken.DimensionTokenType:
4816
- case exports.EnumToken.FrequencyTokenType:
4817
- case exports.EnumToken.ResolutionTokenType:
4818
- let val = token.val.typ == exports.EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
4819
- let unit = token.unit;
4820
- if (token.typ == exports.EnumToken.AngleTokenType && !val.includes('/')) {
4821
- const angle = getAngle(token);
4822
- let v;
4823
- let value = val + unit;
4824
- for (const u of ['turn', 'deg', 'rad', 'grad']) {
4825
- if (token.unit == u) {
4826
- continue;
4827
- }
4828
- switch (u) {
4829
- case 'turn':
4830
- v = minifyNumber(angle);
4831
- if (v.length + 4 < value.length) {
4832
- val = v;
4833
- unit = u;
4834
- value = v + u;
4835
- }
4836
- break;
4837
- case 'deg':
4838
- v = minifyNumber(angle * 360);
4839
- if (v.length + 3 < value.length) {
4840
- val = v;
4841
- unit = u;
4842
- value = v + u;
4843
- }
4844
- break;
4845
- case 'rad':
4846
- v = minifyNumber(angle * (2 * Math.PI));
4847
- if (v.length + 3 < value.length) {
4848
- val = v;
4849
- unit = u;
4850
- value = v + u;
4851
- }
4852
- break;
4853
- case 'grad':
4854
- v = minifyNumber(angle * 400);
4855
- if (v.length + 4 < value.length) {
4856
- val = v;
4857
- unit = u;
4858
- value = v + u;
4859
- }
4860
- break;
4861
- }
4862
- }
4863
- }
4864
- if (val === '0') {
4865
- if (token.typ == exports.EnumToken.TimeTokenType) {
4866
- return '0s';
4867
- }
4868
- if (token.typ == exports.EnumToken.FrequencyTokenType) {
4869
- return '0Hz';
4870
- }
4871
- // @ts-ignore
4872
- if (token.typ == exports.EnumToken.ResolutionTokenType) {
4873
- return '0x';
4874
- }
4875
- return '0';
4876
- }
4877
- if (token.typ == exports.EnumToken.TimeTokenType) {
4878
- if (unit == 'ms') {
4879
- // @ts-ignore
4880
- const v = minifyNumber(val / 1000);
4881
- if (v.length + 1 <= val.length) {
4882
- return v + 's';
4883
- }
4884
- return val + 'ms';
4885
- }
4886
- return val + 's';
4887
- }
4888
- if (token.typ == exports.EnumToken.ResolutionTokenType && unit == 'dppx') {
4889
- unit = 'x';
4890
- }
4891
- return val.includes('/') ? val.replace('/', unit + '/') : val + unit;
4892
- case exports.EnumToken.FlexTokenType:
4893
- case exports.EnumToken.PercentageTokenType:
4894
- const uni = token.typ == exports.EnumToken.PercentageTokenType ? '%' : 'fr';
4895
- const perc = token.val.typ == exports.EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
4896
- return options.minify && perc == '0' ? '0' : (perc.includes('/') ? perc.replace('/', uni + '/') : perc + uni);
4897
- case exports.EnumToken.NumberTokenType:
4898
- return token.val.typ == exports.EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
4899
- case exports.EnumToken.CommentTokenType:
4900
- if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
4901
- return '';
4902
- }
4903
- case exports.EnumToken.PseudoClassTokenType:
4904
- case exports.EnumToken.PseudoElementTokenType:
4905
- // https://www.w3.org/TR/selectors-4/#single-colon-pseudos
4906
- if (token.typ == exports.EnumToken.PseudoElementTokenType && pseudoElements.includes(token.val.slice(1))) {
4907
- return token.val.slice(1);
4908
- }
4909
- case exports.EnumToken.UrlTokenTokenType:
4910
- // if (token.typ == EnumToken.UrlTokenTokenType) {
4911
- //
4912
- // if (options.output != null) {
4913
- //
4914
- // if (!('original' in token)) {
4915
- //
4916
- // // do not modify original token
4917
- // token = {...token};
4918
- // Object.defineProperty(token, 'original', {
4919
- // enumerable: false,
4920
- // writable: false,
4921
- // value: (token as UrlToken).val
4922
- // })
4923
- // }
4924
- //
4925
- // // @ts-ignore
4926
- // if (!(token.original in cache)) {
4927
- //
4928
- // let output: string = <string>options.output ?? '';
4929
- // const key = output + 'abs';
4930
- //
4931
- // if (!(key in cache)) {
4932
- //
4933
- // // @ts-ignore
4934
- // cache[key] = options.dirname(options.resolve(output, options.cwd).absolute);
4935
- // }
4936
- //
4937
- // // @ts-ignore
4938
- // cache[token.original] = options.resolve(token.original, cache[key]).relative;
4939
- // }
4940
- //
4941
- // // @ts-ignore
4942
- // token.val = cache[token.original];
4943
- // }
4944
- // }
4945
- case exports.EnumToken.HashTokenType:
4946
- case exports.EnumToken.IdenTokenType:
4947
- case exports.EnumToken.AtRuleTokenType:
4948
- case exports.EnumToken.StringTokenType:
4949
- case exports.EnumToken.LiteralTokenType:
4950
- case exports.EnumToken.DashedIdenTokenType:
4951
- case exports.EnumToken.PseudoPageTokenType:
4952
- case exports.EnumToken.ClassSelectorTokenType:
4953
- return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
4954
- case exports.EnumToken.NestingSelectorTokenType:
4955
- return '&';
4956
- case exports.EnumToken.InvalidAttrTokenType:
4957
- return '[' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
4958
- case exports.EnumToken.InvalidClassSelectorTokenType:
4959
- return token.val;
4960
- case exports.EnumToken.DeclarationNodeType:
4961
- return token.nam + ':' + (options.minify ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
4962
- case exports.EnumToken.MediaQueryConditionTokenType:
4963
- return renderToken(token.l, options, cache, reducer, errors) + renderToken(token.op, options, cache, reducer, errors) + token.r.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
4964
- case exports.EnumToken.MediaFeatureTokenType:
4965
- return token.val;
4966
- case exports.EnumToken.MediaFeatureNotTokenType:
4967
- return 'not ' + renderToken(token.val, options, cache, reducer, errors);
4968
- case exports.EnumToken.MediaFeatureOnlyTokenType:
4969
- return 'only ' + renderToken(token.val, options, cache, reducer, errors);
4970
- case exports.EnumToken.MediaFeatureAndTokenType:
4971
- return 'and';
4972
- case exports.EnumToken.MediaFeatureOrTokenType:
4973
- return 'or';
4974
- }
4975
- errors?.push({ action: 'ignore', message: `render: unexpected token ${JSON.stringify(token, null, 1)}` });
4976
- return '';
4977
- }
4978
- function filterValues(values) {
4979
- let i = 0;
4980
- for (; i < values.length; i++) {
4981
- if (values[i].typ == exports.EnumToken.ImportantTokenType && values[i - 1]?.typ == exports.EnumToken.WhitespaceTokenType) {
4982
- values.splice(i - 1, 1);
4983
- }
4984
- else if (funcLike.includes(values[i].typ) && !['var', 'calc'].includes(values[i].val) && values[i + 1]?.typ == exports.EnumToken.WhitespaceTokenType) {
4985
- values.splice(i + 1, 1);
4986
- }
4987
- }
4988
- return values;
4989
- }
4990
-
4991
4682
  // https://www.w3.org/TR/CSS21/syndata.html#syntax
4992
4683
  // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
4993
4684
  // '\\'
@@ -5001,6 +4692,11 @@ const dimensionUnits = new Set([
5001
4692
  const fontFormat = ['collection', 'embedded-opentype', 'opentype', 'svg', 'truetype', 'woff', 'woff2'];
5002
4693
  const colorFontTech = ['color-colrv0', 'color-colrv1', 'color-svg', 'color-sbix', 'color-cbdt'];
5003
4694
  const fontFeaturesTech = ['features-opentype', 'features-aat', 'features-graphite', 'incremental-patch', 'incremental-range', 'incremental-auto', 'variations', 'palettes'];
4695
+ /**
4696
+ * supported transform functions
4697
+ *
4698
+ * @internal
4699
+ */
5004
4700
  const transformFunctions = [
5005
4701
  'translate', 'scale', 'rotate', 'skew', 'perspective',
5006
4702
  'translateX', 'translateY', 'translateZ',
@@ -5014,6 +4710,11 @@ const mediaTypes = ['all', 'print', 'screen',
5014
4710
  /* deprecated */
5015
4711
  'aural', 'braille', 'embossed', 'handheld', 'projection', 'tty', 'tv', 'speech'];
5016
4712
  // https://www.w3.org/TR/css-values-4/#math-function
4713
+ /**
4714
+ * supported math functions
4715
+ *
4716
+ * @internal
4717
+ */
5017
4718
  const mathFuncs = ['minmax', 'repeat', 'fit-content', 'calc', 'clamp', 'min', 'max', 'round', 'mod', 'rem', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2', 'pow', 'sqrt', 'hypot', 'log', 'exp', 'abs', 'sign'];
5018
4719
  const wildCardFuncs = ['var', 'env'];
5019
4720
  const pseudoElements = [':before', ':after', ':first-line', ':first-letter'];
@@ -5520,7 +5221,7 @@ function isColor(token) {
5520
5221
  // adding numbers and percentages is disallowed
5521
5222
  // https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/lch#defining_relative_color_output_channel_components
5522
5223
  // @ts-ignore
5523
- for (const { value } of walkValues(token.chi, null, (node) => funcLike.includes(node.typ) ? WalkerOptionEnum.IgnoreChildren : null)) {
5224
+ for (const { value } of walkValues(token.chi, null, (node) => funcLike.includes(node.typ) ? exports.WalkerOptionEnum.IgnoreChildren : null)) {
5524
5225
  if (funcLike.includes(value.typ)) {
5525
5226
  for (const { value: val } of walkValues([buildExpression(value.chi)])) {
5526
5227
  if (val.typ == exports.EnumToken.BinaryExpressionTokenType &&
@@ -7466,86 +7167,828 @@ var config$4 = {
7466
7167
  Object.freeze(config$4);
7467
7168
  const getConfig = () => config$4;
7468
7169
 
7469
- function matchType(val, properties) {
7470
- if (val.typ == exports.EnumToken.IdenTokenType && properties.keywords.includes(val.val) ||
7170
+ function matchType(val, properties) {
7171
+ if (val.typ == exports.EnumToken.IdenTokenType && properties.keywords.includes(val.val) ||
7172
+ // @ts-ignore
7173
+ (properties.types.some((t) => exports.EnumToken[t] == val.typ))) {
7174
+ return true;
7175
+ }
7176
+ if (val.typ == exports.EnumToken.NumberTokenType && val.val == 0) {
7177
+ // @ts-ignore
7178
+ return properties.types.some((type) => {
7179
+ // @ts-ignore
7180
+ const typ = exports.EnumToken[type];
7181
+ return typ == exports.EnumToken.LengthTokenType || typ == exports.EnumToken.AngleTokenType;
7182
+ });
7183
+ }
7184
+ if (val.typ == exports.EnumToken.FunctionTokenType) {
7185
+ if (mathFuncs.includes(val.val)) {
7186
+ return val.chi.every(((t) => [exports.EnumToken.Add, exports.EnumToken.Mul, exports.EnumToken.Div, exports.EnumToken.Sub, exports.EnumToken.LiteralTokenType, exports.EnumToken.CommaTokenType, exports.EnumToken.WhitespaceTokenType, exports.EnumToken.DimensionTokenType, exports.EnumToken.NumberTokenType, exports.EnumToken.LengthTokenType, exports.EnumToken.AngleTokenType, exports.EnumToken.PercentageTokenType, exports.EnumToken.ResolutionTokenType, exports.EnumToken.TimeTokenType, exports.EnumToken.BinaryExpressionTokenType].includes(t.typ) || matchType(t, properties)));
7187
+ }
7188
+ // match type defined like function 'symbols()', 'url()', 'attr()' etc.
7189
+ // return properties.types.includes((<FunctionToken>val).val + '()')
7190
+ }
7191
+ return false;
7192
+ }
7193
+
7194
+ function parseDeclarationNode(node, errors, location) {
7195
+ while (node.val[0]?.typ == exports.EnumToken.WhitespaceTokenType) {
7196
+ node.val.shift();
7197
+ }
7198
+ if (!node.nam.startsWith('--') && node.val.filter((t) => ![exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType].includes(t.typ)).length == 0) {
7199
+ errors.push({
7200
+ action: 'drop',
7201
+ message: 'doParse: invalid declaration',
7202
+ location
7203
+ });
7204
+ return null;
7205
+ }
7206
+ for (const { value: val, parent } of walkValues(node.val, node)) {
7207
+ if (val.typ == exports.EnumToken.AttrTokenType && val.chi.every((t) => [exports.EnumToken.IdenTokenType, exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType].includes(t.typ))) {
7208
+ // @ts-ignore
7209
+ val.typ = exports.EnumToken.IdenListTokenType;
7210
+ }
7211
+ else if (val.typ == exports.EnumToken.StringTokenType && (node.nam == 'grid' || node.nam == 'grid-template-areas' || node.nam == 'grid-template-rows' || node.nam == 'grid-template-columns')) {
7212
+ val.val = val.val.at(0) + parseGridTemplate(val.val.slice(1, -1)) + val.val.at(-1);
7213
+ // @ts-ignore
7214
+ const array = parent?.chi ?? node.val;
7215
+ const index = array.indexOf(val);
7216
+ if (index > 0 && array[index - 1].typ == exports.EnumToken.WhitespaceTokenType) {
7217
+ array.splice(index - 1, 1);
7218
+ }
7219
+ }
7220
+ }
7221
+ return node;
7222
+ }
7223
+ function parseGridTemplate(template) {
7224
+ let result = '';
7225
+ let buffer = '';
7226
+ for (let i = 0; i < template.length; i++) {
7227
+ const char = template[i];
7228
+ if (isWhiteSpace(char.codePointAt(0))) {
7229
+ while (i + 1 < template.length && isWhiteSpace(template[i + 1].codePointAt(0))) {
7230
+ i++;
7231
+ }
7232
+ result += buffer + ' ';
7233
+ buffer = '';
7234
+ }
7235
+ else if (char == '.') {
7236
+ while (i + 1 < template.length && template[i + 1] == '.') {
7237
+ i++;
7238
+ }
7239
+ if (isWhiteSpace((result.at(-1)?.codePointAt(0)))) {
7240
+ result = result.slice(0, -1);
7241
+ }
7242
+ result += buffer + char;
7243
+ buffer = '';
7244
+ }
7245
+ else {
7246
+ buffer += char;
7247
+ }
7248
+ }
7249
+ return buffer.length > 0 ? result + buffer : result;
7250
+ }
7251
+
7252
+ // from https://github.com/Rich-Harris/vlq/tree/master
7253
+ // credit: Rich Harris
7254
+ const integer_to_char = {};
7255
+ let i = 0;
7256
+ for (const char of 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=') {
7257
+ integer_to_char[i++] = char;
7258
+ }
7259
+ function encode(value) {
7260
+ if (typeof value === 'number') {
7261
+ return encode_integer(value);
7262
+ }
7263
+ let result = '';
7264
+ for (let i = 0; i < value.length; i += 1) {
7265
+ result += encode_integer(value[i]);
7266
+ }
7267
+ return result;
7268
+ }
7269
+ function encode_integer(num) {
7270
+ let result = '';
7271
+ if (num < 0) {
7272
+ num = (-num << 1) | 1;
7273
+ }
7274
+ else {
7275
+ num <<= 1;
7276
+ }
7277
+ do {
7278
+ let clamped = num & 31;
7279
+ num >>>= 5;
7280
+ if (num > 0) {
7281
+ clamped |= 32;
7282
+ }
7283
+ result += integer_to_char[clamped];
7284
+ } while (num > 0);
7285
+ return result;
7286
+ }
7287
+
7288
+ /**
7289
+ * Source map class
7290
+ * @internal
7291
+ */
7292
+ class SourceMap {
7293
+ /**
7294
+ * Last location
7295
+ */
7296
+ lastLocation = null;
7297
+ /**
7298
+ * Version
7299
+ * @private
7300
+ */
7301
+ #version = 3;
7302
+ /**
7303
+ * Sources
7304
+ * @private
7305
+ */
7306
+ #sources = [];
7307
+ /**
7308
+ * Map
7309
+ * @private
7310
+ */
7311
+ #map = new Map;
7312
+ /**
7313
+ * Line
7314
+ * @private
7315
+ */
7316
+ #line = -1;
7317
+ /**
7318
+ * Add a location
7319
+ * @param source
7320
+ * @param original
7321
+ */
7322
+ add(source, original) {
7323
+ if (original.src !== '') {
7324
+ if (!this.#sources.includes(original.src)) {
7325
+ this.#sources.push(original.src);
7326
+ }
7327
+ const line = source.sta.lin - 1;
7328
+ let record;
7329
+ if (line > this.#line) {
7330
+ this.#line = line;
7331
+ }
7332
+ if (!this.#map.has(line)) {
7333
+ record = [Math.max(0, source.sta.col - 1), this.#sources.indexOf(original.src), original.sta.lin - 1, original.sta.col - 1];
7334
+ this.#map.set(line, [record]);
7335
+ }
7336
+ else {
7337
+ const arr = this.#map.get(line);
7338
+ record = [Math.max(0, source.sta.col - 1 - arr[0][0]), this.#sources.indexOf(original.src) - arr[0][1], original.sta.lin - 1, original.sta.col - 1];
7339
+ arr.push(record);
7340
+ }
7341
+ if (this.lastLocation != null) {
7342
+ record[2] -= this.lastLocation.sta.lin - 1;
7343
+ record[3] -= this.lastLocation.sta.col - 1;
7344
+ }
7345
+ this.lastLocation = original;
7346
+ }
7347
+ }
7348
+ /**
7349
+ * Convert to URL encoded string
7350
+ */
7351
+ toUrl() {
7352
+ // /*# sourceMappingURL = ${url} */
7353
+ return `data:application/json,${encodeURIComponent(JSON.stringify(this.toJSON()))}`;
7354
+ }
7355
+ /**
7356
+ * Convert to JSON object
7357
+ */
7358
+ toJSON() {
7359
+ const mappings = [];
7360
+ let i = 0;
7361
+ for (; i <= this.#line; i++) {
7362
+ if (!this.#map.has(i)) {
7363
+ mappings.push('');
7364
+ }
7365
+ else {
7366
+ mappings.push(this.#map.get(i).reduce((acc, curr) => acc + (acc === '' ? '' : ',') + encode(curr), ''));
7367
+ }
7368
+ }
7369
+ return {
7370
+ version: this.#version,
7371
+ sources: this.#sources.slice(),
7372
+ mappings: mappings.join(';')
7373
+ };
7374
+ }
7375
+ }
7376
+
7377
+ /**
7378
+ * Update position
7379
+ * @param position
7380
+ * @param str
7381
+ */
7382
+ function update(position, str) {
7383
+ let i = 0;
7384
+ for (; i < str.length; i++) {
7385
+ if (isNewLine(str[i].charCodeAt(0))) {
7386
+ position.lin++;
7387
+ position.col = 0;
7388
+ }
7389
+ else {
7390
+ position.col++;
7391
+ }
7392
+ }
7393
+ }
7394
+ /**
7395
+ * render ast
7396
+ * @param data
7397
+ * @param options
7398
+ * @private
7399
+ */
7400
+ function doRender(data, options = {}) {
7401
+ const minify = options.minify ?? true;
7402
+ const beautify = options.beautify ?? !minify;
7403
+ options = {
7404
+ ...(beautify ? {
7405
+ indent: ' ',
7406
+ newLine: '\n',
7407
+ } : {
7408
+ indent: '',
7409
+ newLine: '',
7410
+ }),
7411
+ ...(minify ? {
7412
+ removeEmpty: true,
7413
+ removeComments: true,
7414
+ minify: true
7415
+ } : {
7416
+ removeEmpty: false,
7417
+ removeComments: false,
7418
+ }), sourcemap: false, convertColor: true, expandNestingRules: false, preserveLicense: false, ...options
7419
+ };
7420
+ if (options.withParents) {
7471
7421
  // @ts-ignore
7472
- (properties.types.some((t) => exports.EnumToken[t] == val.typ))) {
7473
- return true;
7422
+ let parent = data.parent;
7423
+ // @ts-ignore
7424
+ while (data.parent != null) {
7425
+ // @ts-ignore
7426
+ parent = { ...data.parent, chi: [{ ...data }] };
7427
+ // @ts-ignore
7428
+ parent.parent = data.parent.parent;
7429
+ // @ts-ignore
7430
+ data = parent;
7431
+ }
7474
7432
  }
7475
- if (val.typ == exports.EnumToken.NumberTokenType && val.val == 0) {
7433
+ const startTime = performance.now();
7434
+ const errors = [];
7435
+ const sourcemap = options.sourcemap ? new SourceMap : null;
7436
+ const cache = Object.create(null);
7437
+ const result = {
7438
+ code: renderAstNode(options.expandNestingRules ? expand(data) : data, options, sourcemap, {
7439
+ ind: 0,
7440
+ lin: 1,
7441
+ col: 1
7442
+ }, errors, function reducer(acc, curr) {
7443
+ if (curr.typ == exports.EnumToken.CommentTokenType && options.removeComments) {
7444
+ if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
7445
+ return acc;
7446
+ }
7447
+ return acc + curr.val;
7448
+ }
7449
+ return acc + renderToken(curr, options, cache, reducer, errors);
7450
+ }, cache), errors, stats: {
7451
+ total: `${(performance.now() - startTime).toFixed(2)}ms`
7452
+ }
7453
+ };
7454
+ if (options.output != null) {
7476
7455
  // @ts-ignore
7477
- return properties.types.some((type) => {
7456
+ options.output = options.resolve(options.output, options.cwd).absolute;
7457
+ }
7458
+ if (sourcemap != null) {
7459
+ result.map = sourcemap;
7460
+ if (options.sourcemap === 'inline') {
7461
+ result.code += `\n/*# sourceMappingURL=data:application/json,${encodeURIComponent(JSON.stringify(result.map))} */`;
7462
+ }
7463
+ }
7464
+ return result;
7465
+ }
7466
+ /**
7467
+ * Update source map
7468
+ * @param node
7469
+ * @param options
7470
+ * @param cache
7471
+ * @param sourcemap
7472
+ * @param position
7473
+ * @param str
7474
+ *
7475
+ * @internal
7476
+ */
7477
+ function updateSourceMap(node, options, cache, sourcemap, position, str) {
7478
+ if ([
7479
+ exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType,
7480
+ exports.EnumToken.KeyFrameRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType
7481
+ ].includes(node.typ)) {
7482
+ let src = node.loc?.src ?? '';
7483
+ let output = options.output ?? '';
7484
+ if (!(src in cache)) {
7478
7485
  // @ts-ignore
7479
- const typ = exports.EnumToken[type];
7480
- return typ == exports.EnumToken.LengthTokenType || typ == exports.EnumToken.AngleTokenType;
7486
+ cache[src] = options.resolve(src, options.cwd ?? '').relative;
7487
+ }
7488
+ if (!(output in cache)) {
7489
+ // @ts-ignore
7490
+ cache[output] = options.resolve(output, options.cwd).relative;
7491
+ }
7492
+ // @ts-ignore
7493
+ sourcemap.add({ src: cache[output], sta: { ...position } }, {
7494
+ ...node.loc,
7495
+ // @ts-ignore
7496
+ src: options.resolve(cache[src], options.cwd).relative
7481
7497
  });
7482
7498
  }
7483
- if (val.typ == exports.EnumToken.FunctionTokenType) {
7484
- if (mathFuncs.includes(val.val)) {
7485
- return val.chi.every(((t) => [exports.EnumToken.Add, exports.EnumToken.Mul, exports.EnumToken.Div, exports.EnumToken.Sub, exports.EnumToken.LiteralTokenType, exports.EnumToken.CommaTokenType, exports.EnumToken.WhitespaceTokenType, exports.EnumToken.DimensionTokenType, exports.EnumToken.NumberTokenType, exports.EnumToken.LengthTokenType, exports.EnumToken.AngleTokenType, exports.EnumToken.PercentageTokenType, exports.EnumToken.ResolutionTokenType, exports.EnumToken.TimeTokenType, exports.EnumToken.BinaryExpressionTokenType].includes(t.typ) || matchType(t, properties)));
7486
- }
7487
- // match type defined like function 'symbols()', 'url()', 'attr()' etc.
7488
- // return properties.types.includes((<FunctionToken>val).val + '()')
7499
+ update(position, str);
7500
+ }
7501
+ /**
7502
+ * render ast node
7503
+ * @param data
7504
+ * @param options
7505
+ * @param sourcemap
7506
+ * @param position
7507
+ * @param errors
7508
+ * @param reducer
7509
+ * @param cache
7510
+ * @param level
7511
+ * @param indents
7512
+ *
7513
+ * @internal
7514
+ */
7515
+ function renderAstNode(data, options, sourcemap, position, errors, reducer, cache, level = 0, indents = []) {
7516
+ if (indents.length < level + 1) {
7517
+ indents.push(options.indent.repeat(level));
7518
+ }
7519
+ if (indents.length < level + 2) {
7520
+ indents.push(options.indent.repeat(level + 1));
7521
+ }
7522
+ const indent = indents[level];
7523
+ const indentSub = indents[level + 1];
7524
+ switch (data.typ) {
7525
+ case exports.EnumToken.DeclarationNodeType:
7526
+ return `${data.nam}:${options.indent}${(options.minify ? filterValues(data.val) : data.val).reduce(reducer, '')}`;
7527
+ case exports.EnumToken.CommentNodeType:
7528
+ case exports.EnumToken.CDOCOMMNodeType:
7529
+ if (data.val.startsWith('/*# sourceMappingURL=')) {
7530
+ // ignore sourcemap
7531
+ return '';
7532
+ }
7533
+ return !options.removeComments || (options.preserveLicense && data.val.startsWith('/*!')) ? data.val : '';
7534
+ case exports.EnumToken.StyleSheetNodeType:
7535
+ return data.chi.reduce((css, node) => {
7536
+ const str = renderAstNode(node, options, sourcemap, { ...position }, errors, reducer, cache, level, indents);
7537
+ if (str === '') {
7538
+ return css;
7539
+ }
7540
+ if (css === '') {
7541
+ if (sourcemap != null && node.loc != null) {
7542
+ updateSourceMap(node, options, cache, sourcemap, position, str);
7543
+ }
7544
+ return str;
7545
+ }
7546
+ if (sourcemap != null && node.loc != null) {
7547
+ update(position, options.newLine);
7548
+ updateSourceMap(node, options, cache, sourcemap, position, str);
7549
+ }
7550
+ return `${css}${options.newLine}${str}`;
7551
+ }, '');
7552
+ case exports.EnumToken.AtRuleNodeType:
7553
+ case exports.EnumToken.RuleNodeType:
7554
+ case exports.EnumToken.KeyFrameRuleNodeType:
7555
+ case exports.EnumToken.KeyframeAtRuleNodeType:
7556
+ if ([exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType].includes(data.typ) && !('chi' in data)) {
7557
+ return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
7558
+ }
7559
+ // @ts-ignore
7560
+ let children = data.chi.reduce((css, node) => {
7561
+ let str;
7562
+ if (node.typ == exports.EnumToken.CommentNodeType) {
7563
+ str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
7564
+ }
7565
+ else if (node.typ == exports.EnumToken.DeclarationNodeType) {
7566
+ if (!node.nam.startsWith('--') && node.val.length == 0) {
7567
+ // @ts-ignore
7568
+ errors.push({
7569
+ action: 'ignore',
7570
+ message: `render: invalid declaration ${JSON.stringify(node)}`,
7571
+ location: node.loc
7572
+ });
7573
+ return '';
7574
+ }
7575
+ str = `${node.nam}:${options.indent}${(options.minify ? filterValues(node.val) : node.val).reduce(reducer, '').trimEnd()};`;
7576
+ }
7577
+ else if (node.typ == exports.EnumToken.AtRuleNodeType && !('chi' in node)) {
7578
+ str = `${data.val === '' ? '' : options.indent || ' '}${data.val};`;
7579
+ }
7580
+ else {
7581
+ str = renderAstNode(node, options, sourcemap, { ...position }, errors, reducer, cache, level + 1, indents);
7582
+ }
7583
+ if (css === '') {
7584
+ return str;
7585
+ }
7586
+ if (str === '') {
7587
+ return css;
7588
+ }
7589
+ return `${css}${options.newLine}${indentSub}${str}`;
7590
+ }, '');
7591
+ if (options.removeEmpty && children === '') {
7592
+ return '';
7593
+ }
7594
+ if (children.endsWith(';')) {
7595
+ children = children.slice(0, -1);
7596
+ }
7597
+ if ([exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType].includes(data.typ)) {
7598
+ return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
7599
+ }
7600
+ return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
7601
+ case exports.EnumToken.InvalidDeclarationNodeType:
7602
+ case exports.EnumToken.InvalidRuleTokenType:
7603
+ case exports.EnumToken.InvalidAtRuleTokenType:
7604
+ default:
7605
+ return '';
7489
7606
  }
7490
- return false;
7491
7607
  }
7492
-
7493
- function parseDeclarationNode(node, errors, location) {
7494
- while (node.val[0]?.typ == exports.EnumToken.WhitespaceTokenType) {
7495
- node.val.shift();
7496
- }
7497
- if (!node.nam.startsWith('--') && node.val.filter((t) => ![exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType].includes(t.typ)).length == 0) {
7498
- errors.push({
7499
- action: 'drop',
7500
- message: 'doParse: invalid declaration',
7501
- location
7502
- });
7503
- return null;
7608
+ /**
7609
+ * render ast token
7610
+ * @param token
7611
+ * @param options
7612
+ */
7613
+ function renderToken(token, options = {}, cache = Object.create(null), reducer, errors) {
7614
+ if (reducer == null) {
7615
+ reducer = function (acc, curr) {
7616
+ if (curr.typ == exports.EnumToken.CommentTokenType && options.removeComments) {
7617
+ if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
7618
+ return acc;
7619
+ }
7620
+ return acc + curr.val;
7621
+ }
7622
+ return acc + renderToken(curr, options, cache, reducer, errors);
7623
+ };
7504
7624
  }
7505
- for (const { value: val, parent } of walkValues(node.val, node)) {
7506
- if (val.typ == exports.EnumToken.AttrTokenType && val.chi.every((t) => [exports.EnumToken.IdenTokenType, exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType].includes(t.typ))) {
7625
+ if (token.typ == exports.EnumToken.FunctionTokenType && colorsFunc.includes(token.val)) {
7626
+ if (isColor(token)) {
7507
7627
  // @ts-ignore
7508
- val.typ = exports.EnumToken.IdenListTokenType;
7509
- }
7510
- else if (val.typ == exports.EnumToken.StringTokenType && (node.nam == 'grid' || node.nam == 'grid-template-areas' || node.nam == 'grid-template-rows' || node.nam == 'grid-template-columns')) {
7511
- val.val = val.val.at(0) + parseGridTemplate(val.val.slice(1, -1)) + val.val.at(-1);
7628
+ token.typ = exports.EnumToken.ColorTokenType;
7512
7629
  // @ts-ignore
7513
- const array = parent?.chi ?? node.val;
7514
- const index = array.indexOf(val);
7515
- if (index > 0 && array[index - 1].typ == exports.EnumToken.WhitespaceTokenType) {
7516
- array.splice(index - 1, 1);
7630
+ if (token.chi[0].typ == exports.EnumToken.IdenTokenType && token.chi[0].val == 'from') {
7631
+ // @ts-ignore
7632
+ token.cal = 'rel';
7633
+ }
7634
+ else { // @ts-ignore
7635
+ if (token.val == 'color-mix' && token.chi[0].typ == exports.EnumToken.IdenTokenType && token.chi[0].val == 'in') {
7636
+ // @ts-ignore
7637
+ token.cal = 'mix';
7638
+ }
7639
+ else {
7640
+ // @ts-ignore
7641
+ if (token.val == 'color') {
7642
+ // @ts-ignore
7643
+ token.cal = 'col';
7644
+ }
7645
+ // @ts-ignore
7646
+ token.chi = token.chi.filter((t) => ![exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommaTokenType, exports.EnumToken.CommentTokenType].includes(t.typ));
7647
+ }
7648
+ }
7649
+ }
7650
+ }
7651
+ switch (token.typ) {
7652
+ case exports.EnumToken.ListToken:
7653
+ return token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
7654
+ case exports.EnumToken.BinaryExpressionTokenType:
7655
+ if ([exports.EnumToken.Mul, exports.EnumToken.Div].includes(token.op)) {
7656
+ let result = '';
7657
+ if (token.l.typ == exports.EnumToken.BinaryExpressionTokenType &&
7658
+ [exports.EnumToken.Add, exports.EnumToken.Sub].includes(token.l.op)) {
7659
+ result = '(' + renderToken(token.l, options, cache) + ')';
7660
+ }
7661
+ else {
7662
+ result = renderToken(token.l, options, cache);
7663
+ }
7664
+ result += token.op == exports.EnumToken.Mul ? '*' : '/';
7665
+ if (token.r.typ == exports.EnumToken.BinaryExpressionTokenType &&
7666
+ [exports.EnumToken.Add, exports.EnumToken.Sub].includes(token.r.op)) {
7667
+ result += '(' + renderToken(token.r, options, cache) + ')';
7668
+ }
7669
+ else {
7670
+ result += renderToken(token.r, options, cache);
7671
+ }
7672
+ return result;
7673
+ }
7674
+ return renderToken(token.l, options, cache) + (token.op == exports.EnumToken.Add ? ' + ' : (token.op == exports.EnumToken.Sub ? ' - ' : (token.op == exports.EnumToken.Mul ? '*' : '/'))) + renderToken(token.r, options, cache);
7675
+ case exports.EnumToken.FractionTokenType:
7676
+ const fraction = renderToken(token.l) + '/' + renderToken(token.r);
7677
+ if (+token.r.val != 0) {
7678
+ const value = minifyNumber(+token.l.val / +token.r.val);
7679
+ if (value.length <= fraction.length) {
7680
+ return value;
7681
+ }
7682
+ }
7683
+ return fraction;
7684
+ case exports.EnumToken.Add:
7685
+ return ' + ';
7686
+ case exports.EnumToken.Sub:
7687
+ return ' - ';
7688
+ case exports.EnumToken.UniversalSelectorTokenType:
7689
+ case exports.EnumToken.Mul:
7690
+ return '*';
7691
+ case exports.EnumToken.Div:
7692
+ return '/';
7693
+ case exports.EnumToken.ColorTokenType:
7694
+ if (token.kin == exports.ColorType.LIGHT_DARK || ('chi' in token && options.convertColor === false)) {
7695
+ return token.val + '(' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache), '') + ')';
7696
+ }
7697
+ if (options.convertColor !== false) {
7698
+ const value = convertColor(token, typeof options.convertColor == 'boolean' ? exports.ColorType.HEX : exports.ColorType[exports.ColorType[options.convertColor ?? 'HEX']?.toUpperCase?.().replaceAll?.('-', '_')] ?? exports.ColorType.HEX);
7699
+ //
7700
+ if (value != null) {
7701
+ token = value;
7702
+ }
7703
+ }
7704
+ if ([exports.ColorType.HEX, exports.ColorType.LIT, exports.ColorType.SYS, exports.ColorType.DPSYS].includes(token.kin)) {
7705
+ return token.val;
7706
+ }
7707
+ if (Array.isArray(token.chi)) {
7708
+ const isLegacy = ['rgb', 'rgba', 'hsl', 'hsla'].includes(token.val.toLowerCase());
7709
+ const useAlpha = (['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'oklab', 'oklch', 'lab', 'lch'].includes(token.val.toLowerCase()) && token.chi.length == 4) ||
7710
+ ('color' == token.val.toLowerCase() && token.chi.length == 5);
7711
+ return (token.val.endsWith('a') ? token.val.slice(0, -1) : token.val) + '(' + token.chi.reduce((acc, curr, index, array) => {
7712
+ if (/[,/]\s*$/.test(acc)) {
7713
+ if (curr.typ == exports.EnumToken.WhitespaceTokenType) {
7714
+ return acc.trimEnd();
7715
+ }
7716
+ return acc.trimStart() + renderToken(curr, options, cache);
7717
+ }
7718
+ if (isLegacy && curr.typ == exports.EnumToken.CommaTokenType) {
7719
+ return acc.trimEnd() + ' ';
7720
+ }
7721
+ if (curr.typ == exports.EnumToken.WhitespaceTokenType) {
7722
+ return acc.trimEnd() + ' ';
7723
+ }
7724
+ if (curr.typ == exports.EnumToken.CommaTokenType || (curr.typ == exports.EnumToken.LiteralTokenType && curr.val == '/')) {
7725
+ return acc.trimEnd() + (curr.typ == exports.EnumToken.CommaTokenType ? ',' : '/');
7726
+ }
7727
+ return acc.trimEnd() + (useAlpha && index == array.length - 1 ? '/' : ' ') + renderToken(curr, options, cache);
7728
+ }, '').trimStart() + ')';
7729
+ }
7730
+ case exports.EnumToken.ParensTokenType:
7731
+ case exports.EnumToken.FunctionTokenType:
7732
+ case exports.EnumToken.UrlFunctionTokenType:
7733
+ case exports.EnumToken.ImageFunctionTokenType:
7734
+ case exports.EnumToken.TimingFunctionTokenType:
7735
+ case exports.EnumToken.PseudoClassFuncTokenType:
7736
+ case exports.EnumToken.TimelineFunctionTokenType:
7737
+ case exports.EnumToken.GridTemplateFuncTokenType:
7738
+ if (token.typ == exports.EnumToken.FunctionTokenType &&
7739
+ mathFuncs.includes(token.val) &&
7740
+ token.chi.length == 1 &&
7741
+ ![exports.EnumToken.BinaryExpressionTokenType, exports.EnumToken.FractionTokenType, exports.EnumToken.IdenTokenType].includes(token.chi[0].typ) &&
7742
+ // @ts-ignore
7743
+ token.chi[0].val?.typ != exports.EnumToken.FractionTokenType) {
7744
+ return token.val + '(' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache, reducer), '') + ')';
7745
+ }
7746
+ return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
7747
+ case exports.EnumToken.MatchExpressionTokenType:
7748
+ return renderToken(token.l, options, cache, reducer, errors) +
7749
+ renderToken(token.op, options, cache, reducer, errors) +
7750
+ renderToken(token.r, options, cache, reducer, errors) +
7751
+ (token.attr ? ' ' + token.attr : '');
7752
+ case exports.EnumToken.NameSpaceAttributeTokenType:
7753
+ return (token.l == null ? '' : renderToken(token.l, options, cache, reducer, errors)) + '|' +
7754
+ renderToken(token.r, options, cache, reducer, errors);
7755
+ case exports.EnumToken.BlockStartTokenType:
7756
+ return '{';
7757
+ case exports.EnumToken.BlockEndTokenType:
7758
+ return '}';
7759
+ case exports.EnumToken.StartParensTokenType:
7760
+ return '(';
7761
+ case exports.EnumToken.DelimTokenType:
7762
+ case exports.EnumToken.EqualMatchTokenType:
7763
+ return '=';
7764
+ case exports.EnumToken.IncludeMatchTokenType:
7765
+ return '~=';
7766
+ case exports.EnumToken.DashMatchTokenType:
7767
+ return '|=';
7768
+ case exports.EnumToken.StartMatchTokenType:
7769
+ return '^=';
7770
+ case exports.EnumToken.EndMatchTokenType:
7771
+ return '$=';
7772
+ case exports.EnumToken.ContainMatchTokenType:
7773
+ return '*=';
7774
+ case exports.EnumToken.LtTokenType:
7775
+ return '<';
7776
+ case exports.EnumToken.LteTokenType:
7777
+ return '<=';
7778
+ case exports.EnumToken.SubsequentSiblingCombinatorTokenType:
7779
+ return '~';
7780
+ case exports.EnumToken.NextSiblingCombinatorTokenType:
7781
+ return '+';
7782
+ case exports.EnumToken.GtTokenType:
7783
+ case exports.EnumToken.ChildCombinatorTokenType:
7784
+ return '>';
7785
+ case exports.EnumToken.GteTokenType:
7786
+ return '>=';
7787
+ case exports.EnumToken.ColumnCombinatorTokenType:
7788
+ return '||';
7789
+ case exports.EnumToken.EndParensTokenType:
7790
+ return ')';
7791
+ case exports.EnumToken.AttrStartTokenType:
7792
+ return '[';
7793
+ case exports.EnumToken.AttrEndTokenType:
7794
+ return ']';
7795
+ case exports.EnumToken.DescendantCombinatorTokenType:
7796
+ case exports.EnumToken.WhitespaceTokenType:
7797
+ return ' ';
7798
+ case exports.EnumToken.ColonTokenType:
7799
+ return ':';
7800
+ case exports.EnumToken.SemiColonTokenType:
7801
+ return ';';
7802
+ case exports.EnumToken.CommaTokenType:
7803
+ return ',';
7804
+ case exports.EnumToken.ImportantTokenType:
7805
+ return '!important';
7806
+ case exports.EnumToken.AttrTokenType:
7807
+ case exports.EnumToken.IdenListTokenType:
7808
+ return '[' + token.chi.reduce(reducer, '') + ']';
7809
+ case exports.EnumToken.TimeTokenType:
7810
+ case exports.EnumToken.AngleTokenType:
7811
+ case exports.EnumToken.LengthTokenType:
7812
+ case exports.EnumToken.DimensionTokenType:
7813
+ case exports.EnumToken.FrequencyTokenType:
7814
+ case exports.EnumToken.ResolutionTokenType:
7815
+ let val = token.val.typ == exports.EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
7816
+ let unit = token.unit;
7817
+ if (token.typ == exports.EnumToken.AngleTokenType && !val.includes('/')) {
7818
+ const angle = getAngle(token);
7819
+ let v;
7820
+ let value = val + unit;
7821
+ for (const u of ['turn', 'deg', 'rad', 'grad']) {
7822
+ if (token.unit == u) {
7823
+ continue;
7824
+ }
7825
+ switch (u) {
7826
+ case 'turn':
7827
+ v = minifyNumber(angle);
7828
+ if (v.length + 4 < value.length) {
7829
+ val = v;
7830
+ unit = u;
7831
+ value = v + u;
7832
+ }
7833
+ break;
7834
+ case 'deg':
7835
+ v = minifyNumber(angle * 360);
7836
+ if (v.length + 3 < value.length) {
7837
+ val = v;
7838
+ unit = u;
7839
+ value = v + u;
7840
+ }
7841
+ break;
7842
+ case 'rad':
7843
+ v = minifyNumber(angle * (2 * Math.PI));
7844
+ if (v.length + 3 < value.length) {
7845
+ val = v;
7846
+ unit = u;
7847
+ value = v + u;
7848
+ }
7849
+ break;
7850
+ case 'grad':
7851
+ v = minifyNumber(angle * 400);
7852
+ if (v.length + 4 < value.length) {
7853
+ val = v;
7854
+ unit = u;
7855
+ value = v + u;
7856
+ }
7857
+ break;
7858
+ }
7859
+ }
7517
7860
  }
7518
- }
7519
- }
7520
- return node;
7521
- }
7522
- function parseGridTemplate(template) {
7523
- let result = '';
7524
- let buffer = '';
7525
- for (let i = 0; i < template.length; i++) {
7526
- const char = template[i];
7527
- if (isWhiteSpace(char.codePointAt(0))) {
7528
- while (i + 1 < template.length && isWhiteSpace(template[i + 1].codePointAt(0))) {
7529
- i++;
7861
+ if (val === '0') {
7862
+ if (token.typ == exports.EnumToken.TimeTokenType) {
7863
+ return '0s';
7864
+ }
7865
+ if (token.typ == exports.EnumToken.FrequencyTokenType) {
7866
+ return '0Hz';
7867
+ }
7868
+ // @ts-ignore
7869
+ if (token.typ == exports.EnumToken.ResolutionTokenType) {
7870
+ return '0x';
7871
+ }
7872
+ return '0';
7530
7873
  }
7531
- result += buffer + ' ';
7532
- buffer = '';
7533
- }
7534
- else if (char == '.') {
7535
- while (i + 1 < template.length && template[i + 1] == '.') {
7536
- i++;
7874
+ if (token.typ == exports.EnumToken.TimeTokenType) {
7875
+ if (unit == 'ms') {
7876
+ // @ts-ignore
7877
+ const v = minifyNumber(val / 1000);
7878
+ if (v.length + 1 <= val.length) {
7879
+ return v + 's';
7880
+ }
7881
+ return val + 'ms';
7882
+ }
7883
+ return val + 's';
7537
7884
  }
7538
- if (isWhiteSpace((result.at(-1)?.codePointAt(0)))) {
7539
- result = result.slice(0, -1);
7885
+ if (token.typ == exports.EnumToken.ResolutionTokenType && unit == 'dppx') {
7886
+ unit = 'x';
7540
7887
  }
7541
- result += buffer + char;
7542
- buffer = '';
7888
+ return val.includes('/') ? val.replace('/', unit + '/') : val + unit;
7889
+ case exports.EnumToken.FlexTokenType:
7890
+ case exports.EnumToken.PercentageTokenType:
7891
+ const uni = token.typ == exports.EnumToken.PercentageTokenType ? '%' : 'fr';
7892
+ const perc = token.val.typ == exports.EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
7893
+ return options.minify && perc == '0' ? '0' : (perc.includes('/') ? perc.replace('/', uni + '/') : perc + uni);
7894
+ case exports.EnumToken.NumberTokenType:
7895
+ return token.val.typ == exports.EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
7896
+ case exports.EnumToken.CommentTokenType:
7897
+ if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
7898
+ return '';
7899
+ }
7900
+ case exports.EnumToken.PseudoClassTokenType:
7901
+ case exports.EnumToken.PseudoElementTokenType:
7902
+ // https://www.w3.org/TR/selectors-4/#single-colon-pseudos
7903
+ if (token.typ == exports.EnumToken.PseudoElementTokenType && pseudoElements.includes(token.val.slice(1))) {
7904
+ return token.val.slice(1);
7905
+ }
7906
+ case exports.EnumToken.UrlTokenTokenType:
7907
+ // if (token.typ == EnumToken.UrlTokenTokenType) {
7908
+ //
7909
+ // if (options.output != null) {
7910
+ //
7911
+ // if (!('original' in token)) {
7912
+ //
7913
+ // // do not modify original token
7914
+ // token = {...token};
7915
+ // Object.defineProperty(token, 'original', {
7916
+ // enumerable: false,
7917
+ // writable: false,
7918
+ // value: (token as UrlToken).val
7919
+ // })
7920
+ // }
7921
+ //
7922
+ // // @ts-ignore
7923
+ // if (!(token.original in cache)) {
7924
+ //
7925
+ // let output: string = <string>options.output ?? '';
7926
+ // const key = output + 'abs';
7927
+ //
7928
+ // if (!(key in cache)) {
7929
+ //
7930
+ // // @ts-ignore
7931
+ // cache[key] = options.dirname(options.resolve(output, options.cwd).absolute);
7932
+ // }
7933
+ //
7934
+ // // @ts-ignore
7935
+ // cache[token.original] = options.resolve(token.original, cache[key]).relative;
7936
+ // }
7937
+ //
7938
+ // // @ts-ignore
7939
+ // token.val = cache[token.original];
7940
+ // }
7941
+ // }
7942
+ case exports.EnumToken.HashTokenType:
7943
+ case exports.EnumToken.IdenTokenType:
7944
+ case exports.EnumToken.AtRuleTokenType:
7945
+ case exports.EnumToken.StringTokenType:
7946
+ case exports.EnumToken.LiteralTokenType:
7947
+ case exports.EnumToken.DashedIdenTokenType:
7948
+ case exports.EnumToken.PseudoPageTokenType:
7949
+ case exports.EnumToken.ClassSelectorTokenType:
7950
+ return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
7951
+ case exports.EnumToken.NestingSelectorTokenType:
7952
+ return '&';
7953
+ case exports.EnumToken.InvalidAttrTokenType:
7954
+ return '[' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
7955
+ case exports.EnumToken.InvalidClassSelectorTokenType:
7956
+ return token.val;
7957
+ case exports.EnumToken.DeclarationNodeType:
7958
+ return token.nam + ':' + (options.minify ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
7959
+ case exports.EnumToken.MediaQueryConditionTokenType:
7960
+ return renderToken(token.l, options, cache, reducer, errors) + renderToken(token.op, options, cache, reducer, errors) + token.r.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
7961
+ case exports.EnumToken.MediaFeatureTokenType:
7962
+ return token.val;
7963
+ case exports.EnumToken.MediaFeatureNotTokenType:
7964
+ return 'not ' + renderToken(token.val, options, cache, reducer, errors);
7965
+ case exports.EnumToken.MediaFeatureOnlyTokenType:
7966
+ return 'only ' + renderToken(token.val, options, cache, reducer, errors);
7967
+ case exports.EnumToken.MediaFeatureAndTokenType:
7968
+ return 'and';
7969
+ case exports.EnumToken.MediaFeatureOrTokenType:
7970
+ return 'or';
7971
+ }
7972
+ errors?.push({ action: 'ignore', message: `render: unexpected token ${JSON.stringify(token, null, 1)}` });
7973
+ return '';
7974
+ }
7975
+ /**
7976
+ * Remove whitespace tokens that are not needed
7977
+ * @param values
7978
+ *
7979
+ * @internal
7980
+ */
7981
+ function filterValues(values) {
7982
+ let i = 0;
7983
+ for (; i < values.length; i++) {
7984
+ if (values[i].typ == exports.EnumToken.ImportantTokenType && values[i - 1]?.typ == exports.EnumToken.WhitespaceTokenType) {
7985
+ values.splice(i - 1, 1);
7543
7986
  }
7544
- else {
7545
- buffer += char;
7987
+ else if (funcLike.includes(values[i].typ) && !['var', 'calc'].includes(values[i].val) && values[i + 1]?.typ == exports.EnumToken.WhitespaceTokenType) {
7988
+ values.splice(i + 1, 1);
7546
7989
  }
7547
7990
  }
7548
- return buffer.length > 0 ? result + buffer : result;
7991
+ return values;
7549
7992
  }
7550
7993
 
7551
7994
  var TokenMap;
@@ -7581,7 +8024,7 @@ var TokenMap;
7581
8024
  })(TokenMap || (TokenMap = {}));
7582
8025
  function consumeWhiteSpace(parseInfo) {
7583
8026
  let count = 0;
7584
- while (isWhiteSpace(parseInfo.stream.charAt(count + parseInfo.currentPosition.ind + 1).charCodeAt(0))) {
8027
+ while (isWhiteSpace(parseInfo.stream.charCodeAt(count + parseInfo.currentPosition.ind + 1))) {
7585
8028
  count++;
7586
8029
  }
7587
8030
  next(parseInfo, count);
@@ -7687,11 +8130,8 @@ function peek(parseInfo, count = 1) {
7687
8130
  }
7688
8131
  return parseInfo.stream.slice(parseInfo.currentPosition.ind + 1, parseInfo.currentPosition.ind + count + 1);
7689
8132
  }
7690
- function prev(parseInfo, count = 1) {
7691
- if (count == 1) {
7692
- return parseInfo.currentPosition.ind == 0 ? '' : parseInfo.stream.charAt(parseInfo.currentPosition.ind - 1);
7693
- }
7694
- return parseInfo.stream.slice(parseInfo.currentPosition.ind - 1 - count, parseInfo.currentPosition.ind - 1);
8133
+ function prev(parseInfo) {
8134
+ return parseInfo.stream.charAt(parseInfo.currentPosition.ind - 1);
7695
8135
  }
7696
8136
  function next(parseInfo, count = 1) {
7697
8137
  let char = '';
@@ -7711,17 +8151,14 @@ function next(parseInfo, count = 1) {
7711
8151
  }
7712
8152
  /**
7713
8153
  * tokenize css string
7714
- * @param stream
8154
+ * @param parseInfo
8155
+ * @param yieldEOFToken
7715
8156
  */
7716
- function* tokenize$1(stream) {
7717
- const parseInfo = {
7718
- stream,
7719
- position: { ind: 0, lin: 1, col: 1 },
7720
- currentPosition: { ind: -1, lin: 1, col: 0 }
7721
- };
8157
+ function* tokenize$1(parseInfo, yieldEOFToken = true) {
7722
8158
  let value;
7723
- let buffer = '';
8159
+ let buffer = parseInfo.buffer;
7724
8160
  let charCode;
8161
+ parseInfo.buffer = '';
7725
8162
  while (value = next(parseInfo)) {
7726
8163
  charCode = value.charCodeAt(0);
7727
8164
  if (isWhiteSpace(charCode)) {
@@ -7984,11 +8421,6 @@ function* tokenize$1(stream) {
7984
8421
  break;
7985
8422
  }
7986
8423
  }
7987
- if (value === '') {
7988
- yield pushToken(buffer, parseInfo, exports.EnumToken.BadUrlTokenType);
7989
- buffer = '';
7990
- break;
7991
- }
7992
8424
  charCode = value.charCodeAt(0);
7993
8425
  }
7994
8426
  // '\\'
@@ -8026,16 +8458,6 @@ function* tokenize$1(stream) {
8026
8458
  }
8027
8459
  while (value = next(parseInfo)) {
8028
8460
  charCode = value.charCodeAt(0);
8029
- if (charCode == 0x5c) {
8030
- buffer += value + next(parseInfo);
8031
- continue;
8032
- }
8033
- if (charCode == 0x29) {
8034
- yield pushToken(buffer, parseInfo, exports.EnumToken.BadStringTokenType);
8035
- yield pushToken('', parseInfo, exports.EnumToken.EndParensTokenType);
8036
- buffer = '';
8037
- break;
8038
- }
8039
8461
  buffer += value;
8040
8462
  }
8041
8463
  if (hasNewLine) {
@@ -8052,40 +8474,12 @@ function* tokenize$1(stream) {
8052
8474
  buffer = '';
8053
8475
  while (value = next(parseInfo)) {
8054
8476
  charCode = value.charCodeAt(0);
8055
- // ')'
8056
- if (charCode == 0x29) {
8477
+ if (charCode == 0x29) { // ')'
8057
8478
  yield pushToken(buffer, parseInfo, exports.EnumToken.UrlTokenTokenType);
8058
8479
  yield pushToken('', parseInfo, exports.EnumToken.EndParensTokenType);
8059
8480
  buffer = '';
8060
8481
  break;
8061
8482
  }
8062
- // if (errorState) {
8063
- //
8064
- // buffer += whitespace + value;
8065
- //
8066
- // while (value = peek(parseInfo)) {
8067
- //
8068
- // charCode = value.charCodeAt(0);
8069
- //
8070
- // if (charCode == 0x5c) {
8071
- //
8072
- // buffer += next(parseInfo, 2);
8073
- // continue;
8074
- // }
8075
- //
8076
- // // ')'
8077
- // if (charCode == 0x29) {
8078
- //
8079
- // break;
8080
- // }
8081
- //
8082
- // buffer += next(parseInfo);
8083
- // }
8084
- //
8085
- // yield pushToken(buffer, parseInfo, EnumToken.BadUrlTokenType);
8086
- // buffer = '';
8087
- // break;
8088
- // }
8089
8483
  buffer += value;
8090
8484
  }
8091
8485
  }
@@ -8124,10 +8518,6 @@ function* tokenize$1(stream) {
8124
8518
  buffer = '!';
8125
8519
  break;
8126
8520
  case 64 /* TokenMap.AT */:
8127
- if (buffer.length > 0) {
8128
- yield pushToken(buffer, parseInfo);
8129
- buffer = '';
8130
- }
8131
8521
  buffer = value;
8132
8522
  {
8133
8523
  let val = peek(parseInfo);
@@ -8145,27 +8535,40 @@ function* tokenize$1(stream) {
8145
8535
  break;
8146
8536
  default:
8147
8537
  buffer += value;
8148
- if (buffer.length == 1) {
8149
- if (buffer == 'h') {
8150
- if (match$1(parseInfo, 'ttp://') || match$1(parseInfo, 'ttps://')) {
8151
- let val = peek(parseInfo);
8152
- while (val != ')' && val != ';' && !isWhiteSpace(val.charCodeAt(0))) {
8153
- buffer += next(parseInfo);
8154
- val = peek(parseInfo);
8155
- }
8156
- yield pushToken(buffer, parseInfo);
8157
- buffer = '';
8158
- break;
8159
- }
8160
- }
8161
- }
8162
8538
  break;
8163
8539
  }
8164
8540
  }
8165
- if (buffer.length > 0) {
8166
- yield pushToken(buffer, parseInfo);
8541
+ if (yieldEOFToken) {
8542
+ if (buffer.length > 0) {
8543
+ yield pushToken(buffer, parseInfo);
8544
+ }
8545
+ yield pushToken('', parseInfo, exports.EnumToken.EOFTokenType);
8546
+ }
8547
+ else {
8548
+ parseInfo.buffer = buffer;
8549
+ }
8550
+ }
8551
+ /**
8552
+ * tokenize readable stream
8553
+ * @param input
8554
+ */
8555
+ async function* tokenizeStream(input) {
8556
+ const parseInfo = {
8557
+ stream: '',
8558
+ buffer: '',
8559
+ position: { ind: 0, lin: 1, col: 1 },
8560
+ currentPosition: { ind: -1, lin: 1, col: 0 }
8561
+ };
8562
+ const decoder = new TextDecoder('utf-8');
8563
+ const reader = input.getReader();
8564
+ while (true) {
8565
+ const { done, value } = await reader.read();
8566
+ parseInfo.stream += decoder.decode(value, { stream: true });
8567
+ yield* tokenize$1(parseInfo, done);
8568
+ if (done) {
8569
+ break;
8570
+ }
8167
8571
  }
8168
- yield pushToken('', parseInfo, exports.EnumToken.EOFTokenType);
8169
8572
  }
8170
8573
 
8171
8574
  var declarations = {
@@ -8473,10 +8876,10 @@ var declarations = {
8473
8876
  syntax: "normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>"
8474
8877
  },
8475
8878
  "align-items": {
8476
- syntax: "normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ]"
8879
+ syntax: "normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ] | anchor-center"
8477
8880
  },
8478
8881
  "align-self": {
8479
- syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>"
8882
+ syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position> | anchor-center"
8480
8883
  },
8481
8884
  "align-tracks": {
8482
8885
  syntax: "[ normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position> ]#"
@@ -8536,7 +8939,7 @@ var declarations = {
8536
8939
  syntax: "<easing-function>#"
8537
8940
  },
8538
8941
  appearance: {
8539
- syntax: "none | auto | textfield | menulist-button | <compat-auto>"
8942
+ syntax: "none | auto | <compat-auto> | <compat-special>"
8540
8943
  },
8541
8944
  "aspect-ratio": {
8542
8945
  syntax: "auto || <ratio>"
@@ -8548,7 +8951,7 @@ var declarations = {
8548
8951
  syntax: "visible | hidden"
8549
8952
  },
8550
8953
  background: {
8551
- syntax: "[ <bg-layer> , ]* <final-bg-layer>"
8954
+ syntax: "<bg-layer>#? , <final-bg-layer>"
8552
8955
  },
8553
8956
  "background-attachment": {
8554
8957
  syntax: "<attachment>#"
@@ -8635,10 +9038,10 @@ var declarations = {
8635
9038
  syntax: "<'border-top-color'>"
8636
9039
  },
8637
9040
  "border-bottom-left-radius": {
8638
- syntax: "<length-percentage>{1,2}"
9041
+ syntax: "<length-percentage [0,∞]>{1,2}"
8639
9042
  },
8640
9043
  "border-bottom-right-radius": {
8641
- syntax: "<length-percentage>{1,2}"
9044
+ syntax: "<length-percentage [0,∞]>{1,2}"
8642
9045
  },
8643
9046
  "border-bottom-style": {
8644
9047
  syntax: "<line-style>"
@@ -8647,7 +9050,7 @@ var declarations = {
8647
9050
  syntax: "<line-width>"
8648
9051
  },
8649
9052
  "border-collapse": {
8650
- syntax: "collapse | separate"
9053
+ syntax: "separate | collapse"
8651
9054
  },
8652
9055
  "border-color": {
8653
9056
  syntax: "<color>{1,4}"
@@ -8662,19 +9065,19 @@ var declarations = {
8662
9065
  syntax: "<'border-image-source'> || <'border-image-slice'> [ / <'border-image-width'> | / <'border-image-width'>? / <'border-image-outset'> ]? || <'border-image-repeat'>"
8663
9066
  },
8664
9067
  "border-image-outset": {
8665
- syntax: "[ <length> | <number> ]{1,4}"
9068
+ syntax: "[ <length [0,∞]> | <number [0,∞]> ]{1,4} "
8666
9069
  },
8667
9070
  "border-image-repeat": {
8668
9071
  syntax: "[ stretch | repeat | round | space ]{1,2}"
8669
9072
  },
8670
9073
  "border-image-slice": {
8671
- syntax: "<number-percentage>{1,4} && fill?"
9074
+ syntax: "[ <number [0,∞]> | <percentage [0,∞]> ]{1,4} && fill?"
8672
9075
  },
8673
9076
  "border-image-source": {
8674
9077
  syntax: "none | <image>"
8675
9078
  },
8676
9079
  "border-image-width": {
8677
- syntax: "[ <length-percentage> | <number> | auto ]{1,4}"
9080
+ syntax: "[ <length-percentage [0,∞]> | <number [0,∞]> | auto ]{1,4}"
8678
9081
  },
8679
9082
  "border-inline": {
8680
9083
  syntax: "<'border-block-start'>"
@@ -8725,7 +9128,7 @@ var declarations = {
8725
9128
  syntax: "<line-width>"
8726
9129
  },
8727
9130
  "border-radius": {
8728
- syntax: "<length-percentage>{1,4} [ / <length-percentage>{1,4} ]?"
9131
+ syntax: "<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?"
8729
9132
  },
8730
9133
  "border-right": {
8731
9134
  syntax: "<line-width> || <line-style> || <color>"
@@ -8740,7 +9143,7 @@ var declarations = {
8740
9143
  syntax: "<line-width>"
8741
9144
  },
8742
9145
  "border-spacing": {
8743
- syntax: "<length> <length>?"
9146
+ syntax: "<length>{1,2}"
8744
9147
  },
8745
9148
  "border-start-end-radius": {
8746
9149
  syntax: "<'border-top-left-radius'>"
@@ -8758,10 +9161,10 @@ var declarations = {
8758
9161
  syntax: "<color>"
8759
9162
  },
8760
9163
  "border-top-left-radius": {
8761
- syntax: "<length-percentage>{1,2}"
9164
+ syntax: "<length-percentage [0,∞]>{1,2}"
8762
9165
  },
8763
9166
  "border-top-right-radius": {
8764
- syntax: "<length-percentage>{1,2}"
9167
+ syntax: "<length-percentage [0,∞]>{1,2}"
8765
9168
  },
8766
9169
  "border-top-style": {
8767
9170
  syntax: "<line-style>"
@@ -8773,7 +9176,7 @@ var declarations = {
8773
9176
  syntax: "<line-width>{1,4}"
8774
9177
  },
8775
9178
  bottom: {
8776
- syntax: "<length> | <percentage> | auto"
9179
+ syntax: "auto | <length-percentage> | <anchor()> | <anchor-size()>"
8777
9180
  },
8778
9181
  "box-align": {
8779
9182
  syntax: "start | center | end | baseline | stretch"
@@ -8908,7 +9311,7 @@ var declarations = {
8908
9311
  syntax: "normal | [ [ size | inline-size ] || scroll-state ]"
8909
9312
  },
8910
9313
  content: {
8911
- syntax: "normal | none | [ <content-replacement> | <content-list> ] [/ [ <string> | <counter> ]+ ]?"
9314
+ syntax: "normal | none | [ <content-replacement> | <content-list> ] [ / [ <string> | <counter> | <attr()> ]+ ]?"
8912
9315
  },
8913
9316
  "content-visibility": {
8914
9317
  syntax: "visible | auto | hidden"
@@ -9202,16 +9605,16 @@ var declarations = {
9202
9605
  syntax: "normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]"
9203
9606
  },
9204
9607
  "justify-items": {
9205
- syntax: "normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ]"
9608
+ syntax: "normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center"
9206
9609
  },
9207
9610
  "justify-self": {
9208
- syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ]"
9611
+ syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center"
9209
9612
  },
9210
9613
  "justify-tracks": {
9211
9614
  syntax: "[ normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ] ]#"
9212
9615
  },
9213
9616
  left: {
9214
- syntax: "<length> | <percentage> | auto"
9617
+ syntax: "auto | <length-percentage> | <anchor()> | <anchor-size()>"
9215
9618
  },
9216
9619
  "letter-spacing": {
9217
9620
  syntax: "normal | <length> normal | <length-percentage>"
@@ -9256,7 +9659,7 @@ var declarations = {
9256
9659
  syntax: "<'margin-top'>"
9257
9660
  },
9258
9661
  "margin-bottom": {
9259
- syntax: "<length-percentage> | auto"
9662
+ syntax: "<length-percentage> | auto | <anchor-size()>"
9260
9663
  },
9261
9664
  "margin-inline": {
9262
9665
  syntax: "<'margin-top'>{1,2}"
@@ -9268,13 +9671,13 @@ var declarations = {
9268
9671
  syntax: "<'margin-top'>"
9269
9672
  },
9270
9673
  "margin-left": {
9271
- syntax: "<length-percentage> | auto"
9674
+ syntax: "<length-percentage> | auto | <anchor-size()>"
9272
9675
  },
9273
9676
  "margin-right": {
9274
- syntax: "<length-percentage> | auto"
9677
+ syntax: "<length-percentage> | auto | <anchor-size()>"
9275
9678
  },
9276
9679
  "margin-top": {
9277
- syntax: "<length-percentage> | auto"
9680
+ syntax: "<length-percentage> | auto | <anchor-size()>"
9278
9681
  },
9279
9682
  "margin-trim": {
9280
9683
  syntax: "none | in-flow | all"
@@ -9382,7 +9785,7 @@ var declarations = {
9382
9785
  syntax: "auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()> | stretch | <-non-standard-size>"
9383
9786
  },
9384
9787
  "mix-blend-mode": {
9385
- syntax: "<blend-mode> | plus-lighter"
9788
+ syntax: "<blend-mode> | plus-darker | plus-lighter"
9386
9789
  },
9387
9790
  "object-fit": {
9388
9791
  syntax: "fill | contain | cover | none | scale-down"
@@ -9580,7 +9983,7 @@ var declarations = {
9580
9983
  syntax: "none | both | horizontal | vertical | block | inline"
9581
9984
  },
9582
9985
  right: {
9583
- syntax: "<length> | <percentage> | auto"
9986
+ syntax: "auto | <length-percentage> | <anchor()> | <anchor-size()>"
9584
9987
  },
9585
9988
  rotate: {
9586
9989
  syntax: "none | <angle> | [ x | y | z | <number>{3} ] && <angle>"
@@ -9880,7 +10283,7 @@ var declarations = {
9880
10283
  syntax: "none | <dashed-ident>#"
9881
10284
  },
9882
10285
  top: {
9883
- syntax: "<length> | <percentage> | auto"
10286
+ syntax: "auto | <length-percentage> | <anchor()> | <anchor-size()>"
9884
10287
  },
9885
10288
  "touch-action": {
9886
10289
  syntax: "auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] || pinch-zoom ] | manipulation"
@@ -10559,7 +10962,7 @@ var syntaxes = {
10559
10962
  syntax: "<visual-box> | border-area | text"
10560
10963
  },
10561
10964
  "bg-image": {
10562
- syntax: "none | <image>"
10965
+ syntax: "<image> | none"
10563
10966
  },
10564
10967
  "bg-layer": {
10565
10968
  syntax: "<bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <visual-box> || <visual-box>"
@@ -10568,7 +10971,7 @@ var syntaxes = {
10568
10971
  syntax: "[ [ left | center | right | top | bottom | <length-percentage> ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] | [ center | [ left | right ] <length-percentage>? ] && [ center | [ top | bottom ] <length-percentage>? ] ]"
10569
10972
  },
10570
10973
  "bg-size": {
10571
- syntax: "[ <length-percentage> | auto ]{1,2} | cover | contain"
10974
+ syntax: "[ <length-percentage [0,∞]> | auto ]{1,2} | cover | contain"
10572
10975
  },
10573
10976
  "blend-mode": {
10574
10977
  syntax: "normal | multiply | screen | overlay | darken | lighten | color-dodge | color-burn | hard-light | soft-light | difference | exclusion | hue | saturation | color | luminosity"
@@ -10658,7 +11061,10 @@ var syntaxes = {
10658
11061
  syntax: "[ common-ligatures | no-common-ligatures ]"
10659
11062
  },
10660
11063
  "compat-auto": {
10661
- syntax: "searchfield | textarea | push-button | slider-horizontal | checkbox | radio | square-button | menulist | listbox | meter | progress-bar | button"
11064
+ syntax: "searchfield | textarea | checkbox | radio | menulist | listbox | meter | progress-bar | button"
11065
+ },
11066
+ "compat-special": {
11067
+ syntax: "textfield | menulist-button"
10662
11068
  },
10663
11069
  "complex-selector": {
10664
11070
  syntax: "<complex-selector-unit> [ <combinator>? <complex-selector-unit> ]*"
@@ -10838,7 +11244,7 @@ var syntaxes = {
10838
11244
  syntax: "[ <filter-function> | <url> ]+"
10839
11245
  },
10840
11246
  "final-bg-layer": {
10841
- syntax: "<'background-color'> || <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <visual-box> || <visual-box>"
11247
+ syntax: "<bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <visual-box> || <visual-box> || <'background-color'>"
10842
11248
  },
10843
11249
  "fit-content()": {
10844
11250
  syntax: "fit-content( <length-percentage [0,∞]> )"
@@ -13961,6 +14367,7 @@ const matchUrl = /^(https?:)?\/\//;
13961
14367
  /**
13962
14368
  * return the directory name of a path
13963
14369
  * @param path
14370
+ * @internal
13964
14371
  */
13965
14372
  function dirname(path) {
13966
14373
  if (path == '/' || path === '') {
@@ -13983,6 +14390,11 @@ function dirname(path) {
13983
14390
  parts.pop();
13984
14391
  return parts.length == 0 ? '/' : parts.join('/');
13985
14392
  }
14393
+ /**
14394
+ * split path
14395
+ * @param result
14396
+ * @private
14397
+ */
13986
14398
  function splitPath(result) {
13987
14399
  const parts = [''];
13988
14400
  let i = 0;
@@ -14012,9 +14424,11 @@ function splitPath(result) {
14012
14424
  }
14013
14425
  /**
14014
14426
  * resolve path
14015
- * @param url
14016
- * @param currentDirectory
14017
- * @param cwd
14427
+ * @param url url or path to resolve
14428
+ * @param currentDirectory directory used to resolve the path
14429
+ * @param cwd current working directory
14430
+ *
14431
+ * @private
14018
14432
  */
14019
14433
  function resolve(url, currentDirectory, cwd) {
14020
14434
  if (matchUrl.test(url)) {
@@ -14054,6 +14468,21 @@ function resolve(url, currentDirectory, cwd) {
14054
14468
  };
14055
14469
  }
14056
14470
 
14471
+ /**
14472
+ * feature walk mode
14473
+ */
14474
+ exports.FeatureWalkMode = void 0;
14475
+ (function (FeatureWalkMode) {
14476
+ /**
14477
+ * pre process
14478
+ */
14479
+ FeatureWalkMode[FeatureWalkMode["Pre"] = 0] = "Pre";
14480
+ /**
14481
+ * post process
14482
+ */
14483
+ FeatureWalkMode[FeatureWalkMode["Post"] = 1] = "Post";
14484
+ })(exports.FeatureWalkMode || (exports.FeatureWalkMode = {}));
14485
+
14057
14486
  const config$2 = getSyntaxConfig();
14058
14487
  // @ts-ignore
14059
14488
  const allValues = getSyntaxConfig()["declarations" /* ValidationSyntaxGroupEnum.Declarations */].all.syntax.trim().split(/[\s|]+/g);
@@ -16762,10 +17191,12 @@ function reject(reason) {
16762
17191
  }
16763
17192
  /**
16764
17193
  * parse css string
16765
- * @param iterator
17194
+ * @param iter
16766
17195
  * @param options
17196
+ *
17197
+ * @private
16767
17198
  */
16768
- async function doParse(iterator, options = {}) {
17199
+ async function doParse(iter, options = {}) {
16769
17200
  if (options.signal != null) {
16770
17201
  options.signal.addEventListener('abort', reject);
16771
17202
  }
@@ -16835,12 +17266,13 @@ async function doParse(iterator, options = {}) {
16835
17266
  src: ''
16836
17267
  };
16837
17268
  }
16838
- const iter = tokenize$1(iterator);
16839
17269
  let item;
16840
17270
  let node;
16841
17271
  const rawTokens = [];
16842
17272
  const imports = [];
16843
- while (item = iter.next().value) {
17273
+ // @ts-ignore ignore error
17274
+ const isAsync = typeof iter[Symbol.asyncIterator] === 'function';
17275
+ while (item = isAsync ? (await iter.next()).value : iter.next().value) {
16844
17276
  stats.bytesIn = item.bytesIn;
16845
17277
  rawTokens.push(item);
16846
17278
  if (item.hint != null && BadTokensTypes.includes(item.hint)) {
@@ -16884,7 +17316,7 @@ async function doParse(iterator, options = {}) {
16884
17316
  let inBlock = 1;
16885
17317
  tokens = [item];
16886
17318
  do {
16887
- item = iter.next().value;
17319
+ item = isAsync ? (await iter.next()).value : iter.next().value;
16888
17320
  if (item == null) {
16889
17321
  break;
16890
17322
  }
@@ -16946,8 +17378,8 @@ async function doParse(iterator, options = {}) {
16946
17378
  }
16947
17379
  }
16948
17380
  if (context != null && context.typ == exports.EnumToken.InvalidRuleTokenType) {
16949
- // @ts-ignore
16950
- const index = context.chi.findIndex((node) => node == context);
17381
+ // @ts-ignore ignore error
17382
+ const index = context.chi.findIndex((node) => node === context);
16951
17383
  if (index > -1) {
16952
17384
  context.chi.splice(index, 1);
16953
17385
  }
@@ -16958,13 +17390,21 @@ async function doParse(iterator, options = {}) {
16958
17390
  const token = node.tokens[0];
16959
17391
  const url = token.typ == exports.EnumToken.StringTokenType ? token.val.slice(1, -1) : token.val;
16960
17392
  try {
16961
- const root = await options.load(url, options.src).then((src) => {
16962
- return doParse(src, Object.assign({}, options, {
17393
+ const root = await options.getStream(url, options.src).then(async (stream) => {
17394
+ return doParse(tokenizeStream(stream), Object.assign({}, options, {
16963
17395
  minify: false,
16964
17396
  setParent: false,
16965
17397
  src: options.resolve(url, options.src).absolute
16966
- }));
17398
+ })); // )
16967
17399
  });
17400
+ // const root: ParseResult = await options.load!(url, <string>options.src).then((src: string) => {
17401
+ //
17402
+ // return doParse(src, Object.assign({}, options, {
17403
+ // minify: false,
17404
+ // setParent: false,
17405
+ // src: options.resolve!(url, options.src as string).absolute
17406
+ // }))
17407
+ // });
16968
17408
  stats.importedBytesIn += root.stats.bytesIn;
16969
17409
  stats.imports.push(root.stats);
16970
17410
  node.parent.chi.splice(node.parent.chi.indexOf(node), 1, ...root.ast.chi);
@@ -16973,7 +17413,7 @@ async function doParse(iterator, options = {}) {
16973
17413
  }
16974
17414
  }
16975
17415
  catch (error) {
16976
- // @ts-ignore
17416
+ // @ts-ignore ignore error
16977
17417
  errors.push({ action: 'ignore', message: 'doParse: ' + error.message, error });
16978
17418
  }
16979
17419
  }));
@@ -16997,28 +17437,33 @@ async function doParse(iterator, options = {}) {
16997
17437
  if (result.node.typ == exports.EnumToken.DeclarationNodeType &&
16998
17438
  (typeof options.visitor.Declaration == 'function' || options.visitor.Declaration?.[result.node.nam] != null)) {
16999
17439
  const callable = typeof options.visitor.Declaration == 'function' ? options.visitor.Declaration : options.visitor.Declaration[result.node.nam];
17000
- const results = await callable(result.node);
17440
+ const isAsync = Object.getPrototypeOf(callable).constructor.name == 'AsyncFunction';
17441
+ const results = isAsync ? await callable(result.node) : callable(result.node);
17001
17442
  if (results == null || (Array.isArray(results) && results.length == 0)) {
17002
17443
  continue;
17003
17444
  }
17445
+ // @ts-ignore
17004
17446
  result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
17005
17447
  }
17006
17448
  else if (options.visitor.Rule != null && result.node.typ == exports.EnumToken.RuleNodeType) {
17007
- const results = await options.visitor.Rule(result.node);
17449
+ const isAsync = Object.getPrototypeOf(options.visitor.Rule).constructor.name == 'AsyncFunction';
17450
+ const results = isAsync ? await options.visitor.Rule(result.node) : options.visitor.Rule(result.node);
17008
17451
  if (results == null || (Array.isArray(results) && results.length == 0)) {
17009
17452
  continue;
17010
17453
  }
17454
+ // @ts-ignore
17011
17455
  result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
17012
17456
  }
17013
17457
  else if (options.visitor.AtRule != null &&
17014
17458
  result.node.typ == exports.EnumToken.AtRuleNodeType &&
17015
- // @ts-ignore
17016
17459
  (typeof options.visitor.AtRule == 'function' || options.visitor.AtRule?.[result.node.nam] != null)) {
17017
17460
  const callable = typeof options.visitor.AtRule == 'function' ? options.visitor.AtRule : options.visitor.AtRule[result.node.nam];
17018
- const results = await callable(result.node);
17461
+ const isAsync = Object.getPrototypeOf(callable).constructor.name == 'AsyncFunction';
17462
+ const results = isAsync ? await callable(result.node) : callable(result.node);
17019
17463
  if (results == null || (Array.isArray(results) && results.length == 0)) {
17020
17464
  continue;
17021
17465
  }
17466
+ // @ts-ignore
17022
17467
  result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
17023
17468
  }
17024
17469
  }
@@ -17129,7 +17574,13 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
17129
17574
  // @ts-ignore
17130
17575
  ['charset', 'layer', 'import'].includes(context.chi[i].nam))) {
17131
17576
  // @ts-ignore
17132
- errors.push({ action: 'drop', message: 'invalid @import', location, rawTokens: [atRule, ...tokens] });
17577
+ errors.push({
17578
+ action: 'drop',
17579
+ message: 'invalid @import',
17580
+ location,
17581
+ // @ts-ignore
17582
+ rawTokens: [atRule, ...tokens]
17583
+ });
17133
17584
  return null;
17134
17585
  }
17135
17586
  }
@@ -17486,7 +17937,7 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
17486
17937
  return null;
17487
17938
  }
17488
17939
  for (const { value: token } of walkValues(value, null, {
17489
- fn: (node) => node.typ == exports.EnumToken.FunctionTokenType && node.val == 'calc' ? WalkerOptionEnum.IgnoreChildren : null,
17940
+ fn: (node) => node.typ == exports.EnumToken.FunctionTokenType && node.val == 'calc' ? exports.WalkerOptionEnum.IgnoreChildren : null,
17490
17941
  type: exports.EnumToken.FunctionTokenType
17491
17942
  })) {
17492
17943
  if (token.typ == exports.EnumToken.FunctionTokenType && token.val == 'calc') {
@@ -17726,6 +18177,27 @@ function parseAtRulePrelude(tokens, atRule) {
17726
18177
  }
17727
18178
  return tokens;
17728
18179
  }
18180
+ /**
18181
+ * parse a string as an array of declaration nodes
18182
+ * @param declaration
18183
+ *
18184
+ * Example:
18185
+ * ````ts
18186
+ *
18187
+ * const declarations = await parseDeclarations('color: red; background: blue');
18188
+ * console.log(declarations);
18189
+ * ```
18190
+ */
18191
+ async function parseDeclarations(declaration) {
18192
+ return doParse(tokenize$1({
18193
+ stream: `.x{${declaration}}`,
18194
+ buffer: '',
18195
+ position: { ind: 0, lin: 1, col: 1 },
18196
+ currentPosition: { ind: -1, lin: 1, col: 0 }
18197
+ }), { setParent: false, minify: false, validation: false }).then(result => {
18198
+ return result.ast.chi[0].chi.filter(t => t.typ == exports.EnumToken.DeclarationNodeType);
18199
+ });
18200
+ }
17729
18201
  /**
17730
18202
  * parse selector
17731
18203
  * @param tokens
@@ -17827,12 +18299,33 @@ function parseSelector(tokens) {
17827
18299
  return tokens;
17828
18300
  }
17829
18301
  /**
17830
- * parse css string
18302
+ * parse css string and return an array of tokens
17831
18303
  * @param src
17832
18304
  * @param options
18305
+ *
18306
+ * @private
18307
+ *
18308
+ * Example:
18309
+ *
18310
+ * ```ts
18311
+ *
18312
+ * import {parseString} from '@tbela99/css-parser';
18313
+ *
18314
+ * let tokens = parseString('body { color: red; }');
18315
+ * console.log(tokens);
18316
+ *
18317
+ * tokens = parseString('#c322c980');
18318
+ * console.log(tokens);
18319
+ * ```
17833
18320
  */
17834
18321
  function parseString(src, options = { location: false }) {
17835
- return parseTokens([...tokenize$1(src)].reduce((acc, t) => {
18322
+ const parseInfo = {
18323
+ stream: src,
18324
+ buffer: '',
18325
+ position: { ind: 0, lin: 1, col: 1 },
18326
+ currentPosition: { ind: -1, lin: 1, col: 0 }
18327
+ };
18328
+ return parseTokens([...tokenize$1(parseInfo)].reduce((acc, t) => {
17836
18329
  if (t.hint == exports.EnumToken.EOFTokenType) {
17837
18330
  return acc;
17838
18331
  }
@@ -17844,6 +18337,11 @@ function parseString(src, options = { location: false }) {
17844
18337
  return acc;
17845
18338
  }, []));
17846
18339
  }
18340
+ /**
18341
+ * get token type from a string
18342
+ * @param val
18343
+ * @param hint
18344
+ */
17847
18345
  function getTokenType(val, hint) {
17848
18346
  if (hint != null) {
17849
18347
  return enumTokenHints.has(hint) ? { typ: hint } : { typ: hint, val };
@@ -18009,9 +18507,24 @@ function getTokenType(val, hint) {
18009
18507
  };
18010
18508
  }
18011
18509
  /**
18012
- * parse token array into a tree structure
18510
+ * parse function tokens in a token array
18013
18511
  * @param tokens
18014
18512
  * @param options
18513
+ *
18514
+ * Example:
18515
+ *
18516
+ * ```ts
18517
+ *
18518
+ * import {parseString, parseTokens} from '@tbela99/css-parser';
18519
+ *
18520
+ * let tokens = parseString('body { color: red; }');
18521
+ * console.log(parseTokens(tokens));
18522
+ *
18523
+ * tokens = parseString('#c322c980');
18524
+ * console.log(parseTokens(tokens));
18525
+ * ```
18526
+ *
18527
+ * @private
18015
18528
  */
18016
18529
  function parseTokens(tokens, options = {}) {
18017
18530
  for (let i = 0; i < tokens.length; i++) {
@@ -18335,18 +18848,36 @@ function eq(a, b) {
18335
18848
  return true;
18336
18849
  }
18337
18850
 
18338
- var WalkerOptionEnum;
18851
+ exports.WalkerOptionEnum = void 0;
18339
18852
  (function (WalkerOptionEnum) {
18853
+ /**
18854
+ * ignore the current node and its children
18855
+ */
18340
18856
  WalkerOptionEnum[WalkerOptionEnum["Ignore"] = 0] = "Ignore";
18857
+ /**
18858
+ * stop walking the tree
18859
+ */
18341
18860
  WalkerOptionEnum[WalkerOptionEnum["Stop"] = 1] = "Stop";
18861
+ /**
18862
+ * ignore node and process children
18863
+ */
18342
18864
  WalkerOptionEnum[WalkerOptionEnum["Children"] = 2] = "Children";
18865
+ /**
18866
+ * ignore children
18867
+ */
18343
18868
  WalkerOptionEnum[WalkerOptionEnum["IgnoreChildren"] = 3] = "IgnoreChildren";
18344
- })(WalkerOptionEnum || (WalkerOptionEnum = {}));
18345
- var WalkerValueEvent;
18869
+ })(exports.WalkerOptionEnum || (exports.WalkerOptionEnum = {}));
18870
+ exports.WalkerValueEvent = void 0;
18346
18871
  (function (WalkerValueEvent) {
18872
+ /**
18873
+ * enter node
18874
+ */
18347
18875
  WalkerValueEvent[WalkerValueEvent["Enter"] = 0] = "Enter";
18876
+ /**
18877
+ * leave node
18878
+ */
18348
18879
  WalkerValueEvent[WalkerValueEvent["Leave"] = 1] = "Leave";
18349
- })(WalkerValueEvent || (WalkerValueEvent = {}));
18880
+ })(exports.WalkerValueEvent || (exports.WalkerValueEvent = {}));
18350
18881
  /**
18351
18882
  * walk ast nodes
18352
18883
  * @param node
@@ -18360,10 +18891,10 @@ function* walk(node, filter) {
18360
18891
  let option = null;
18361
18892
  if (filter != null) {
18362
18893
  option = filter(node);
18363
- if (option === WalkerOptionEnum.Ignore) {
18894
+ if (option === exports.WalkerOptionEnum.Ignore) {
18364
18895
  continue;
18365
18896
  }
18366
- if (option === WalkerOptionEnum.Stop) {
18897
+ if (option === exports.WalkerOptionEnum.Stop) {
18367
18898
  break;
18368
18899
  }
18369
18900
  }
@@ -18372,7 +18903,7 @@ function* walk(node, filter) {
18372
18903
  // @ts-ignore
18373
18904
  yield { node, parent: map.get(node), root };
18374
18905
  }
18375
- if (option !== WalkerOptionEnum.IgnoreChildren && 'chi' in node) {
18906
+ if (option !== exports.WalkerOptionEnum.IgnoreChildren && 'chi' in node) {
18376
18907
  parents.unshift(...node.chi);
18377
18908
  for (const child of node.chi.slice()) {
18378
18909
  map.set(child, node);
@@ -18395,29 +18926,29 @@ function* walkValues(values, root = null, filter, reverse) {
18395
18926
  // let parent: FunctionToken | ParensToken | BinaryExpressionToken | null = null;
18396
18927
  if (filter != null && typeof filter == 'function') {
18397
18928
  filter = {
18398
- event: WalkerValueEvent.Enter,
18929
+ event: exports.WalkerValueEvent.Enter,
18399
18930
  fn: filter
18400
18931
  };
18401
18932
  }
18402
18933
  else if (filter == null) {
18403
18934
  filter = {
18404
- event: WalkerValueEvent.Enter
18935
+ event: exports.WalkerValueEvent.Enter
18405
18936
  };
18406
18937
  }
18407
- const eventType = filter.event ?? WalkerValueEvent.Enter;
18938
+ const eventType = filter.event ?? exports.WalkerValueEvent.Enter;
18408
18939
  while (stack.length > 0) {
18409
18940
  let value = reverse ? stack.pop() : stack.shift();
18410
18941
  let option = null;
18411
- if (filter.fn != null && eventType == WalkerValueEvent.Enter) {
18942
+ if (filter.fn != null && eventType == exports.WalkerValueEvent.Enter) {
18412
18943
  const isValid = filter.type == null || value.typ == filter.type ||
18413
18944
  (Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
18414
18945
  (typeof filter.type == 'function' && filter.type(value));
18415
18946
  if (isValid) {
18416
18947
  option = filter.fn(value, map.get(value) ?? root);
18417
- if (option === WalkerOptionEnum.Ignore) {
18948
+ if (option === exports.WalkerOptionEnum.Ignore) {
18418
18949
  continue;
18419
18950
  }
18420
- if (option === WalkerOptionEnum.Stop) {
18951
+ if (option === exports.WalkerOptionEnum.Stop) {
18421
18952
  break;
18422
18953
  }
18423
18954
  // @ts-ignore
@@ -18426,7 +18957,7 @@ function* walkValues(values, root = null, filter, reverse) {
18426
18957
  }
18427
18958
  }
18428
18959
  }
18429
- if (eventType == WalkerValueEvent.Enter && option !== WalkerOptionEnum.Children) {
18960
+ if (eventType == exports.WalkerValueEvent.Enter && option !== exports.WalkerOptionEnum.Children) {
18430
18961
  yield {
18431
18962
  value,
18432
18963
  parent: map.get(value) ?? root,
@@ -18436,7 +18967,7 @@ function* walkValues(values, root = null, filter, reverse) {
18436
18967
  root: root ?? null
18437
18968
  };
18438
18969
  }
18439
- if (option !== WalkerOptionEnum.IgnoreChildren && 'chi' in value) {
18970
+ if (option !== exports.WalkerOptionEnum.IgnoreChildren && 'chi' in value) {
18440
18971
  const sliced = value.chi.slice();
18441
18972
  for (const child of sliced) {
18442
18973
  map.set(child, value);
@@ -18481,7 +19012,7 @@ function* walkValues(values, root = null, filter, reverse) {
18481
19012
  stack.unshift(...values);
18482
19013
  }
18483
19014
  }
18484
- if (eventType == WalkerValueEvent.Leave && filter.fn != null) {
19015
+ if (eventType == exports.WalkerValueEvent.Leave && filter.fn != null) {
18485
19016
  const isValid = filter.type == null || value.typ == filter.type ||
18486
19017
  (Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
18487
19018
  (typeof filter.type == 'function' && filter.type(value));
@@ -18493,7 +19024,7 @@ function* walkValues(values, root = null, filter, reverse) {
18493
19024
  }
18494
19025
  }
18495
19026
  }
18496
- if (eventType == WalkerValueEvent.Leave && option !== WalkerOptionEnum.Children) {
19027
+ if (eventType == exports.WalkerValueEvent.Leave && option !== exports.WalkerOptionEnum.Children) {
18497
19028
  yield {
18498
19029
  value,
18499
19030
  parent: map.get(value) ?? root,
@@ -19753,7 +20284,7 @@ class ComputeCalcExpressionFeature {
19753
20284
  }
19754
20285
  const set = new Set;
19755
20286
  for (const { value, parent } of walkValues(node.val, node, {
19756
- event: WalkerValueEvent.Enter,
20287
+ event: exports.WalkerValueEvent.Enter,
19757
20288
  // @ts-ignore
19758
20289
  fn(node, parent) {
19759
20290
  if (parent != null &&
@@ -19765,7 +20296,7 @@ class ComputeCalcExpressionFeature {
19765
20296
  mathFuncs.includes(node.val) &&
19766
20297
  node.chi.length == 1 &&
19767
20298
  node.chi[0].typ == exports.EnumToken.IdenTokenType) {
19768
- return WalkerOptionEnum.Ignore;
20299
+ return exports.WalkerOptionEnum.Ignore;
19769
20300
  }
19770
20301
  if ((node.typ == exports.EnumToken.FunctionTokenType && node.val == 'var') || (!mathFuncs.includes(parent.val) && [exports.EnumToken.ColorTokenType, exports.EnumToken.DeclarationNodeType, exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType, exports.EnumToken.StyleSheetNodeType].includes(parent?.typ))) {
19771
20302
  return null;
@@ -19781,7 +20312,7 @@ class ComputeCalcExpressionFeature {
19781
20312
  // @ts-ignore
19782
20313
  node[key] = slice;
19783
20314
  }
19784
- return WalkerOptionEnum.Ignore;
20315
+ return exports.WalkerOptionEnum.Ignore;
19785
20316
  }
19786
20317
  return null;
19787
20318
  }
@@ -20935,25 +21466,20 @@ var allFeatures = /*#__PURE__*/Object.freeze({
20935
21466
  TransformCssFeature: TransformCssFeature
20936
21467
  });
20937
21468
 
20938
- var FeatureWalkMode;
20939
- (function (FeatureWalkMode) {
20940
- FeatureWalkMode[FeatureWalkMode["Pre"] = 0] = "Pre";
20941
- FeatureWalkMode[FeatureWalkMode["Post"] = 1] = "Post";
20942
- })(FeatureWalkMode || (FeatureWalkMode = {}));
20943
-
20944
21469
  const combinators = ['+', '>', '~', '||', '|'];
20945
21470
  const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
20946
21471
  const notEndingWith = ['(', '['].concat(combinators);
20947
21472
  // @ts-ignore
20948
21473
  const features = Object.values(allFeatures).sort((a, b) => a.ordering - b.ordering);
20949
21474
  /**
20950
- * minify ast
21475
+ * apply minification rules to the ast tree
20951
21476
  * @param ast
20952
21477
  * @param options
20953
21478
  * @param recursive
20954
21479
  * @param errors
20955
21480
  * @param nestingContent
20956
- * @param context
21481
+ *
21482
+ * @private
20957
21483
  */
20958
21484
  function minify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
20959
21485
  let preprocess = false;
@@ -20997,7 +21523,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
20997
21523
  if (!feature.preProcess) {
20998
21524
  continue;
20999
21525
  }
21000
- feature.run(parent, options, parent.parent ?? ast, context, FeatureWalkMode.Pre);
21526
+ feature.run(parent, options, parent.parent ?? ast, context, exports.FeatureWalkMode.Pre);
21001
21527
  }
21002
21528
  if (('chi' in parent)) {
21003
21529
  // @ts-ignore
@@ -21012,14 +21538,13 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
21012
21538
  for (const feature of options.features) {
21013
21539
  if (feature.preProcess && 'cleanup' in feature) {
21014
21540
  // @ts-ignore
21015
- feature.cleanup(ast, options, context, FeatureWalkMode.Pre);
21541
+ feature.cleanup(ast, options, context, exports.FeatureWalkMode.Pre);
21016
21542
  }
21017
21543
  }
21018
21544
  }
21019
21545
  doMinify(ast, options, recursive, errors, nestingContent, context);
21020
21546
  parents = [ast];
21021
21547
  for (const parent of parents) {
21022
- // parent = parents.shift() as AstNode;
21023
21548
  if (parent.typ == exports.EnumToken.CommentTokenType ||
21024
21549
  parent.typ == exports.EnumToken.CDOCOMMTokenType) {
21025
21550
  continue;
@@ -21029,7 +21554,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
21029
21554
  if (!feature.postProcess) {
21030
21555
  continue;
21031
21556
  }
21032
- feature.run(parent, options, parent.parent ?? ast, context, FeatureWalkMode.Post);
21557
+ feature.run(parent, options, parent.parent ?? ast, context, exports.FeatureWalkMode.Post);
21033
21558
  }
21034
21559
  }
21035
21560
  if (('chi' in parent)) {
@@ -21046,12 +21571,21 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
21046
21571
  for (const feature of options.features) {
21047
21572
  if (feature.postProcess && 'cleanup' in feature) {
21048
21573
  // @ts-ignore
21049
- feature.cleanup(ast, options, context, FeatureWalkMode.Post);
21574
+ feature.cleanup(ast, options, context, exports.FeatureWalkMode.Post);
21050
21575
  }
21051
21576
  }
21052
21577
  }
21053
21578
  return ast;
21054
21579
  }
21580
+ /**
21581
+ * reduce selectors
21582
+ * @param acc
21583
+ * @param curr
21584
+ * @param index
21585
+ * @param array
21586
+ *
21587
+ * @private
21588
+ */
21055
21589
  function reduce(acc, curr, index, array) {
21056
21590
  // trim :is()
21057
21591
  // if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
@@ -21062,20 +21596,21 @@ function reduce(acc, curr, index, array) {
21062
21596
  if (curr[1] == ' ' && !isIdent(curr[2]) && !isFunction(curr[2])) {
21063
21597
  curr.splice(0, 2);
21064
21598
  }
21065
- // else if (combinators.includes(curr[1])) {
21066
- //
21067
- // curr.shift();
21068
- // }
21069
21599
  }
21070
- // else { // @ts-ignore
21071
- // if (this.typ == EnumToken.RuleNodeType && (isIdent(curr[0]) || isFunction(curr[0]))) {
21072
- //
21073
- // curr.unshift('&', ' ');
21074
- // }
21075
- // }
21076
21600
  acc.push(curr.join(''));
21077
21601
  return acc;
21078
21602
  }
21603
+ /**
21604
+ * apply minification rules to the ast tree
21605
+ * @param ast
21606
+ * @param options
21607
+ * @param recursive
21608
+ * @param errors
21609
+ * @param nestingContent
21610
+ * @param context
21611
+ *
21612
+ * @private
21613
+ */
21079
21614
  function doMinify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
21080
21615
  if (!('nodes' in context)) {
21081
21616
  context.nodes = new Set;
@@ -21102,13 +21637,6 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
21102
21637
  }
21103
21638
  // @ts-ignore
21104
21639
  node = ast.chi[i];
21105
- // @ts-ignore
21106
- // if (previous == node) {
21107
- //
21108
- // // @ts-ignore
21109
- // ast.chi.splice(i--, 1);
21110
- // continue;
21111
- // }
21112
21640
  if (node.typ == exports.EnumToken.AtRuleNodeType && node.nam == 'font-face') {
21113
21641
  continue;
21114
21642
  }
@@ -21260,12 +21788,7 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
21260
21788
  curr.splice(0, 2);
21261
21789
  }
21262
21790
  else {
21263
- // if (ast.typ != EnumToken.RuleNodeType && combinators.includes(curr[1])) {
21264
- //
21265
- // wrap = false;
21266
- // } else {
21267
21791
  curr.splice(0, 1);
21268
- // }
21269
21792
  }
21270
21793
  }
21271
21794
  else if (combinators.includes(curr[0])) {
@@ -21307,11 +21830,6 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
21307
21830
  }
21308
21831
  // @ts-ignore
21309
21832
  let sel = wrap ? node.optimized.optimized.join('') + `:is(${rule})` : rule;
21310
- // if (rule.includes('&')) {
21311
- //
21312
- // // @ts-ignore
21313
- // rule = replaceCompound(rule, node.optimized.optimized[0]);
21314
- // }
21315
21833
  if (sel.length < node.sel.length) {
21316
21834
  node.sel = sel;
21317
21835
  }
@@ -21344,13 +21862,6 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
21344
21862
  node.chi.unshift(...previous.chi);
21345
21863
  // @ts-ignore
21346
21864
  ast.chi.splice(nodeIndex, 1);
21347
- // @ts-ignore
21348
- // if (!hasDeclaration(node)) {
21349
- // // @ts-ignore
21350
- // // minifyRule(node, <MinifyOptions>options, ast, context);
21351
- // // } else {
21352
- // doMinify(node, options, recursive, errors, nestingContent, context);
21353
- // }
21354
21865
  i--;
21355
21866
  previous = node;
21356
21867
  nodeIndex = i;
@@ -21362,13 +21873,10 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
21362
21873
  if (intersect.node1.chi.length == 0) {
21363
21874
  // @ts-ignore
21364
21875
  ast.chi.splice(i--, 1);
21365
- // @ts-ignore
21366
- // node = ast.chi[i];
21367
21876
  }
21368
21877
  else {
21369
21878
  // @ts-ignore
21370
21879
  ast.chi.splice(i--, 1, intersect.node1);
21371
- // node = ast.chi intersect.node1;
21372
21880
  }
21373
21881
  if (intersect.node2.chi.length == 0) {
21374
21882
  // @ts-ignore
@@ -21401,33 +21909,11 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
21401
21909
  if (recursive && previous != node) {
21402
21910
  // @ts-ignore
21403
21911
  if (!hasDeclaration(previous)) {
21404
- // @ts-ignore
21405
- // minifyRule(previous, <MinifyOptions>options, ast, context);
21406
- // } else {
21407
21912
  doMinify(previous, options, recursive, errors, nestingContent, context);
21408
21913
  }
21409
21914
  }
21410
21915
  }
21411
- // else {
21412
- //
21413
- // if ('chi' in previous) {
21414
- //
21415
- // // @ts-ignore
21416
- // if (!hasDeclaration(previous)) {
21417
- //
21418
- // // @ts-ignore
21419
- // // minifyRule(previous, <MinifyOptions>options, ast, context);
21420
- // // } else {
21421
- //
21422
- // doMinify(previous, options, recursive, errors, nestingContent, context);
21423
- // }
21424
- // }
21425
- // }
21426
21916
  }
21427
- // else if ('chi' in node) {
21428
- //
21429
- // doMinify(node, options, recursive, errors, nestingContent, context);
21430
- // }
21431
21917
  if (!nestingContent &&
21432
21918
  // @ts-ignore
21433
21919
  previous != null &&
@@ -21460,6 +21946,12 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
21460
21946
  }
21461
21947
  return ast;
21462
21948
  }
21949
+ /**
21950
+ * check if a rule has a declaration
21951
+ * @param node
21952
+ *
21953
+ * @private
21954
+ */
21463
21955
  function hasDeclaration(node) {
21464
21956
  // @ts-ignore
21465
21957
  for (let i = 0; i < node.chi?.length; i++) {
@@ -21475,11 +21967,10 @@ function hasDeclaration(node) {
21475
21967
  /**
21476
21968
  * optimize selector
21477
21969
  * @param selector
21970
+ *
21971
+ * @private
21478
21972
  */
21479
21973
  function optimizeSelector(selector) {
21480
- // if (selector.length == 0) {
21481
- // return null;
21482
- // }
21483
21974
  selector = selector.reduce((acc, curr) => {
21484
21975
  // @ts-ignore
21485
21976
  if (curr.length > 0 && curr.at(-1).startsWith(':is(')) {
@@ -21527,11 +22018,6 @@ function optimizeSelector(selector) {
21527
22018
  break;
21528
22019
  }
21529
22020
  selector.forEach((selector) => selector.splice(0, optimized.length));
21530
- // combinator
21531
- // if (combinators.includes(<string>optimized.at(-1))) {
21532
- // const combinator: string = <string>optimized.pop();
21533
- // selector.forEach((selector: string[]) => selector.unshift(combinator));
21534
- // }
21535
22021
  let reducible = optimized.length == 1;
21536
22022
  if (optimized[0] == '&') {
21537
22023
  if (optimized[1] == ' ') {
@@ -21579,6 +22065,8 @@ function optimizeSelector(selector) {
21579
22065
  /**
21580
22066
  * split selector string
21581
22067
  * @param buffer
22068
+ *
22069
+ * @internal
21582
22070
  */
21583
22071
  function splitRule(buffer) {
21584
22072
  const result = [[]];
@@ -21586,17 +22074,6 @@ function splitRule(buffer) {
21586
22074
  for (let i = 0; i < buffer.length; i++) {
21587
22075
  let chr = buffer.charAt(i);
21588
22076
  if (isWhiteSpace(chr.charCodeAt(0))) {
21589
- // let k: number = i;
21590
- // while (k + 1 < buffer.length) {
21591
- //
21592
- // if (isWhiteSpace(buffer[k + 1].charCodeAt(0))) {
21593
- //
21594
- // k++;
21595
- // continue;
21596
- // }
21597
- //
21598
- // break;
21599
- // }
21600
22077
  if (str !== '') {
21601
22078
  // @ts-ignore
21602
22079
  result.at(-1).push(str);
@@ -21658,22 +22135,6 @@ function splitRule(buffer) {
21658
22135
  str += buffer.charAt(++i);
21659
22136
  continue;
21660
22137
  }
21661
- // if (chr == '"' || chr == "'") {
21662
- //
21663
- // let k = i;
21664
- // while (++k < buffer.length) {
21665
- // chr = buffer.charAt(k);
21666
- // str += chr;
21667
- // if (chr == '//') {
21668
- // str += buffer.charAt(++k);
21669
- // continue;
21670
- // }
21671
- // if (chr == buffer.charAt(i)) {
21672
- // break;
21673
- // }
21674
- // }
21675
- // continue;
21676
- // }
21677
22138
  if (chr == '(' || chr == '[') {
21678
22139
  const open = chr;
21679
22140
  const close = chr == '(' ? ')' : ']';
@@ -21706,11 +22167,14 @@ function splitRule(buffer) {
21706
22167
  }
21707
22168
  return result;
21708
22169
  }
22170
+ /**
22171
+ * reduce selector
22172
+ * @param acc
22173
+ * @param curr
22174
+ *
22175
+ * @private
22176
+ */
21709
22177
  function reduceSelector(acc, curr) {
21710
- // if (acc === null) {
21711
- //
21712
- // return null;
21713
- // }
21714
22178
  let hasCompoundSelector = true;
21715
22179
  // @ts-ignore
21716
22180
  curr = curr.slice(this.match[0].length);
@@ -21722,16 +22186,6 @@ function reduceSelector(acc, curr) {
21722
22186
  }
21723
22187
  break;
21724
22188
  }
21725
- // invalid function match
21726
- // if (curr.length > 0 && curr[0].endsWith('(') && curr.at(-1) != ')') {
21727
- //
21728
- // return null;
21729
- // }
21730
- //
21731
- // if (curr.length == 1 && combinators.includes(curr[0].charAt(0))) {
21732
- //
21733
- // return null;
21734
- // }
21735
22189
  if (hasCompoundSelector && curr.length > 0) {
21736
22190
  hasCompoundSelector = !['&'].concat(combinators).includes(curr[0].charAt(0));
21737
22191
  }
@@ -21741,15 +22195,6 @@ function reduceSelector(acc, curr) {
21741
22195
  if (index == 0) {
21742
22196
  canReduce = curr[1] == '&';
21743
22197
  }
21744
- // else if (token.endsWith('(')) {
21745
- //
21746
- // if (inFunction == 0) {
21747
- //
21748
- // canReduce = false;
21749
- // }
21750
- //
21751
- // inFunction++;
21752
- // }
21753
22198
  else if (token == ')') ;
21754
22199
  else if (token == ',') {
21755
22200
  if (!canReduce) {
@@ -21761,10 +22206,6 @@ function reduceSelector(acc, curr) {
21761
22206
  acc.at(-1)?.push(token);
21762
22207
  return acc;
21763
22208
  }, [[]]);
21764
- // if (inFunction > 0) {
21765
- //
21766
- // canReduce = false;
21767
- // }
21768
22209
  if (canReduce) {
21769
22210
  curr = isCompound.reduce((acc, curr) => {
21770
22211
  if (acc.length > 0) {
@@ -21779,7 +22220,14 @@ function reduceSelector(acc, curr) {
21779
22220
  acc.push(this.match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
21780
22221
  return acc;
21781
22222
  }
21782
- function matchSelectors(selector1, selector2, parentType, errors) {
22223
+ /**
22224
+ * match selectors
22225
+ * @param selector1
22226
+ * @param selector2
22227
+ *
22228
+ * @private
22229
+ */
22230
+ function matchSelectors(selector1, selector2 /*, parentType: EnumToken, errors: ErrorDescription[] */) {
21783
22231
  let match = [[]];
21784
22232
  const j = Math.min(selector1.reduce((acc, curr) => Math.min(acc, curr.length), selector1.length > 0 ? selector1[0].length : 0), selector2.reduce((acc, curr) => Math.min(acc, curr.length), selector2.length > 0 ? selector2[0].length : 0));
21785
22233
  let i = 0;
@@ -21810,52 +22258,15 @@ function matchSelectors(selector1, selector2, parentType, errors) {
21810
22258
  if (!matching) {
21811
22259
  break;
21812
22260
  }
21813
- // if (token == ',') {
21814
- //
21815
- // match.push([]);
21816
- // } else {
21817
22261
  if (token.endsWith('(')) {
21818
22262
  matchFunction++;
21819
22263
  }
21820
- // if (token.endsWith('[')) {
21821
- //
21822
- // inAttr++;
21823
- // } else if (token == ')') {
21824
- //
21825
- // matchFunction--;
21826
- // } else if (token == ']') {
21827
- //
21828
- // inAttr--;
21829
- // }
21830
22264
  match.at(-1).push(token);
21831
- // }
21832
22265
  }
21833
22266
  // invalid function
21834
22267
  if (matchFunction != 0 || inAttr != 0) {
21835
22268
  return null;
21836
22269
  }
21837
- // if (parentType != EnumToken.RuleNodeType) {
21838
- //
21839
- // for (const part of match) {
21840
- //
21841
- // if (part.length > 0 && combinators.includes(part[0].charAt(0))) {
21842
- //
21843
- // return null;
21844
- // }
21845
- // }
21846
- // }
21847
- // if (match.length > 1) {
21848
- //
21849
- // errors?.push({
21850
- // action: 'ignore',
21851
- // message: `minify: unsupported multilevel matching\n${JSON.stringify({
21852
- // match,
21853
- // selector1,
21854
- // selector2
21855
- // }, null, 1)}`
21856
- // });
21857
- // return null;
21858
- // }
21859
22270
  for (const part of match) {
21860
22271
  while (part.length > 0) {
21861
22272
  const token = part.at(-1);
@@ -21884,6 +22295,12 @@ function matchSelectors(selector1, selector2, parentType, errors) {
21884
22295
  selector2
21885
22296
  };
21886
22297
  }
22298
+ /**
22299
+ * fix selector
22300
+ * @param node
22301
+ *
22302
+ * @private
22303
+ */
21887
22304
  function fixSelector(node) {
21888
22305
  // @ts-ignore
21889
22306
  if (node.sel.includes('&')) {
@@ -21901,6 +22318,18 @@ function fixSelector(node) {
21901
22318
  node.sel = attributes.reduce((acc, curr) => acc + renderToken(curr), '');
21902
22319
  }
21903
22320
  }
22321
+ /**
22322
+ * wrap nodes
22323
+ * @param previous
22324
+ * @param node
22325
+ * @param match
22326
+ * @param ast
22327
+ * @param reducer
22328
+ * @param i
22329
+ * @param nodeIndex
22330
+ *
22331
+ * @private
22332
+ */
21904
22333
  function wrapNodes(previous, node, match, ast, reducer, i, nodeIndex) {
21905
22334
  // @ts-ignore
21906
22335
  let pSel = match.selector1.reduce(reducer, []).join(',');
@@ -21946,6 +22375,15 @@ function wrapNodes(previous, node, match, ast, reducer, i, nodeIndex) {
21946
22375
  reduceRuleSelector(wrapper);
21947
22376
  return wrapper;
21948
22377
  }
22378
+ /**
22379
+ * diff nodes
22380
+ * @param n1
22381
+ * @param n2
22382
+ * @param reducer
22383
+ * @param options
22384
+ *
22385
+ * @private
22386
+ */
21949
22387
  function diff(n1, n2, reducer, options = {}) {
21950
22388
  if (!('cache' in options)) {
21951
22389
  options.cache = new WeakMap();
@@ -21961,10 +22399,6 @@ function diff(n1, n2, reducer, options = {}) {
21961
22399
  }
21962
22400
  let i = node1.chi.length;
21963
22401
  let j = node2.chi.length;
21964
- // if (i == 0 || j == 0) {
21965
- //
21966
- // return null;
21967
- // }
21968
22402
  const raw1 = node1.raw;
21969
22403
  const raw2 = node2.raw;
21970
22404
  if (raw1 != null && raw2 != null) {
@@ -22035,10 +22469,6 @@ function diff(n1, n2, reducer, options = {}) {
22035
22469
  continue;
22036
22470
  }
22037
22471
  j = node2.chi.length;
22038
- // if (j == 0) {
22039
- //
22040
- // break;
22041
- // }
22042
22472
  while (j--) {
22043
22473
  if (node2.chi[j].typ == exports.EnumToken.CommentNodeType) {
22044
22474
  continue;
@@ -22076,6 +22506,12 @@ function diff(n1, n2, reducer, options = {}) {
22076
22506
  }
22077
22507
  return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node1 : node2 };
22078
22508
  }
22509
+ /**
22510
+ * reduce rule selector
22511
+ * @param node
22512
+ *
22513
+ * @private
22514
+ */
22079
22515
  function reduceRuleSelector(node) {
22080
22516
  if (node.raw == null) {
22081
22517
  Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: splitRule(node.sel) });
@@ -22119,27 +22555,12 @@ function reduceRuleSelector(node) {
22119
22555
  }
22120
22556
 
22121
22557
  /**
22122
- * expand nested css ast
22558
+ * expand css nesting ast nodes
22123
22559
  * @param ast
22560
+ *
22561
+ * @private
22124
22562
  */
22125
22563
  function expand(ast) {
22126
- //
22127
- // if (![EnumToken.RuleNodeType, EnumToken.StyleSheetNodeType, EnumToken.AtRuleNodeType].includes(ast.typ)) {
22128
- //
22129
- // return ast;
22130
- // }
22131
- // if (EnumToken.RuleNodeType == ast.typ) {
22132
- //
22133
- // return <AstRuleStyleSheet>{
22134
- // typ: EnumToken.StyleSheetNodeType,
22135
- // chi: expandRule(<AstRule>ast)
22136
- // }
22137
- // }
22138
- //
22139
- // if (!('chi' in ast)) {
22140
- //
22141
- // return ast;
22142
- // }
22143
22564
  const result = { ...ast, chi: [] };
22144
22565
  // @ts-ignore
22145
22566
  for (let i = 0; i < ast.chi.length; i++) {
@@ -22163,11 +22584,6 @@ function expand(ast) {
22163
22584
  // @ts-ignore
22164
22585
  result.chi.push({ ...(hasRule ? expand(node) : node) });
22165
22586
  }
22166
- // else {
22167
- //
22168
- // // @ts-ignore
22169
- // result.chi.push(node);
22170
- // }
22171
22587
  }
22172
22588
  return result;
22173
22589
  }
@@ -22181,14 +22597,6 @@ function expandRule(node) {
22181
22597
  const rule = ast.chi[i];
22182
22598
  if (!rule.sel.includes('&')) {
22183
22599
  const selRule = splitRule(rule.sel);
22184
- // if (selRule.length > 1) {
22185
- //
22186
- // const r: string = ':is(' + selRule.map(a => a.join('')).join(',') + ')';
22187
- // rule.sel = splitRule(ast.sel).reduce((a: string[], b: string[]): string[] => a.concat([b.join('') + r]), <string[]>[]).join(',');
22188
- //
22189
- // }
22190
- // else {
22191
- // selRule = splitRule(selRule.reduce((acc, curr) => acc + (acc.length > 0 ? ',' : '') + curr.join(''), ''));
22192
22600
  const arSelf = splitRule(ast.sel).filter((r) => r.every((t) => t != ':before' && t != ':after' && !t.startsWith('::'))).reduce((acc, curr) => acc.concat([curr.join('')]), []).join(',');
22193
22601
  if (arSelf.length == 0) {
22194
22602
  ast.chi.splice(i--, 1);
@@ -22226,10 +22634,6 @@ function expandRule(node) {
22226
22634
  if (s == '&' || parentSelector) {
22227
22635
  withCompound.push(s);
22228
22636
  }
22229
- // else {
22230
- //
22231
- // withoutCompound.push(s.slice(1));
22232
- // }
22233
22637
  }
22234
22638
  }
22235
22639
  else {
@@ -22240,10 +22644,6 @@ function expandRule(node) {
22240
22644
  withCompound.push(s);
22241
22645
  }
22242
22646
  }
22243
- // else {
22244
- //
22245
- // withoutCompound.push(s);
22246
- // }
22247
22647
  }
22248
22648
  const selectors = [];
22249
22649
  const selector = rules.length > 1 ? ':is(' + rules.map(a => a.join('')).join(',') + ')' : rules[0].join('');
@@ -22275,13 +22675,6 @@ function expandRule(node) {
22275
22675
  if (withCompound.length == 1) {
22276
22676
  selectors.push(replaceCompound(withCompound[0], selector));
22277
22677
  }
22278
- // else {
22279
- //
22280
- // for (const w of withCompound) {
22281
- //
22282
- // selectors.push(replaceCompound(w, selector));
22283
- // }
22284
- // }
22285
22678
  }
22286
22679
  rule.sel = selectors.reduce((acc, curr) => curr.length == 0 ? acc : acc + (acc.length > 0 ? ',' : '') + curr, '');
22287
22680
  }
@@ -22322,11 +22715,6 @@ function expandRule(node) {
22322
22715
  // @ts-ignore
22323
22716
  astAtRule.chi.push(...expandRule(r));
22324
22717
  }
22325
- // else {
22326
- //
22327
- // // @ts-ignore
22328
- // astAtRule.chi.push(r);
22329
- // }
22330
22718
  }
22331
22719
  }
22332
22720
  // @ts-ignore
@@ -22353,12 +22741,6 @@ function replaceCompound(input, replace) {
22353
22741
  if (replacement == null) {
22354
22742
  replacement = parseString(replace);
22355
22743
  }
22356
- // if (tokens[1].typ == EnumToken.IdenTokenType) {
22357
- //
22358
- //
22359
- // (t.value as LiteralToken).val = (replacement as Token[]).length == 1 || (!replace.includes(' ') && replace.charAt(0).match(/[:.]/)) ? (tokens[1] as IdentToken).val + replace : replaceCompoundLiteral((tokens[1] as IdentToken).val + '&', replace);
22360
- // tokens.splice(1, 1);
22361
- // } else {
22362
22744
  t.value.val = replaceCompoundLiteral(t.value.val, replace);
22363
22745
  // }
22364
22746
  continue;
@@ -22366,10 +22748,6 @@ function replaceCompound(input, replace) {
22366
22748
  const rule = splitRule(replace);
22367
22749
  t.value.val = rule.length > 1 ? ':is(' + replace + ')' : replace;
22368
22750
  }
22369
- // else if ((t.value as LiteralToken).val.length > 1 && (t.value as LiteralToken).val.charAt(0) == '&') {
22370
- //
22371
- // (t.value as LiteralToken).val = replaceCompoundLiteral((t.value as LiteralToken).val, replace);
22372
- // }
22373
22751
  }
22374
22752
  }
22375
22753
  return tokens.reduce((acc, curr) => acc + renderToken(curr), '');
@@ -22382,10 +22760,6 @@ function replaceCompoundLiteral(selector, replace) {
22382
22760
  tokens.push('&');
22383
22761
  tokens.push('');
22384
22762
  }
22385
- // else {
22386
- //
22387
- // tokens[tokens.length - 1] += selector.charAt(i);
22388
- // }
22389
22763
  }
22390
22764
  return tokens.sort((a, b) => {
22391
22765
  if (a == '&') {
@@ -22401,36 +22775,189 @@ function replaceCompoundLiteral(selector, replace) {
22401
22775
  }, '');
22402
22776
  }
22403
22777
 
22404
- function parseResponse(response) {
22405
- if (!response.ok) {
22406
- throw new Error(`${response.status} ${response.statusText} ${response.url}`);
22407
- }
22408
- return response.text();
22409
- }
22410
22778
  /**
22411
- * load file
22779
+ * node module entry point
22780
+ * @module node
22781
+ */
22782
+ /**
22783
+ * load file or url as stream
22412
22784
  * @param url
22413
22785
  * @param currentFile
22786
+ *
22787
+ * @private
22414
22788
  */
22415
- async function load(url, currentFile = '.') {
22789
+ async function getStream(url, currentFile = '.') {
22416
22790
  const resolved = resolve(url, currentFile);
22417
- return matchUrl.test(resolved.absolute) ? fetch(resolved.absolute).then(parseResponse) : promises.readFile(resolved.absolute, { encoding: 'utf-8' });
22791
+ // @ts-ignore
22792
+ return matchUrl.test(resolved.absolute) ? fetch(resolved.absolute).then((response) => {
22793
+ if (!response.ok) {
22794
+ throw new Error(`${response.status} ${response.statusText} ${response.url}`);
22795
+ }
22796
+ return response.body;
22797
+ }) : node_stream.Readable.toWeb(node_fs.createReadStream(resolved.absolute));
22418
22798
  }
22419
-
22420
22799
  /**
22421
- * render ast node
22800
+ * render ast tree
22801
+ * @param data
22802
+ * @param options
22803
+ *
22804
+ * Example:
22805
+ *
22806
+ * ```ts
22807
+ *
22808
+ * import {render, ColorType} from '@tbela99/css-parser';
22809
+ *
22810
+ * // remote file
22811
+ * let result = render(ast);
22812
+ * console.log(result.code);
22813
+ *
22814
+ * // local file
22815
+ * result = await parseFile(ast, {beatify: true, convertColor: ColorType.SRGB});
22816
+ * console.log(result.code);
22817
+ * ```
22422
22818
  */
22423
22819
  function render(data, options = {}) {
22424
- return doRender(data, Object.assign(options, { load, resolve, dirname, cwd: options.cwd ?? process.cwd() }));
22820
+ return doRender(data, Object.assign(options, { getStream, resolve, dirname, cwd: options.cwd ?? process.cwd() }));
22821
+ }
22822
+ /**
22823
+ * parse css file
22824
+ * @param file url or path
22825
+ * @param options
22826
+ *
22827
+ * Example:
22828
+ *
22829
+ * ```ts
22830
+ *
22831
+ * import {parseFile} from '@tbela99/css-parser';
22832
+ *
22833
+ * // remote file
22834
+ * let result = await parseFile('https://docs.deno.com/styles.css');
22835
+ * console.log(result.ast);
22836
+ *
22837
+ * // local file
22838
+ * result = await parseFile('./css/styles.css');
22839
+ * console.log(result.ast);
22840
+ * ```
22841
+ */
22842
+ async function parseFile(file, options = {}) {
22843
+ return getStream(file).then(stream => parse(stream, { src: file, ...options }));
22425
22844
  }
22426
22845
  /**
22427
22846
  * parse css
22847
+ * @param stream
22848
+ * @param opt
22849
+ *
22850
+ * Example:
22851
+ *
22852
+ * ```ts
22853
+ *
22854
+ * import {transform} from '@tbela99/css-parser';
22855
+ *
22856
+ * // css string
22857
+ * let result = await transform(css);
22858
+ * console.log(result.code);
22859
+ * ```
22860
+ *
22861
+ * Example using stream
22862
+ *
22863
+ * ```ts
22864
+ *
22865
+ * import {parse} from '@tbela99/css-parser';
22866
+ * import {Readable} from "node:stream";
22867
+ *
22868
+ * // usage: node index.ts < styles.css or cat styles.css | node index.ts
22869
+ *
22870
+ * const readableStream = Readable.toWeb(process.stdin);
22871
+ * const result = await parse(readableStream, {beautify: true});
22872
+ *
22873
+ * console.log(result.ast);
22874
+ * ```
22875
+ *
22876
+ * Example using fetch
22877
+ *
22878
+ * ```ts
22879
+ *
22880
+ * import {parse} from '@tbela99/css-parser';
22881
+ *
22882
+ * const response = await fetch('https://docs.deno.com/styles.css');
22883
+ * result = await parse(response.body, {beautify: true});
22884
+ *
22885
+ * console.log(result.ast);
22886
+ * ```
22887
+ */
22888
+ async function parse(stream, opt = {}) {
22889
+ return doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize$1({
22890
+ stream,
22891
+ buffer: '',
22892
+ position: { ind: 0, lin: 1, col: 1 },
22893
+ currentPosition: { ind: -1, lin: 1, col: 0 }
22894
+ }), Object.assign(opt, { getStream, resolve, dirname, cwd: opt.cwd ?? process.cwd() }));
22895
+ }
22896
+ /**
22897
+ * transform css file
22898
+ * @param file url or path
22899
+ * @param options
22900
+ *
22901
+ * Example:
22902
+ *
22903
+ * ```ts
22904
+ *
22905
+ * import {transformFile} from '@tbela99/css-parser';
22906
+ *
22907
+ * // remote file
22908
+ * let result = await transformFile('https://docs.deno.com/styles.css');
22909
+ * console.log(result.code);
22910
+ *
22911
+ * // local file
22912
+ * result = await transformFile('./css/styles.css');
22913
+ * console.log(result.code);
22914
+ * ```
22428
22915
  */
22429
- async function parse(iterator, opt = {}) {
22430
- return doParse(iterator, Object.assign(opt, { load, resolve, dirname, cwd: opt.cwd ?? process.cwd() }));
22916
+ async function transformFile(file, options = {}) {
22917
+ return getStream(file).then(stream => transform(stream, { src: file, ...options }));
22431
22918
  }
22432
22919
  /**
22433
- * parse and render css
22920
+ * transform css
22921
+ * @param css
22922
+ * @param options
22923
+ *
22924
+ * Example:
22925
+ *
22926
+ * ```ts
22927
+ *
22928
+ * import {transform} from '@tbela99/css-parser';
22929
+ *
22930
+ * // css string
22931
+ * let result = await transform(css);
22932
+ * console.log(result.code);
22933
+ * ```
22934
+ *
22935
+ * Example using stream
22936
+ *
22937
+ * ```ts
22938
+ *
22939
+ * import {transform} from '@tbela99/css-parser';
22940
+ * import {Readable} from "node:stream";
22941
+ *
22942
+ * // usage: node index.ts < styles.css or cat styles.css | node index.ts
22943
+ *
22944
+ * const readableStream = Readable.toWeb(process.stdin);
22945
+ * const result = await transform(readableStream, {beautify: true});
22946
+ *
22947
+ * console.log(result.code);
22948
+ * ```
22949
+ *
22950
+ * Example using fetch
22951
+ *
22952
+ * ```ts
22953
+ *
22954
+ * import {transform} from '@tbela99/css-parser';
22955
+ *
22956
+ * const response = await fetch('https://docs.deno.com/styles.css');
22957
+ * result = await transform(response.body, {beautify: true});
22958
+ *
22959
+ * console.log(result.code);
22960
+ * ```
22434
22961
  */
22435
22962
  async function transform(css, options = {}) {
22436
22963
  options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
@@ -22451,19 +22978,23 @@ async function transform(css, options = {}) {
22451
22978
  });
22452
22979
  }
22453
22980
 
22981
+ exports.SourceMap = SourceMap;
22454
22982
  exports.convertColor = convertColor;
22455
22983
  exports.dirname = dirname;
22456
22984
  exports.expand = expand;
22985
+ exports.getStream = getStream;
22457
22986
  exports.isOkLabClose = isOkLabClose;
22458
- exports.load = load;
22459
22987
  exports.minify = minify;
22460
22988
  exports.okLabDistance = okLabDistance;
22461
22989
  exports.parse = parse;
22990
+ exports.parseDeclarations = parseDeclarations;
22991
+ exports.parseFile = parseFile;
22462
22992
  exports.parseString = parseString;
22463
22993
  exports.parseTokens = parseTokens;
22464
22994
  exports.render = render;
22465
22995
  exports.renderToken = renderToken;
22466
22996
  exports.resolve = resolve;
22467
22997
  exports.transform = transform;
22998
+ exports.transformFile = transformFile;
22468
22999
  exports.walk = walk;
22469
23000
  exports.walkValues = walkValues;