@tbela99/css-parser 1.3.2 → 1.3.3

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.
@@ -1,4 +1,4 @@
1
- import { parseString } from '../parser/parse.js';
1
+ import { replaceToken, parseString } from '../parser/parse.js';
2
2
  import '../parser/tokenize.js';
3
3
  import '../parser/utils/config.js';
4
4
  import { EnumToken } from './types.js';
@@ -29,6 +29,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
29
29
  let preprocess = false;
30
30
  let postprocess = false;
31
31
  let parents;
32
+ let replacement;
32
33
  if (!('features' in options)) {
33
34
  // @ts-ignore
34
35
  options = {
@@ -38,82 +39,92 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
38
39
  removePrefix: false,
39
40
  features: [], ...options
40
41
  };
41
- // @ts-ignore
42
42
  for (const feature of features) {
43
43
  feature.register(options);
44
44
  }
45
45
  options.features.sort((a, b) => a.ordering - b.ordering);
46
46
  }
47
47
  for (const feature of options.features) {
48
- if (feature.preProcess) {
48
+ if (feature.processMode & FeatureWalkMode.Pre) {
49
49
  preprocess = true;
50
50
  }
51
- if (feature.postProcess) {
51
+ if (feature.processMode & FeatureWalkMode.Post) {
52
52
  postprocess = true;
53
53
  }
54
54
  }
55
55
  if (preprocess) {
56
- parents = [ast];
56
+ parents = new Set([ast]);
57
57
  for (const parent of parents) {
58
58
  if (parent.typ == EnumToken.CommentTokenType ||
59
59
  parent.typ == EnumToken.CDOCOMMTokenType) {
60
- Object.defineProperty(parent, 'parent', {
61
- ...definedPropertySettings,
62
- value: parent
63
- });
64
60
  continue;
65
61
  }
62
+ replacement = parent;
66
63
  for (const feature of options.features) {
67
- if (!feature.preProcess) {
64
+ if ((feature.processMode & FeatureWalkMode.Pre) === 0) {
68
65
  continue;
69
66
  }
70
- feature.run(parent, options, parent.parent ?? ast, context, FeatureWalkMode.Pre);
67
+ const result = feature.run(replacement, options, parent.parent ?? ast, context, FeatureWalkMode.Pre);
68
+ if (result != null) {
69
+ replacement = result;
70
+ }
71
+ }
72
+ if (replacement != parent && parent.parent != null) {
73
+ // @ts-ignore
74
+ replaceToken(parent.parent, parent, replacement);
71
75
  }
72
- if (('chi' in parent)) {
76
+ if (('chi' in replacement)) {
73
77
  // @ts-ignore
74
- for (const node of parent.chi) {
75
- parents.push(Object.defineProperty(node, 'parent', {
78
+ for (const node of replacement.chi) {
79
+ parents.add(Object.defineProperty(node, 'parent', {
76
80
  ...definedPropertySettings,
77
- value: parent
81
+ value: replacement
78
82
  }));
79
83
  }
80
84
  }
81
85
  }
82
86
  for (const feature of options.features) {
83
- if (feature.preProcess && 'cleanup' in feature) {
87
+ if ((feature.processMode & FeatureWalkMode.Pre) && 'cleanup' in feature) {
84
88
  // @ts-ignore
85
89
  feature.cleanup(ast, options, context, FeatureWalkMode.Pre);
86
90
  }
87
91
  }
88
92
  }
89
93
  doMinify(ast, options, recursive, errors, nestingContent, context);
90
- parents = [ast];
94
+ parents = new Set([ast]);
91
95
  for (const parent of parents) {
92
96
  if (parent.typ == EnumToken.CommentTokenType ||
93
97
  parent.typ == EnumToken.CDOCOMMTokenType) {
94
98
  continue;
95
99
  }
100
+ replacement = parent;
96
101
  if (postprocess) {
97
102
  for (const feature of options.features) {
98
- if (!feature.postProcess) {
103
+ if ((feature.processMode & FeatureWalkMode.Post) === 0) {
99
104
  continue;
100
105
  }
101
- feature.run(parent, options, parent.parent ?? ast, context, FeatureWalkMode.Post);
106
+ const result = feature.run(replacement, options, parent.parent ?? ast, context, FeatureWalkMode.Post);
107
+ if (result != null) {
108
+ replacement = result;
109
+ }
102
110
  }
103
111
  }
104
- if (('chi' in parent)) {
112
+ if (replacement != null && replacement != parent && parent.parent != null) {
105
113
  // @ts-ignore
106
- for (const node of parent.chi) {
107
- parents.push(Object.defineProperty(node, 'parent', {
114
+ replaceToken(parent.parent, parent, replacement);
115
+ }
116
+ if (('chi' in replacement)) {
117
+ for (const node of replacement.chi) {
118
+ parents.add(Object.defineProperty(node, 'parent', {
108
119
  ...definedPropertySettings,
109
- value: parent
120
+ value: replacement
110
121
  }));
111
122
  }
112
123
  }
113
124
  }
114
125
  if (postprocess) {
115
126
  for (const feature of options.features) {
116
- if (feature.postProcess && 'cleanup' in feature) {
127
+ if (feature.processMode & FeatureWalkMode.Post && 'cleanup' in feature) {
117
128
  // @ts-ignore
118
129
  feature.cleanup(ast, options, context, FeatureWalkMode.Post);
119
130
  }
@@ -125,12 +136,10 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
125
136
  * reduce selectors
126
137
  * @param acc
127
138
  * @param curr
128
- * @param index
129
- * @param array
130
139
  *
131
140
  * @private
132
141
  */
133
- function reduce(acc, curr, index, array) {
142
+ function reduce(acc, curr) {
134
143
  // trim :is()
135
144
  // if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
136
145
  //
@@ -171,21 +180,18 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
171
180
  }
172
181
  let i = 0;
173
182
  let previous = null;
174
- let node;
183
+ let node = null;
175
184
  let nodeIndex = -1;
176
- // @ts-ignore
177
185
  for (; i < ast.chi.length; i++) {
178
- // @ts-ignore
179
186
  if (ast.chi[i].typ == EnumToken.CommentNodeType) {
180
187
  continue;
181
188
  }
182
- // @ts-ignore
183
189
  node = ast.chi[i];
184
190
  if (node.typ == EnumToken.AtRuleNodeType && node.nam == 'font-face') {
185
191
  continue;
186
192
  }
187
- if (node.typ == EnumToken.KeyframeAtRuleNodeType) {
188
- if (previous?.typ == EnumToken.KeyframeAtRuleNodeType &&
193
+ if (node.typ == EnumToken.KeyframesAtRuleNodeType) {
194
+ if (previous?.typ == EnumToken.KeyframesAtRuleNodeType &&
189
195
  node.nam == previous.nam &&
190
196
  node.val == previous.val) {
191
197
  ast.chi?.splice(nodeIndex--, 1);
@@ -193,15 +199,11 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
193
199
  i = nodeIndex;
194
200
  continue;
195
201
  }
196
- if (node.chi.length > 0) {
197
- doMinify(node, options, true, errors, nestingContent, context);
198
- }
199
202
  }
200
- else if (node.typ == EnumToken.KeyFrameRuleNodeType) {
201
- if (previous?.typ == EnumToken.KeyFrameRuleNodeType &&
203
+ else if (node.typ == EnumToken.KeyFramesRuleNodeType) {
204
+ if (previous?.typ == EnumToken.KeyFramesRuleNodeType &&
202
205
  node.sel == previous.sel) {
203
206
  previous.chi.push(...node.chi);
204
- // @ts-ignore
205
207
  ast.chi.splice(i--, 1);
206
208
  continue;
207
209
  }
@@ -223,25 +225,25 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
223
225
  }
224
226
  }
225
227
  else if (node.typ == EnumToken.AtRuleNodeType) {
226
- // @ts-ignore
227
228
  if (node.nam == 'media' && ['all', '', null].includes(node.val)) {
228
- // @ts-ignore
229
229
  ast.chi?.splice(i, 1, ...node.chi);
230
230
  i--;
231
231
  continue;
232
232
  }
233
- // @ts-ignore
234
233
  if (previous?.typ == EnumToken.AtRuleNodeType &&
235
234
  previous.nam == node.nam &&
236
235
  previous.val == node.val) {
237
236
  if ('chi' in node) {
238
237
  // @ts-ignore
239
238
  previous.chi.push(...node.chi);
239
+ if (!hasDeclaration(previous)) {
240
+ context.nodes.delete(previous);
241
+ doMinify(previous, options, recursive, errors, nestingContent, context);
242
+ }
240
243
  }
241
244
  ast?.chi?.splice(i--, 1);
242
245
  continue;
243
246
  }
244
- // @ts-ignore
245
247
  if (!hasDeclaration(node)) {
246
248
  doMinify(node, options, recursive, errors, nestingContent, context);
247
249
  }
@@ -252,47 +254,33 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
252
254
  // @ts-ignore
253
255
  else if (node.typ == EnumToken.RuleNodeType) {
254
256
  reduceRuleSelector(node);
255
- let wrapper;
257
+ let wrapper = null;
256
258
  let match;
257
- // @ts-ignore
258
259
  if (options.nestingRules) {
259
- // @ts-ignore
260
260
  if (previous?.typ == EnumToken.RuleNodeType) {
261
- // @ts-ignore
262
261
  reduceRuleSelector(previous);
263
262
  // @ts-ignore
264
263
  match = matchSelectors(previous.raw, node.raw, ast.typ);
265
- // @ts-ignore
266
264
  if (match != null) {
267
- // @ts-ignore
268
265
  wrapper = wrapNodes(previous, node, match, ast, reducer, i, nodeIndex);
269
266
  nodeIndex = i - 1;
270
- // @ts-ignore
271
267
  previous = ast.chi[nodeIndex];
272
268
  }
273
269
  }
274
- // @ts-ignore
275
270
  if (wrapper != null) {
276
- // @ts-ignore
277
271
  while (i < ast.chi.length) {
278
- // @ts-ignore
279
272
  const nextNode = ast.chi[i];
280
- // @ts-ignore
281
273
  if (nextNode.typ != EnumToken.RuleNodeType) {
282
274
  break;
283
275
  }
284
276
  reduceRuleSelector(nextNode);
285
- // @ts-ignore
286
- match = matchSelectors(wrapper.raw, nextNode.raw, ast.typ);
287
- // @ts-ignore
277
+ match = matchSelectors(wrapper.raw, nextNode.raw);
288
278
  if (match == null) {
289
279
  break;
290
280
  }
291
- // @ts-ignore
292
281
  wrapper = wrapNodes(wrapper, nextNode, match, ast, reducer, i, nodeIndex);
293
282
  }
294
283
  nodeIndex = --i;
295
- // @ts-ignore
296
284
  previous = ast.chi[nodeIndex];
297
285
  doMinify(wrapper, options, recursive, errors, nestingContent, context);
298
286
  continue;
@@ -339,7 +327,6 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
339
327
  curr.unshift('&');
340
328
  wrap = false;
341
329
  }
342
- // @ts-ignore
343
330
  acc.push(curr);
344
331
  return acc;
345
332
  }, []);
@@ -365,82 +352,65 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
365
352
  }
366
353
  }
367
354
  if (rule == null) {
368
- rule = selector.map(s => {
355
+ rule = selector.map((s) => {
369
356
  if (s[0] == '&') {
370
357
  s.splice(0, 1, ...node.optimized.optimized);
371
358
  }
372
359
  return s.join('');
373
360
  }).join(',');
374
361
  }
375
- // @ts-ignore
376
362
  let sel = wrap ? node.optimized.optimized.join('') + `:is(${rule})` : rule;
377
363
  if (sel.length < node.sel.length) {
378
364
  node.sel = sel;
379
365
  }
380
366
  }
367
+ doMinify(node, options, recursive, errors, nestingContent, context);
381
368
  }
382
- // @ts-ignore
383
369
  if (previous != null) {
384
- // @ts-ignore
385
370
  if ('chi' in previous && ('chi' in node)) {
386
- // @ts-ignore
387
371
  if (previous.typ == node.typ) {
388
372
  let shouldMerge = true;
389
- // @ts-ignore
390
373
  let k = previous.chi.length;
391
374
  while (k-- > 0) {
392
- // @ts-ignore
393
375
  if (previous.chi[k].typ == EnumToken.CommentNodeType) {
394
376
  continue;
395
377
  }
396
- // @ts-ignore
397
378
  shouldMerge = previous.chi[k].typ == EnumToken.DeclarationNodeType;
398
379
  break;
399
380
  }
400
381
  if (shouldMerge) {
401
- // @ts-ignore
402
- if (((node.typ == EnumToken.RuleNodeType || node.typ == EnumToken.KeyFrameRuleNodeType) && node.sel == previous.sel) ||
403
- // @ts-ignore
382
+ if (((node.typ == EnumToken.RuleNodeType || node.typ == EnumToken.KeyFramesRuleNodeType) && node.sel == previous.sel) ||
404
383
  (node.typ == EnumToken.AtRuleNodeType) && node.val != 'font-face' && node.val == previous.val) {
405
384
  // @ts-ignore
406
385
  node.chi.unshift(...previous.chi);
407
- // @ts-ignore
386
+ doMinify(node, options, recursive, errors, nestingContent, context);
408
387
  ast.chi.splice(nodeIndex, 1);
409
- i--;
410
- previous = node;
388
+ previous = ast.chi[--i];
411
389
  nodeIndex = i;
412
390
  continue;
413
391
  }
414
- else if (node.typ == previous?.typ && [EnumToken.KeyFrameRuleNodeType, EnumToken.RuleNodeType].includes(node.typ)) {
392
+ else if (node.typ == previous?.typ && [EnumToken.KeyFramesRuleNodeType, EnumToken.RuleNodeType].includes(node.typ)) {
415
393
  const intersect = diff(previous, node, reducer, options);
416
394
  if (intersect != null) {
417
395
  if (intersect.node1.chi.length == 0) {
418
- // @ts-ignore
419
396
  ast.chi.splice(i--, 1);
420
397
  }
421
398
  else {
422
- // @ts-ignore
423
399
  ast.chi.splice(i--, 1, intersect.node1);
424
400
  }
425
401
  if (intersect.node2.chi.length == 0) {
426
- // @ts-ignore
427
402
  ast.chi.splice(nodeIndex, 1, intersect.result);
428
403
  i--;
429
- // @ts-ignore
430
404
  if (nodeIndex == i) {
431
405
  nodeIndex = i;
432
406
  }
433
407
  }
434
408
  else {
435
- // @ts-ignore
436
409
  ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
437
- // @ts-ignore
438
410
  i = (nodeIndex ?? 0) + 1;
439
411
  }
440
412
  reduceRuleSelector(intersect.result);
441
- // @ts-ignore
442
413
  if (node != ast.chi[i]) {
443
- // @ts-ignore
444
414
  node = ast.chi[i];
445
415
  }
446
416
  previous = intersect.result;
@@ -449,9 +419,7 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
449
419
  }
450
420
  }
451
421
  }
452
- // @ts-ignore
453
422
  if (recursive && previous != node) {
454
- // @ts-ignore
455
423
  if (!hasDeclaration(previous)) {
456
424
  doMinify(previous, options, recursive, errors, nestingContent, context);
457
425
  }
@@ -459,9 +427,7 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
459
427
  }
460
428
  }
461
429
  if (!nestingContent &&
462
- // @ts-ignore
463
430
  previous != null &&
464
- // previous.optimized != null &&
465
431
  previous.typ == EnumToken.RuleNodeType &&
466
432
  previous.sel.includes('&')) {
467
433
  fixSelector(previous);
@@ -469,20 +435,15 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
469
435
  previous = node;
470
436
  nodeIndex = i;
471
437
  }
472
- // @ts-ignore
473
438
  if (recursive && node != null && ('chi' in node)) {
474
- // @ts-ignore
475
- if (node.typ == EnumToken.KeyframeAtRuleNodeType || !node.chi.some(n => n.typ == EnumToken.DeclarationNodeType)) {
476
- // @ts-ignore
439
+ if (node.typ == EnumToken.KeyframesAtRuleNodeType || !node.chi.some(n => n.typ == EnumToken.DeclarationNodeType)) {
477
440
  if (!(node.typ == EnumToken.AtRuleNodeType && node.nam != 'font-face')) {
478
441
  doMinify(node, options, recursive, errors, nestingContent, context);
479
442
  }
480
443
  }
481
444
  }
482
445
  if (!nestingContent &&
483
- // @ts-ignore
484
446
  node != null &&
485
- // previous.optimized != null &&
486
447
  node.typ == EnumToken.RuleNodeType &&
487
448
  node.sel.includes('&')) {
488
449
  fixSelector(node);
@@ -633,7 +594,6 @@ function splitRule(buffer) {
633
594
  }
634
595
  if (chr == ',') {
635
596
  if (str !== '') {
636
- // @ts-ignore
637
597
  result.at(-1).push(str);
638
598
  str = '';
639
599
  }
@@ -642,7 +602,6 @@ function splitRule(buffer) {
642
602
  }
643
603
  if (chr == '.') {
644
604
  if (str !== '') {
645
- // @ts-ignore
646
605
  result.at(-1).push(str);
647
606
  str = '';
648
607
  }
@@ -651,20 +610,17 @@ function splitRule(buffer) {
651
610
  }
652
611
  if (combinators.includes(chr)) {
653
612
  if (str !== '') {
654
- // @ts-ignore
655
613
  result.at(-1).push(str);
656
614
  str = '';
657
615
  }
658
616
  if (chr == '|' && buffer.charAt(i + 1) == '|') {
659
617
  chr += buffer.charAt(++i);
660
618
  }
661
- // @ts-ignore
662
619
  result.at(-1).push(chr);
663
620
  continue;
664
621
  }
665
622
  if (chr == ':') {
666
623
  if (str !== '') {
667
- // @ts-ignore
668
624
  result.at(-1).push(str);
669
625
  str = '';
670
626
  }
@@ -706,7 +662,6 @@ function splitRule(buffer) {
706
662
  }
707
663
  }
708
664
  if (str !== '') {
709
- // @ts-ignore
710
665
  result.at(-1).push(str);
711
666
  }
712
667
  return result;
@@ -771,7 +726,7 @@ function reduceSelector(acc, curr) {
771
726
  *
772
727
  * @private
773
728
  */
774
- function matchSelectors(selector1, selector2 /*, parentType: EnumToken, errors: ErrorDescription[] */) {
729
+ function matchSelectors(selector1, selector2) {
775
730
  let match = [[]];
776
731
  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));
777
732
  let i = 0;
@@ -846,7 +801,6 @@ function matchSelectors(selector1, selector2 /*, parentType: EnumToken, errors:
846
801
  * @private
847
802
  */
848
803
  function fixSelector(node) {
849
- // @ts-ignore
850
804
  if (node.sel.includes('&')) {
851
805
  const attributes = parseString(node.sel);
852
806
  for (const attr of walkValues(attributes)) {
@@ -881,40 +835,27 @@ function wrapNodes(previous, node, match, ast, reducer, i, nodeIndex) {
881
835
  let nSel = match.selector2.reduce(reducer, []).join(',');
882
836
  // @ts-ignore
883
837
  const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
884
- // @ts-ignore
885
838
  Object.defineProperty(wrapper, 'raw', {
886
839
  ...definedPropertySettings,
887
- // @ts-ignore
888
840
  value: match.match.map(t => t.slice())
889
841
  });
890
842
  if (pSel == '&' || pSel === '') {
891
- // @ts-ignore
892
843
  wrapper.chi.push(...previous.chi);
893
- // @ts-ignore
894
844
  if ((nSel == '&' || nSel === '')) {
895
- // @ts-ignore
896
845
  wrapper.chi.push(...node.chi);
897
846
  }
898
847
  else {
899
- // @ts-ignore
900
848
  wrapper.chi.push(node);
901
849
  }
902
850
  }
903
851
  else {
904
- // @ts-ignore
905
852
  wrapper.chi.push(previous, node);
906
853
  }
907
- // @ts-ignore
908
854
  ast.chi.splice(i, 1, wrapper);
909
- // @ts-ignore
910
855
  ast.chi.splice(nodeIndex, 1);
911
- // @ts-ignore
912
856
  previous.sel = pSel;
913
- // @ts-ignore
914
857
  previous.raw = match.selector1;
915
- // @ts-ignore
916
858
  node.sel = nSel;
917
- // @ts-ignore
918
859
  node.raw = match.selector2;
919
860
  reduceRuleSelector(wrapper);
920
861
  return wrapper;
@@ -330,7 +330,7 @@ var EnumToken;
330
330
  /**
331
331
  * keyframe rule node type
332
332
  */
333
- EnumToken[EnumToken["KeyFrameRuleNodeType"] = 73] = "KeyFrameRuleNodeType";
333
+ EnumToken[EnumToken["KeyFramesRuleNodeType"] = 73] = "KeyFramesRuleNodeType";
334
334
  /**
335
335
  * class selector token type
336
336
  */
@@ -410,7 +410,7 @@ var EnumToken;
410
410
  /**
411
411
  * keyframe at rule node type
412
412
  */
413
- EnumToken[EnumToken["KeyframeAtRuleNodeType"] = 93] = "KeyframeAtRuleNodeType";
413
+ EnumToken[EnumToken["KeyframesAtRuleNodeType"] = 93] = "KeyframesAtRuleNodeType";
414
414
  /**
415
415
  * invalid declaration node type
416
416
  */