@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.
- package/CHANGELOG.md +265 -0
- package/LICENSE.md +1 -1
- package/README.md +29 -17
- package/dist/index-umd-web.js +7461 -4360
- package/dist/index.cjs +8608 -5507
- package/dist/index.d.ts +203 -61
- package/dist/lib/ast/expand.js +2 -1
- package/dist/lib/ast/features/calc.js +19 -11
- package/dist/lib/ast/features/index.js +1 -0
- package/dist/lib/ast/features/inlinecssvariables.js +47 -29
- package/dist/lib/ast/features/prefix.js +117 -91
- package/dist/lib/ast/features/shorthand.js +34 -14
- package/dist/lib/ast/features/transform.js +67 -0
- package/dist/lib/ast/features/type.js +7 -0
- package/dist/lib/ast/math/expression.js +20 -10
- package/dist/lib/ast/math/math.js +20 -2
- package/dist/lib/ast/minify.js +209 -80
- package/dist/lib/ast/transform/compute.js +337 -0
- package/dist/lib/ast/transform/convert.js +33 -0
- package/dist/lib/ast/transform/matrix.js +112 -0
- package/dist/lib/ast/transform/minify.js +296 -0
- package/dist/lib/ast/transform/perspective.js +10 -0
- package/dist/lib/ast/transform/rotate.js +40 -0
- package/dist/lib/ast/transform/scale.js +32 -0
- package/dist/lib/ast/transform/skew.js +23 -0
- package/dist/lib/ast/transform/translate.js +32 -0
- package/dist/lib/ast/transform/utils.js +198 -0
- package/dist/lib/ast/types.js +18 -15
- package/dist/lib/ast/walk.js +54 -22
- package/dist/lib/fs/resolve.js +10 -0
- package/dist/lib/parser/declaration/list.js +48 -45
- package/dist/lib/parser/declaration/map.js +1 -0
- package/dist/lib/parser/declaration/set.js +2 -1
- package/dist/lib/parser/parse.js +449 -340
- package/dist/lib/parser/tokenize.js +147 -72
- package/dist/lib/parser/utils/declaration.js +5 -4
- package/dist/lib/parser/utils/type.js +2 -1
- package/dist/lib/renderer/color/a98rgb.js +2 -1
- package/dist/lib/renderer/color/{colormix.js → color-mix.js} +16 -7
- package/dist/lib/renderer/color/color.js +264 -170
- package/dist/lib/renderer/color/hex.js +19 -8
- package/dist/lib/renderer/color/hsl.js +9 -3
- package/dist/lib/renderer/color/hwb.js +2 -1
- package/dist/lib/renderer/color/lab.js +10 -1
- package/dist/lib/renderer/color/lch.js +10 -1
- package/dist/lib/renderer/color/oklab.js +10 -1
- package/dist/lib/renderer/color/oklch.js +10 -1
- package/dist/lib/renderer/color/p3.js +2 -1
- package/dist/lib/renderer/color/rec2020.js +2 -1
- package/dist/lib/renderer/color/relativecolor.js +27 -32
- package/dist/lib/renderer/color/rgb.js +14 -10
- package/dist/lib/renderer/color/srgb.js +48 -23
- package/dist/lib/renderer/color/utils/components.js +18 -6
- package/dist/lib/renderer/color/utils/constants.js +47 -3
- package/dist/lib/renderer/color/xyz.js +2 -1
- package/dist/lib/renderer/color/xyzd50.js +2 -1
- package/dist/lib/renderer/render.js +108 -43
- package/dist/lib/syntax/syntax.js +267 -136
- package/dist/lib/validation/at-rules/container.js +81 -103
- package/dist/lib/validation/at-rules/counter-style.js +9 -8
- package/dist/lib/validation/at-rules/custom-media.js +13 -15
- package/dist/lib/validation/at-rules/document.js +22 -27
- package/dist/lib/validation/at-rules/font-feature-values.js +8 -8
- package/dist/lib/validation/at-rules/import.js +30 -81
- package/dist/lib/validation/at-rules/keyframes.js +19 -23
- package/dist/lib/validation/at-rules/layer.js +5 -5
- package/dist/lib/validation/at-rules/media.js +42 -53
- package/dist/lib/validation/at-rules/namespace.js +19 -23
- package/dist/lib/validation/at-rules/page-margin-box.js +15 -18
- package/dist/lib/validation/at-rules/page.js +8 -7
- package/dist/lib/validation/at-rules/supports.js +73 -82
- package/dist/lib/validation/at-rules/when.js +32 -36
- package/dist/lib/validation/atrule.js +15 -18
- package/dist/lib/validation/config.js +24 -1
- package/dist/lib/validation/config.json.js +563 -63
- package/dist/lib/validation/parser/parse.js +196 -185
- package/dist/lib/validation/parser/types.js +1 -1
- package/dist/lib/validation/selector.js +8 -5
- package/dist/lib/validation/syntax.js +724 -1405
- package/dist/lib/validation/syntaxes/complex-selector-list.js +10 -11
- package/dist/lib/validation/syntaxes/complex-selector.js +10 -11
- package/dist/lib/validation/syntaxes/compound-selector.js +40 -50
- package/dist/lib/validation/syntaxes/family-name.js +9 -8
- package/dist/lib/validation/syntaxes/keyframe-block-list.js +6 -5
- package/dist/lib/validation/syntaxes/keyframe-selector.js +23 -105
- package/dist/lib/validation/syntaxes/layer-name.js +6 -5
- package/dist/lib/validation/syntaxes/relative-selector-list.js +7 -6
- package/dist/lib/validation/syntaxes/relative-selector.js +17 -15
- package/dist/lib/validation/syntaxes/url.js +18 -22
- package/dist/lib/validation/utils/list.js +20 -2
- package/dist/lib/validation/utils/whitespace.js +2 -1
- package/dist/node/index.js +4 -2
- package/dist/node/load.js +6 -1
- package/dist/web/index.js +4 -2
- package/dist/web/load.js +5 -0
- package/package.json +16 -15
- package/dist/lib/renderer/color/prophotoRgb.js +0 -56
- package/dist/lib/validation/declaration.js +0 -94
- package/dist/lib/validation/syntaxes/image.js +0 -29
package/dist/lib/ast/minify.js
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
53
|
-
if (
|
|
54
|
-
|
|
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
|
-
|
|
57
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) =>
|
|
961
|
-
|
|
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
|
}
|