@tbela99/css-parser 0.9.1 → 1.1.0

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.
Files changed (99) hide show
  1. package/CHANGELOG.md +265 -0
  2. package/LICENSE.md +1 -1
  3. package/README.md +29 -17
  4. package/dist/index-umd-web.js +7461 -4360
  5. package/dist/index.cjs +8608 -5507
  6. package/dist/index.d.ts +203 -61
  7. package/dist/lib/ast/expand.js +2 -1
  8. package/dist/lib/ast/features/calc.js +19 -11
  9. package/dist/lib/ast/features/index.js +1 -0
  10. package/dist/lib/ast/features/inlinecssvariables.js +47 -29
  11. package/dist/lib/ast/features/prefix.js +117 -91
  12. package/dist/lib/ast/features/shorthand.js +34 -14
  13. package/dist/lib/ast/features/transform.js +67 -0
  14. package/dist/lib/ast/features/type.js +7 -0
  15. package/dist/lib/ast/math/expression.js +20 -10
  16. package/dist/lib/ast/math/math.js +20 -2
  17. package/dist/lib/ast/minify.js +209 -80
  18. package/dist/lib/ast/transform/compute.js +337 -0
  19. package/dist/lib/ast/transform/convert.js +33 -0
  20. package/dist/lib/ast/transform/matrix.js +112 -0
  21. package/dist/lib/ast/transform/minify.js +296 -0
  22. package/dist/lib/ast/transform/perspective.js +10 -0
  23. package/dist/lib/ast/transform/rotate.js +40 -0
  24. package/dist/lib/ast/transform/scale.js +32 -0
  25. package/dist/lib/ast/transform/skew.js +23 -0
  26. package/dist/lib/ast/transform/translate.js +32 -0
  27. package/dist/lib/ast/transform/utils.js +198 -0
  28. package/dist/lib/ast/types.js +18 -15
  29. package/dist/lib/ast/walk.js +54 -22
  30. package/dist/lib/fs/resolve.js +10 -0
  31. package/dist/lib/parser/declaration/list.js +48 -45
  32. package/dist/lib/parser/declaration/map.js +1 -0
  33. package/dist/lib/parser/declaration/set.js +2 -1
  34. package/dist/lib/parser/parse.js +449 -340
  35. package/dist/lib/parser/tokenize.js +147 -72
  36. package/dist/lib/parser/utils/declaration.js +5 -4
  37. package/dist/lib/parser/utils/type.js +2 -1
  38. package/dist/lib/renderer/color/a98rgb.js +2 -1
  39. package/dist/lib/renderer/color/{colormix.js → color-mix.js} +16 -7
  40. package/dist/lib/renderer/color/color.js +264 -170
  41. package/dist/lib/renderer/color/hex.js +19 -8
  42. package/dist/lib/renderer/color/hsl.js +9 -3
  43. package/dist/lib/renderer/color/hwb.js +2 -1
  44. package/dist/lib/renderer/color/lab.js +10 -1
  45. package/dist/lib/renderer/color/lch.js +10 -1
  46. package/dist/lib/renderer/color/oklab.js +10 -1
  47. package/dist/lib/renderer/color/oklch.js +10 -1
  48. package/dist/lib/renderer/color/p3.js +2 -1
  49. package/dist/lib/renderer/color/rec2020.js +2 -1
  50. package/dist/lib/renderer/color/relativecolor.js +27 -32
  51. package/dist/lib/renderer/color/rgb.js +14 -10
  52. package/dist/lib/renderer/color/srgb.js +48 -23
  53. package/dist/lib/renderer/color/utils/components.js +18 -6
  54. package/dist/lib/renderer/color/utils/constants.js +47 -3
  55. package/dist/lib/renderer/color/xyz.js +2 -1
  56. package/dist/lib/renderer/color/xyzd50.js +2 -1
  57. package/dist/lib/renderer/render.js +108 -43
  58. package/dist/lib/syntax/syntax.js +267 -136
  59. package/dist/lib/validation/at-rules/container.js +81 -103
  60. package/dist/lib/validation/at-rules/counter-style.js +9 -8
  61. package/dist/lib/validation/at-rules/custom-media.js +13 -15
  62. package/dist/lib/validation/at-rules/document.js +22 -27
  63. package/dist/lib/validation/at-rules/font-feature-values.js +8 -8
  64. package/dist/lib/validation/at-rules/import.js +30 -81
  65. package/dist/lib/validation/at-rules/keyframes.js +19 -23
  66. package/dist/lib/validation/at-rules/layer.js +5 -5
  67. package/dist/lib/validation/at-rules/media.js +42 -53
  68. package/dist/lib/validation/at-rules/namespace.js +19 -23
  69. package/dist/lib/validation/at-rules/page-margin-box.js +15 -18
  70. package/dist/lib/validation/at-rules/page.js +8 -7
  71. package/dist/lib/validation/at-rules/supports.js +73 -82
  72. package/dist/lib/validation/at-rules/when.js +32 -36
  73. package/dist/lib/validation/atrule.js +15 -18
  74. package/dist/lib/validation/config.js +24 -1
  75. package/dist/lib/validation/config.json.js +563 -63
  76. package/dist/lib/validation/parser/parse.js +196 -185
  77. package/dist/lib/validation/parser/types.js +1 -1
  78. package/dist/lib/validation/selector.js +8 -5
  79. package/dist/lib/validation/syntax.js +724 -1405
  80. package/dist/lib/validation/syntaxes/complex-selector-list.js +10 -11
  81. package/dist/lib/validation/syntaxes/complex-selector.js +10 -11
  82. package/dist/lib/validation/syntaxes/compound-selector.js +40 -50
  83. package/dist/lib/validation/syntaxes/family-name.js +9 -8
  84. package/dist/lib/validation/syntaxes/keyframe-block-list.js +6 -5
  85. package/dist/lib/validation/syntaxes/keyframe-selector.js +23 -105
  86. package/dist/lib/validation/syntaxes/layer-name.js +6 -5
  87. package/dist/lib/validation/syntaxes/relative-selector-list.js +7 -6
  88. package/dist/lib/validation/syntaxes/relative-selector.js +17 -15
  89. package/dist/lib/validation/syntaxes/url.js +18 -22
  90. package/dist/lib/validation/utils/list.js +20 -2
  91. package/dist/lib/validation/utils/whitespace.js +2 -1
  92. package/dist/node/index.js +4 -2
  93. package/dist/node/load.js +6 -1
  94. package/dist/web/index.js +4 -2
  95. package/dist/web/load.js +5 -0
  96. package/package.json +16 -15
  97. package/dist/lib/renderer/color/prophotoRgb.js +0 -56
  98. package/dist/lib/validation/declaration.js +0 -94
  99. package/dist/lib/validation/syntaxes/image.js +0 -29
@@ -1,12 +1,15 @@
1
1
  import { parseString } from '../parser/parse.js';
2
+ import '../parser/tokenize.js';
3
+ import '../parser/utils/config.js';
2
4
  import { EnumToken } from './types.js';
3
5
  import { walkValues } from './walk.js';
4
6
  import { replaceCompound } from './expand.js';
5
- import { isIdent, isFunction, isWhiteSpace, isIdentStart } from '../syntax/syntax.js';
6
- import '../parser/utils/config.js';
7
+ import { isWhiteSpace, isIdent, isFunction, isIdentStart } from '../syntax/syntax.js';
7
8
  import { eq } from '../parser/utils/eq.js';
8
9
  import { doRender, renderToken } from '../renderer/render.js';
10
+ import '../renderer/color/utils/constants.js';
9
11
  import * as index from './features/index.js';
12
+ import { FeatureWalkMode } from './features/type.js';
10
13
 
11
14
  const combinators = ['+', '>', '~', '||', '|'];
12
15
  const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
@@ -23,13 +26,9 @@ const features = Object.values(index).sort((a, b) => a.ordering - b.ordering);
23
26
  * @param context
24
27
  */
25
28
  function minify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
26
- if (!('nodes' in context)) {
27
- context.nodes = new Set;
28
- }
29
- if (context.nodes.has(ast)) {
30
- return ast;
31
- }
32
- context.nodes.add(ast);
29
+ let preprocess = false;
30
+ let postprocess = false;
31
+ let parents;
33
32
  if (!('features' in options)) {
34
33
  // @ts-ignore
35
34
  options = {
@@ -43,35 +42,125 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
43
42
  for (const feature of features) {
44
43
  feature.register(options);
45
44
  }
45
+ options.features.sort((a, b) => a.ordering - b.ordering);
46
+ }
47
+ for (const feature of options.features) {
48
+ if (feature.preProcess) {
49
+ preprocess = true;
50
+ }
51
+ if (feature.postProcess) {
52
+ postprocess = true;
53
+ }
46
54
  }
47
- function reducer(acc, curr, index, array) {
48
- // trim :is()
49
- if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
50
- curr = curr.slice(1, -1);
55
+ if (preprocess) {
56
+ parents = [ast];
57
+ for (const parent of parents) {
58
+ if (parent.typ == EnumToken.CommentTokenType ||
59
+ parent.typ == EnumToken.CDOCOMMTokenType) {
60
+ Object.defineProperty(parent, 'parent', {
61
+ ...definedPropertySettings,
62
+ value: parent
63
+ });
64
+ continue;
65
+ }
66
+ for (const feature of options.features) {
67
+ if (!feature.preProcess) {
68
+ continue;
69
+ }
70
+ feature.run(parent, options, parent.parent ?? ast, context, FeatureWalkMode.Pre);
71
+ }
72
+ if (('chi' in parent)) {
73
+ // @ts-ignore
74
+ for (const node of parent.chi) {
75
+ parents.push(Object.defineProperty(node, 'parent', {
76
+ ...definedPropertySettings,
77
+ value: parent
78
+ }));
79
+ }
80
+ }
51
81
  }
52
- if (curr[0] == '&') {
53
- if (curr[1] == ' ' && !isIdent(curr[2]) && !isFunction(curr[2])) {
54
- curr.splice(0, 2);
82
+ for (const feature of options.features) {
83
+ if (feature.preProcess && 'cleanup' in feature) {
84
+ // @ts-ignore
85
+ feature.cleanup(ast, options, context, FeatureWalkMode.Pre);
55
86
  }
56
- else if (combinators.includes(curr[1])) {
57
- curr.shift();
87
+ }
88
+ }
89
+ doMinify(ast, options, recursive, errors, nestingContent, context);
90
+ parents = [ast];
91
+ for (const parent of parents) {
92
+ // parent = parents.shift() as AstNode;
93
+ if (parent.typ == EnumToken.CommentTokenType ||
94
+ parent.typ == EnumToken.CDOCOMMTokenType) {
95
+ continue;
96
+ }
97
+ if (postprocess) {
98
+ for (const feature of options.features) {
99
+ if (!feature.postProcess) {
100
+ continue;
101
+ }
102
+ feature.run(parent, options, parent.parent ?? ast, context, FeatureWalkMode.Post);
58
103
  }
59
104
  }
60
- else if (ast.typ == EnumToken.RuleNodeType && (isIdent(curr[0]) || isFunction(curr[0]))) {
105
+ if (('chi' in parent)) {
106
+ // @ts-ignore
107
+ for (const node of parent.chi) {
108
+ parents.push(Object.defineProperty(node, 'parent', {
109
+ ...definedPropertySettings,
110
+ value: parent
111
+ }));
112
+ }
113
+ }
114
+ }
115
+ if (postprocess) {
116
+ for (const feature of options.features) {
117
+ if (feature.postProcess && 'cleanup' in feature) {
118
+ // @ts-ignore
119
+ feature.cleanup(ast, options, context, FeatureWalkMode.Post);
120
+ }
121
+ }
122
+ }
123
+ return ast;
124
+ }
125
+ function reduce(acc, curr, index, array) {
126
+ // trim :is()
127
+ if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
128
+ curr = curr.slice(1, -1);
129
+ }
130
+ if (curr[0] == '&') {
131
+ if (curr[1] == ' ' && !isIdent(curr[2]) && !isFunction(curr[2])) {
132
+ curr.splice(0, 2);
133
+ }
134
+ else if (combinators.includes(curr[1])) {
135
+ curr.shift();
136
+ }
137
+ }
138
+ else { // @ts-ignore
139
+ if (this.typ == EnumToken.RuleNodeType && (isIdent(curr[0]) || isFunction(curr[0]))) {
61
140
  curr.unshift('&', ' ');
62
141
  }
63
- acc.push(curr.join(''));
64
- return acc;
65
142
  }
143
+ acc.push(curr.join(''));
144
+ return acc;
145
+ }
146
+ function doMinify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
147
+ if (!('nodes' in context)) {
148
+ context.nodes = new Set;
149
+ }
150
+ if (context.nodes.has(ast)) {
151
+ return ast;
152
+ }
153
+ context.nodes.add(ast);
66
154
  // @ts-ignore
67
155
  if ('chi' in ast && ast.chi.length > 0) {
156
+ const reducer = reduce.bind(ast);
68
157
  if (!nestingContent) {
69
158
  nestingContent = options.nestingRules && ast.typ == EnumToken.RuleNodeType;
70
159
  }
71
160
  let i = 0;
72
- let previous;
161
+ let previous = null;
73
162
  let node;
74
- let nodeIndex;
163
+ let nodeIndex = -1;
75
164
  // @ts-ignore
76
165
  for (; i < ast.chi.length; i++) {
77
166
  // @ts-ignore
@@ -83,13 +172,50 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
83
172
  // @ts-ignore
84
173
  if (previous == node) {
85
174
  // @ts-ignore
86
- ast.chi.splice(i, 1);
87
- i--;
175
+ ast.chi.splice(i--, 1);
88
176
  continue;
89
177
  }
90
178
  if (node.typ == EnumToken.AtRuleNodeType && node.nam == 'font-face') {
91
179
  continue;
92
180
  }
181
+ if (node.typ == EnumToken.KeyframeAtRuleNodeType) {
182
+ if (previous?.typ == EnumToken.KeyframeAtRuleNodeType &&
183
+ node.nam == previous.nam &&
184
+ node.val == previous.val) {
185
+ ast.chi?.splice(nodeIndex--, 1);
186
+ previous = ast?.chi?.[nodeIndex] ?? null;
187
+ i = nodeIndex;
188
+ continue;
189
+ }
190
+ if (node.chi.length > 0) {
191
+ doMinify(node, options, true, errors, nestingContent, context);
192
+ }
193
+ }
194
+ if (node.typ == EnumToken.KeyFrameRuleNodeType) {
195
+ if (previous?.typ == EnumToken.KeyFrameRuleNodeType &&
196
+ node.sel == previous.sel) {
197
+ previous.chi.push(...node.chi);
198
+ // @ts-ignore
199
+ ast.chi.splice(i--, 1);
200
+ continue;
201
+ }
202
+ let k;
203
+ for (k = 0; k < node.chi.length; k++) {
204
+ if (node.chi[k].typ == EnumToken.DeclarationNodeType) {
205
+ let l = node.chi[k].val.length;
206
+ while (l--) {
207
+ if (node.chi[k].val[l].typ == EnumToken.ImportantTokenType) {
208
+ node.chi.splice(k--, 1);
209
+ break;
210
+ }
211
+ if ([EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(node.chi[k].val[l].typ)) {
212
+ continue;
213
+ }
214
+ break;
215
+ }
216
+ }
217
+ }
218
+ }
93
219
  if (node.typ == EnumToken.AtRuleNodeType) {
94
220
  // @ts-ignore
95
221
  if (node.nam == 'media' && ['all', '', null].includes(node.val)) {
@@ -111,7 +237,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
111
237
  }
112
238
  // @ts-ignore
113
239
  if (!hasDeclaration(node)) {
114
- minify(node, options, recursive, errors, nestingContent, context);
240
+ doMinify(node, options, recursive, errors, nestingContent, context);
115
241
  }
116
242
  previous = node;
117
243
  nodeIndex = i;
@@ -162,7 +288,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
162
288
  nodeIndex = --i;
163
289
  // @ts-ignore
164
290
  previous = ast.chi[nodeIndex];
165
- minify(wrapper, options, recursive, errors, nestingContent, context);
291
+ doMinify(wrapper, options, recursive, errors, nestingContent, context);
166
292
  continue;
167
293
  }
168
294
  // @ts-ignore
@@ -269,7 +395,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
269
395
  // @ts-ignore
270
396
  // minifyRule(node, <MinifyOptions>options, ast, context);
271
397
  // } else {
272
- minify(node, options, recursive, errors, nestingContent, context);
398
+ doMinify(node, options, recursive, errors, nestingContent, context);
273
399
  }
274
400
  i--;
275
401
  previous = node;
@@ -324,7 +450,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
324
450
  // @ts-ignore
325
451
  // minifyRule(previous, <MinifyOptions>options, ast, context);
326
452
  // } else {
327
- minify(previous, options, recursive, errors, nestingContent, context);
453
+ doMinify(previous, options, recursive, errors, nestingContent, context);
328
454
  }
329
455
  }
330
456
  }
@@ -335,11 +461,15 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
335
461
  // @ts-ignore
336
462
  // minifyRule(previous, <MinifyOptions>options, ast, context);
337
463
  // } else {
338
- minify(previous, options, recursive, errors, nestingContent, context);
464
+ doMinify(previous, options, recursive, errors, nestingContent, context);
339
465
  }
340
466
  }
341
467
  }
342
468
  }
469
+ // else if ('chi' in node) {
470
+ //
471
+ // doMinify(node, options, recursive, errors, nestingContent, context);
472
+ // }
343
473
  if (!nestingContent &&
344
474
  // @ts-ignore
345
475
  previous != null &&
@@ -354,10 +484,10 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
354
484
  // @ts-ignore
355
485
  if (recursive && node != null && ('chi' in node)) {
356
486
  // @ts-ignore
357
- if (!node.chi.some(n => n.typ == EnumToken.DeclarationNodeType)) {
487
+ if (node.typ == EnumToken.KeyframeAtRuleNodeType || !node.chi.some(n => n.typ == EnumToken.DeclarationNodeType)) {
358
488
  // @ts-ignore
359
489
  if (!(node.typ == EnumToken.AtRuleNodeType && node.nam != 'font-face')) {
360
- minify(node, options, recursive, errors, nestingContent, context);
490
+ doMinify(node, options, recursive, errors, nestingContent, context);
361
491
  }
362
492
  }
363
493
  }
@@ -370,41 +500,6 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
370
500
  fixSelector(node);
371
501
  }
372
502
  }
373
- if (ast.typ == EnumToken.StyleSheetNodeType) {
374
- let parent;
375
- let parents = [ast];
376
- while (parents.length > 0) {
377
- parent = parents.shift();
378
- // @ts-ignore
379
- for (let k = 0; k < parent.chi.length; k++) {
380
- // @ts-ignore
381
- const node = parent.chi[k];
382
- if (!('chi' in node) || node.typ == EnumToken.StyleSheetNodeType || (node.typ == EnumToken.AtRuleNodeType && node.nam == 'font-face')) {
383
- continue;
384
- }
385
- // @ts-ignore
386
- if (node.chi.length > 0) {
387
- parents.push(node);
388
- Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: parent });
389
- for (const feature of options.features) {
390
- feature.run(node, options, parent, context);
391
- }
392
- }
393
- // @ts-ignore
394
- if (options.removeEmpty && node.chi.length == 0) {
395
- // @ts-ignore
396
- parent.chi.splice(k, 1);
397
- k--;
398
- }
399
- }
400
- }
401
- for (const feature of options.features) {
402
- if ('cleanup' in feature) {
403
- // @ts-ignore
404
- feature.cleanup(ast, options, context);
405
- }
406
- }
407
- }
408
503
  return ast;
409
504
  }
410
505
  function hasDeclaration(node) {
@@ -559,6 +654,28 @@ function splitRule(buffer) {
559
654
  result.push([]);
560
655
  continue;
561
656
  }
657
+ if (chr == '.') {
658
+ if (str !== '') {
659
+ // @ts-ignore
660
+ result.at(-1).push(str);
661
+ str = '';
662
+ }
663
+ str += chr;
664
+ continue;
665
+ }
666
+ if (combinators.includes(chr)) {
667
+ if (str !== '') {
668
+ // @ts-ignore
669
+ result.at(-1).push(str);
670
+ str = '';
671
+ }
672
+ if (chr == '|' && buffer.charAt(i + 1) == '|') {
673
+ chr += buffer.charAt(++i);
674
+ }
675
+ // @ts-ignore
676
+ result.at(-1).push(chr);
677
+ continue;
678
+ }
562
679
  if (chr == ':') {
563
680
  if (str !== '') {
564
681
  // @ts-ignore
@@ -775,7 +892,6 @@ function matchSelectors(selector1, selector2, parentType, errors) {
775
892
  }, []);
776
893
  }
777
894
  }
778
- // @todo: check hasCompoundSelector && curr[0] == '&' && curr[1] == ' '
779
895
  acc.push(match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
780
896
  return acc;
781
897
  }
@@ -853,6 +969,9 @@ function wrapNodes(previous, node, match, ast, reducer, i, nodeIndex) {
853
969
  return wrapper;
854
970
  }
855
971
  function diff(n1, n2, reducer, options = {}) {
972
+ if (!('cache' in options)) {
973
+ options.cache = new WeakMap();
974
+ }
856
975
  let node1 = n1;
857
976
  let node2 = n2;
858
977
  let exchanged = false;
@@ -865,12 +984,9 @@ function diff(n1, n2, reducer, options = {}) {
865
984
  let i = node1.chi.length;
866
985
  let j = node2.chi.length;
867
986
  if (i == 0 || j == 0) {
868
- // @ts-ignore
869
987
  return null;
870
988
  }
871
- // @ts-ignore
872
989
  const raw1 = node1.raw;
873
- // @ts-ignore
874
990
  const raw2 = node2.raw;
875
991
  if (raw1 != null && raw2 != null) {
876
992
  const prefixes1 = new Set;
@@ -918,9 +1034,16 @@ function diff(n1, n2, reducer, options = {}) {
918
1034
  }
919
1035
  }
920
1036
  }
921
- // @ts-ignore
1037
+ const css1 = options.cache.get(node1);
1038
+ const css2 = options.cache.get(node2);
922
1039
  node1 = { ...node1, chi: node1.chi.slice() };
923
1040
  node2 = { ...node2, chi: node2.chi.slice() };
1041
+ if (css1 != null) {
1042
+ options.cache.set(node1, css1);
1043
+ }
1044
+ if (css2 != null) {
1045
+ options.cache.set(node2, css2);
1046
+ }
924
1047
  if (raw1 != null) {
925
1048
  Object.defineProperty(node1, 'raw', { ...definedPropertySettings, value: raw1 });
926
1049
  }
@@ -941,24 +1064,34 @@ function diff(n1, n2, reducer, options = {}) {
941
1064
  continue;
942
1065
  }
943
1066
  if (node1.chi[i].nam == node2.chi[j].nam) {
944
- if (eq(node1.chi[i], node2.chi[j])) {
1067
+ if (node1.chi[i].typ == node2.chi[j].typ && eq(node1.chi[i], node2.chi[j])) {
945
1068
  intersect.push(node1.chi[i]);
946
1069
  node1.chi.splice(i, 1);
947
1070
  node2.chi.splice(j, 1);
1071
+ options.cache.delete(node1);
1072
+ options.cache.delete(node2);
948
1073
  break;
949
1074
  }
950
1075
  }
951
1076
  }
952
1077
  }
953
- // @ts-ignore
954
1078
  const result = (intersect.length == 0 ? null : {
955
1079
  ...node1,
956
1080
  // @ts-ignore
957
1081
  sel: [...new Set([...(n1?.raw?.reduce(reducer, []) ?? splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) ?? splitRule(n2.sel))])].join(','),
958
1082
  chi: intersect.reverse()
959
1083
  });
960
- if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + doRender(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + doRender(curr, options).code.length, 0)) {
961
- // @ts-ignore
1084
+ if (result == null || [n1, n2].reduce((acc, curr) => {
1085
+ let css = options.cache.get(curr);
1086
+ if (css == null) {
1087
+ css = doRender(curr, options).code;
1088
+ options.cache.set(curr, css);
1089
+ }
1090
+ return curr.chi.length == 0 ? acc : acc + css.length;
1091
+ }, 0) <= [node1, node2, result].reduce((acc, curr) => {
1092
+ const css = doRender(curr, options).code;
1093
+ return curr.chi.length == 0 ? acc : acc + css.length;
1094
+ }, 0)) {
962
1095
  return null;
963
1096
  }
964
1097
  return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node1 : node2 };
@@ -967,9 +1100,6 @@ function reduceRuleSelector(node) {
967
1100
  if (node.raw == null) {
968
1101
  Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: splitRule(node.sel) });
969
1102
  }
970
- // @ts-ignore
971
- // if (node.raw != null) {
972
- // @ts-ignore
973
1103
  let optimized = reduceSelector(node.raw.reduce((acc, curr) => {
974
1104
  acc.push(curr.slice());
975
1105
  return acc;
@@ -1003,7 +1133,6 @@ function reduceRuleSelector(node) {
1003
1133
  const sel = raw[0].join('');
1004
1134
  if (sel.length < node.sel.length) {
1005
1135
  node.sel = sel;
1006
- // node.raw = raw;
1007
1136
  Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
1008
1137
  }
1009
1138
  }