@tbela99/css-parser 0.9.0 → 1.0.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/LICENSE.md +1 -1
- package/README.md +22 -12
- package/dist/index-umd-web.js +2678 -2838
- package/dist/index.cjs +2468 -2628
- package/dist/index.d.ts +71 -26
- package/dist/lib/ast/expand.js +15 -2
- package/dist/lib/ast/features/calc.js +7 -10
- package/dist/lib/ast/features/index.js +1 -0
- package/dist/lib/ast/features/inlinecssvariables.js +0 -5
- package/dist/lib/ast/features/prefix.js +2 -7
- package/dist/lib/ast/features/shorthand.js +6 -9
- package/dist/lib/ast/features/transform.js +60 -0
- package/dist/lib/ast/math/expression.js +14 -10
- package/dist/lib/ast/math/math.js +14 -2
- package/dist/lib/ast/minify.js +47 -6
- package/dist/lib/ast/transform/compute.js +336 -0
- package/dist/lib/ast/transform/convert.js +33 -0
- package/dist/lib/ast/transform/matrix.js +111 -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 +2 -0
- package/dist/lib/ast/walk.js +23 -17
- package/dist/lib/parser/parse.js +174 -127
- package/dist/lib/parser/utils/declaration.js +1 -1
- package/dist/lib/renderer/color/{colormix.js → color-mix.js} +6 -0
- package/dist/lib/renderer/color/color.js +96 -20
- package/dist/lib/renderer/color/hex.js +17 -7
- package/dist/lib/renderer/color/hsl.js +7 -2
- package/dist/lib/renderer/color/lab.js +10 -1
- package/dist/lib/renderer/color/lch.js +8 -0
- package/dist/lib/renderer/color/oklab.js +8 -0
- package/dist/lib/renderer/color/oklch.js +8 -0
- package/dist/lib/renderer/color/prophotorgb.js +2 -2
- package/dist/lib/renderer/color/relativecolor.js +10 -21
- package/dist/lib/renderer/color/rgb.js +10 -7
- package/dist/lib/renderer/color/srgb.js +30 -6
- package/dist/lib/renderer/color/utils/components.js +13 -2
- package/dist/lib/renderer/color/xyz.js +2 -18
- package/dist/lib/renderer/color/xyzd50.js +20 -2
- package/dist/lib/renderer/render.js +70 -32
- package/dist/lib/renderer/sourcemap/sourcemap.js +1 -1
- package/dist/lib/syntax/syntax.js +75 -56
- package/dist/lib/validation/at-rules/container.js +6 -6
- package/dist/lib/validation/at-rules/document.js +40 -60
- package/dist/lib/validation/at-rules/import.js +61 -59
- package/dist/lib/validation/at-rules/keyframes.js +1 -1
- package/dist/lib/validation/at-rules/media.js +1 -1
- package/dist/lib/validation/at-rules/supports.js +40 -9
- package/dist/lib/validation/atrule.js +0 -4
- package/dist/lib/validation/config.json.js +83 -35
- package/dist/lib/validation/parser/parse.js +1 -95
- package/dist/lib/validation/parser/types.js +1 -2
- package/dist/lib/validation/selector.js +5 -2
- package/dist/lib/validation/syntaxes/compound-selector.js +2 -2
- package/dist/lib/validation/syntaxes/keyframe-block-list.js +2 -2
- package/dist/lib/validation/syntaxes/keyframe-selector.js +11 -90
- package/dist/lib/validation/syntaxes/layer-name.js +5 -16
- package/dist/lib/validation/syntaxes/relative-selector.js +15 -14
- package/dist/lib/validation/utils/list.js +18 -1
- package/dist/node/load.js +1 -1
- package/package.json +13 -12
- package/dist/lib/renderer/color/prophotoRgb.js +0 -56
- package/dist/lib/validation/declaration.js +0 -102
- package/dist/lib/validation/syntax.js +0 -1475
- package/dist/lib/validation/syntaxes/image.js +0 -29
package/dist/lib/ast/walk.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { EnumToken } from './types.js';
|
|
2
2
|
|
|
3
|
+
var WalkerOptionEnum;
|
|
4
|
+
(function (WalkerOptionEnum) {
|
|
5
|
+
WalkerOptionEnum[WalkerOptionEnum["Ignore"] = 0] = "Ignore";
|
|
6
|
+
WalkerOptionEnum[WalkerOptionEnum["Stop"] = 1] = "Stop";
|
|
7
|
+
WalkerOptionEnum[WalkerOptionEnum["Children"] = 2] = "Children";
|
|
8
|
+
WalkerOptionEnum[WalkerOptionEnum["IgnoreChildren"] = 3] = "IgnoreChildren";
|
|
9
|
+
})(WalkerOptionEnum || (WalkerOptionEnum = {}));
|
|
3
10
|
var WalkerValueEvent;
|
|
4
11
|
(function (WalkerValueEvent) {
|
|
5
12
|
WalkerValueEvent[WalkerValueEvent["Enter"] = 0] = "Enter";
|
|
@@ -18,10 +25,10 @@ function* walk(node, filter) {
|
|
|
18
25
|
let option = null;
|
|
19
26
|
if (filter != null) {
|
|
20
27
|
option = filter(node);
|
|
21
|
-
if (option ===
|
|
28
|
+
if (option === WalkerOptionEnum.Ignore) {
|
|
22
29
|
continue;
|
|
23
30
|
}
|
|
24
|
-
if (option ===
|
|
31
|
+
if (option === WalkerOptionEnum.Stop) {
|
|
25
32
|
break;
|
|
26
33
|
}
|
|
27
34
|
}
|
|
@@ -30,7 +37,7 @@ function* walk(node, filter) {
|
|
|
30
37
|
// @ts-ignore
|
|
31
38
|
yield { node, parent: map.get(node), root };
|
|
32
39
|
}
|
|
33
|
-
if (option !==
|
|
40
|
+
if (option !== WalkerOptionEnum.IgnoreChildren && 'chi' in node) {
|
|
34
41
|
parents.unshift(...node.chi);
|
|
35
42
|
for (const child of node.chi.slice()) {
|
|
36
43
|
map.set(child, node);
|
|
@@ -62,19 +69,20 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
62
69
|
event: WalkerValueEvent.Enter
|
|
63
70
|
};
|
|
64
71
|
}
|
|
72
|
+
const eventType = filter.event ?? WalkerValueEvent.Enter;
|
|
65
73
|
while (stack.length > 0) {
|
|
66
74
|
let value = reverse ? stack.pop() : stack.shift();
|
|
67
75
|
let option = null;
|
|
68
|
-
if (filter.fn != null &&
|
|
76
|
+
if (filter.fn != null && eventType == WalkerValueEvent.Enter) {
|
|
69
77
|
const isValid = filter.type == null || value.typ == filter.type ||
|
|
70
78
|
(Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
|
|
71
79
|
(typeof filter.type == 'function' && filter.type(value));
|
|
72
80
|
if (isValid) {
|
|
73
|
-
option = filter.fn(value, map.get(value) ?? root
|
|
74
|
-
if (option ===
|
|
81
|
+
option = filter.fn(value, map.get(value) ?? root);
|
|
82
|
+
if (option === WalkerOptionEnum.Ignore) {
|
|
75
83
|
continue;
|
|
76
84
|
}
|
|
77
|
-
if (option ===
|
|
85
|
+
if (option === WalkerOptionEnum.Stop) {
|
|
78
86
|
break;
|
|
79
87
|
}
|
|
80
88
|
// @ts-ignore
|
|
@@ -83,8 +91,7 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
83
91
|
}
|
|
84
92
|
}
|
|
85
93
|
}
|
|
86
|
-
|
|
87
|
-
if (filter.event == WalkerValueEvent.Enter && option !== 'children') {
|
|
94
|
+
if (eventType == WalkerValueEvent.Enter && option !== WalkerOptionEnum.Children) {
|
|
88
95
|
yield {
|
|
89
96
|
value,
|
|
90
97
|
parent: map.get(value) ?? root,
|
|
@@ -94,7 +101,7 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
94
101
|
root: root ?? null
|
|
95
102
|
};
|
|
96
103
|
}
|
|
97
|
-
if (option !==
|
|
104
|
+
if (option !== WalkerOptionEnum.IgnoreChildren && 'chi' in value) {
|
|
98
105
|
const sliced = value.chi.slice();
|
|
99
106
|
for (const child of sliced) {
|
|
100
107
|
map.set(child, value);
|
|
@@ -107,24 +114,23 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
107
114
|
}
|
|
108
115
|
}
|
|
109
116
|
else if (value.typ == EnumToken.BinaryExpressionTokenType) {
|
|
110
|
-
map.set(value.l,
|
|
111
|
-
map.set(value.r,
|
|
117
|
+
map.set(value.l, value);
|
|
118
|
+
map.set(value.r, value);
|
|
112
119
|
stack.unshift(value.l, value.r);
|
|
113
120
|
}
|
|
114
|
-
if (
|
|
121
|
+
if (eventType == WalkerValueEvent.Leave && filter.fn != null) {
|
|
115
122
|
const isValid = filter.type == null || value.typ == filter.type ||
|
|
116
123
|
(Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
|
|
117
124
|
(typeof filter.type == 'function' && filter.type(value));
|
|
118
125
|
if (isValid) {
|
|
119
|
-
option = filter.fn(value, map.get(value)
|
|
126
|
+
option = filter.fn(value, map.get(value));
|
|
120
127
|
// @ts-ignore
|
|
121
128
|
if (option != null && 'typ' in option) {
|
|
122
129
|
map.set(option, map.get(value) ?? root);
|
|
123
130
|
}
|
|
124
131
|
}
|
|
125
132
|
}
|
|
126
|
-
|
|
127
|
-
if (filter.event == WalkerValueEvent.Leave && option !== 'children') {
|
|
133
|
+
if (eventType == WalkerValueEvent.Leave && option !== WalkerOptionEnum.Children) {
|
|
128
134
|
yield {
|
|
129
135
|
value,
|
|
130
136
|
parent: map.get(value) ?? root,
|
|
@@ -138,4 +144,4 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
138
144
|
}
|
|
139
145
|
}
|
|
140
146
|
|
|
141
|
-
export { WalkerValueEvent, walk, walkValues };
|
|
147
|
+
export { WalkerOptionEnum, WalkerValueEvent, walk, walkValues };
|
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { webkitPseudoAliasMap, isIdentStart, isIdent, mathFuncs, isColor, isHexColor, isPseudo, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isHash, mediaTypes } from '../syntax/syntax.js';
|
|
1
|
+
import { webkitPseudoAliasMap, isIdentStart, isIdent, mathFuncs, isColor, isHexColor, isPseudo, pseudoElements, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isHash, mediaTypes } from '../syntax/syntax.js';
|
|
2
2
|
import './utils/config.js';
|
|
3
3
|
import { EnumToken, funcLike, ValidationLevel } from '../ast/types.js';
|
|
4
4
|
import { minify, definedPropertySettings, combinators } from '../ast/minify.js';
|
|
5
|
-
import { walkValues, walk } from '../ast/walk.js';
|
|
5
|
+
import { walkValues, walk, WalkerOptionEnum } from '../ast/walk.js';
|
|
6
6
|
import { expand } from '../ast/expand.js';
|
|
7
7
|
import { parseDeclarationNode } from './utils/declaration.js';
|
|
8
8
|
import { renderToken } from '../renderer/render.js';
|
|
@@ -14,6 +14,8 @@ import '../validation/parser/parse.js';
|
|
|
14
14
|
import { validateSelector } from '../validation/selector.js';
|
|
15
15
|
import { validateAtRule } from '../validation/atrule.js';
|
|
16
16
|
import '../validation/syntaxes/complex-selector.js';
|
|
17
|
+
import { validateKeyframeSelector } from '../validation/syntaxes/keyframe-selector.js';
|
|
18
|
+
import { validateAtRuleKeyframes } from '../validation/at-rules/keyframes.js';
|
|
17
19
|
|
|
18
20
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
19
21
|
const trimWhiteSpace = [EnumToken.CommentTokenType, EnumToken.GtTokenType, EnumToken.GteTokenType, EnumToken.LtTokenType, EnumToken.LteTokenType, EnumToken.ColumnCombinatorTokenType];
|
|
@@ -46,13 +48,15 @@ async function doParse(iterator, options = {}) {
|
|
|
46
48
|
src: '',
|
|
47
49
|
sourcemap: false,
|
|
48
50
|
minify: true,
|
|
51
|
+
pass: 1,
|
|
49
52
|
parseColor: true,
|
|
50
|
-
nestingRules:
|
|
53
|
+
nestingRules: true,
|
|
51
54
|
resolveImport: false,
|
|
52
55
|
resolveUrls: false,
|
|
53
56
|
removeCharset: true,
|
|
54
57
|
removeEmpty: true,
|
|
55
58
|
removeDuplicateDeclarations: true,
|
|
59
|
+
computeTransform: true,
|
|
56
60
|
computeShorthand: true,
|
|
57
61
|
computeCalcExpression: true,
|
|
58
62
|
inlineCssVariables: false,
|
|
@@ -121,11 +125,13 @@ async function doParse(iterator, options = {}) {
|
|
|
121
125
|
}
|
|
122
126
|
else if (item.token == '{') {
|
|
123
127
|
let inBlock = 1;
|
|
128
|
+
tokens = [item];
|
|
124
129
|
do {
|
|
125
130
|
item = iter.next().value;
|
|
126
131
|
if (item == null) {
|
|
127
132
|
break;
|
|
128
133
|
}
|
|
134
|
+
tokens.push(item);
|
|
129
135
|
if (item.token == '{') {
|
|
130
136
|
inBlock++;
|
|
131
137
|
}
|
|
@@ -133,6 +139,13 @@ async function doParse(iterator, options = {}) {
|
|
|
133
139
|
inBlock--;
|
|
134
140
|
}
|
|
135
141
|
} while (inBlock != 0);
|
|
142
|
+
if (tokens.length > 0) {
|
|
143
|
+
errors.push({
|
|
144
|
+
action: 'drop',
|
|
145
|
+
message: 'invalid block',
|
|
146
|
+
rawTokens: tokens.slice()
|
|
147
|
+
});
|
|
148
|
+
}
|
|
136
149
|
}
|
|
137
150
|
tokens = [];
|
|
138
151
|
map = new Map;
|
|
@@ -165,7 +178,8 @@ async function doParse(iterator, options = {}) {
|
|
|
165
178
|
await parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
166
179
|
rawTokens.length = 0;
|
|
167
180
|
if (context != null && context.typ == EnumToken.InvalidRuleTokenType) {
|
|
168
|
-
|
|
181
|
+
// @ts-ignore
|
|
182
|
+
const index = context.chi.findIndex((node) => node == context);
|
|
169
183
|
if (index > -1) {
|
|
170
184
|
context.chi.splice(index, 1);
|
|
171
185
|
}
|
|
@@ -225,7 +239,10 @@ async function doParse(iterator, options = {}) {
|
|
|
225
239
|
}
|
|
226
240
|
if (options.minify) {
|
|
227
241
|
if (ast.chi.length > 0) {
|
|
228
|
-
|
|
242
|
+
let passes = options.pass ?? 1;
|
|
243
|
+
while (passes--) {
|
|
244
|
+
minify(ast, options, true, errors, false);
|
|
245
|
+
}
|
|
229
246
|
}
|
|
230
247
|
}
|
|
231
248
|
const endTime = performance.now();
|
|
@@ -326,8 +343,13 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
326
343
|
continue;
|
|
327
344
|
}
|
|
328
345
|
if (type != EnumToken.AtRuleNodeType) {
|
|
329
|
-
|
|
330
|
-
|
|
346
|
+
// @ts-ignore
|
|
347
|
+
if (!(type == EnumToken.InvalidAtRuleTokenType &&
|
|
348
|
+
// @ts-ignore
|
|
349
|
+
['charset', 'layer', 'import'].includes(context.chi[i].nam))) {
|
|
350
|
+
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
331
353
|
}
|
|
332
354
|
// @ts-ignore
|
|
333
355
|
const name = context.chi[i].nam;
|
|
@@ -362,12 +384,20 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
362
384
|
if (tokens[0].typ == EnumToken.UrlFunctionTokenType) {
|
|
363
385
|
if (tokens[1].typ == EnumToken.UrlTokenTokenType || tokens[1].typ == EnumToken.StringTokenType) {
|
|
364
386
|
tokens.shift();
|
|
365
|
-
if (tokens[
|
|
387
|
+
if (tokens[0]?.typ == EnumToken.UrlTokenTokenType) {
|
|
366
388
|
// @ts-ignore
|
|
367
389
|
tokens[0].typ = EnumToken.StringTokenType;
|
|
368
390
|
// @ts-ignore
|
|
369
391
|
tokens[0].val = `"${tokens[0].val}"`;
|
|
370
392
|
}
|
|
393
|
+
// @ts-ignore
|
|
394
|
+
while (tokens[1]?.typ == EnumToken.WhitespaceTokenType || tokens[1]?.typ == EnumToken.CommentTokenType) {
|
|
395
|
+
tokens.splice(1, 1);
|
|
396
|
+
}
|
|
397
|
+
// @ts-ignore
|
|
398
|
+
if (tokens[1]?.typ == EnumToken.EndParensTokenType) {
|
|
399
|
+
tokens.splice(1, 1);
|
|
400
|
+
}
|
|
371
401
|
}
|
|
372
402
|
}
|
|
373
403
|
// @ts-ignore
|
|
@@ -448,14 +478,16 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
448
478
|
acc.push(renderToken(curr, { removeComments: true }));
|
|
449
479
|
return acc;
|
|
450
480
|
}, []);
|
|
481
|
+
const nam = renderToken(atRule, { removeComments: true });
|
|
482
|
+
// @ts-ignore
|
|
451
483
|
const node = {
|
|
452
|
-
typ: EnumToken.AtRuleNodeType,
|
|
453
|
-
nam
|
|
454
|
-
tokens: t,
|
|
484
|
+
typ: /^(-[a-z]+-)?keyframes$/.test(nam) ? EnumToken.KeyframeAtRuleNodeType : EnumToken.AtRuleNodeType,
|
|
485
|
+
nam,
|
|
486
|
+
// tokens: t,
|
|
455
487
|
val: raw.join('')
|
|
456
488
|
};
|
|
457
489
|
Object.defineProperties(node, {
|
|
458
|
-
tokens: { ...definedPropertySettings, enumerable:
|
|
490
|
+
tokens: { ...definedPropertySettings, enumerable: false, value: tokens.slice() },
|
|
459
491
|
raw: { ...definedPropertySettings, value: raw }
|
|
460
492
|
});
|
|
461
493
|
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
@@ -481,7 +513,7 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
481
513
|
isValid = false;
|
|
482
514
|
}
|
|
483
515
|
}
|
|
484
|
-
const valid = isValid ? validateAtRule(node, options, context) : {
|
|
516
|
+
const valid = isValid ? (node.typ == EnumToken.KeyframeAtRuleNodeType ? validateAtRuleKeyframes(node) : validateAtRule(node, options, context)) : {
|
|
485
517
|
valid: ValidationLevel.Drop,
|
|
486
518
|
node,
|
|
487
519
|
syntax: '@' + node.nam,
|
|
@@ -497,7 +529,10 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
497
529
|
node.typ = EnumToken.InvalidAtRuleTokenType;
|
|
498
530
|
}
|
|
499
531
|
else {
|
|
500
|
-
node.val = node.tokens.reduce((acc, curr) => acc + renderToken(curr, {
|
|
532
|
+
node.val = node.tokens.reduce((acc, curr) => acc + renderToken(curr, {
|
|
533
|
+
minify: false,
|
|
534
|
+
removeComments: true
|
|
535
|
+
}), '');
|
|
501
536
|
}
|
|
502
537
|
}
|
|
503
538
|
// @ts-ignore
|
|
@@ -510,77 +545,84 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
510
545
|
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
511
546
|
const position = map.get(tokens[0]);
|
|
512
547
|
const uniq = new Map;
|
|
513
|
-
parseTokens(tokens, { minify: true })
|
|
514
|
-
|
|
515
|
-
return acc;
|
|
516
|
-
}
|
|
517
|
-
if (curr.typ == EnumToken.WhitespaceTokenType) {
|
|
518
|
-
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
519
|
-
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
520
|
-
combinators.includes(array[index - 1]?.val) ||
|
|
521
|
-
combinators.includes(array[index + 1]?.val)) {
|
|
522
|
-
return acc;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
let t = renderToken(curr, { minify: false });
|
|
526
|
-
if (t == ',') {
|
|
527
|
-
acc.push([]);
|
|
528
|
-
// uniqTokens.push([]);
|
|
529
|
-
}
|
|
530
|
-
else {
|
|
531
|
-
acc[acc.length - 1].push(t);
|
|
532
|
-
// uniqTokens[uniqTokens.length - 1].push(curr);
|
|
533
|
-
}
|
|
534
|
-
return acc;
|
|
535
|
-
}, [[]]).reduce((acc, curr) => {
|
|
536
|
-
let i = 0;
|
|
537
|
-
for (; i < curr.length; i++) {
|
|
538
|
-
if (i + 1 < curr.length && curr[i] == '*') {
|
|
539
|
-
if (curr[i] == '*') {
|
|
540
|
-
let index = curr[i + 1] == ' ' ? 2 : 1;
|
|
541
|
-
if (!['>', '~', '+'].includes(curr[index])) {
|
|
542
|
-
curr.splice(i, index);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
acc.set(curr.join(''), curr);
|
|
548
|
-
return acc;
|
|
549
|
-
}, uniq);
|
|
550
|
-
const ruleType = context.typ == EnumToken.AtRuleNodeType && context.nam == 'keyframes' ? EnumToken.KeyFrameRuleNodeType : EnumToken.RuleNodeType;
|
|
548
|
+
parseTokens(tokens, { minify: true });
|
|
549
|
+
const ruleType = context.typ == EnumToken.KeyframeAtRuleNodeType ? EnumToken.KeyFrameRuleNodeType : EnumToken.RuleNodeType;
|
|
551
550
|
if (ruleType == EnumToken.RuleNodeType) {
|
|
552
551
|
parseSelector(tokens);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
// @ts-ignore
|
|
567
|
-
location: { src, ...(map.get(valid.node) ?? position) }
|
|
568
|
-
});
|
|
552
|
+
}
|
|
553
|
+
if (options.validation) {
|
|
554
|
+
// @ts-ignore
|
|
555
|
+
const valid = ruleType == EnumToken.KeyFrameRuleNodeType ? validateKeyframeSelector(tokens) : validateSelector(tokens, options, context);
|
|
556
|
+
if (valid.valid != ValidationLevel.Valid) {
|
|
557
|
+
const node = {
|
|
558
|
+
typ: EnumToken.InvalidRuleTokenType,
|
|
559
|
+
sel: tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), ''),
|
|
560
|
+
chi: []
|
|
561
|
+
};
|
|
562
|
+
errors.push({
|
|
563
|
+
action: 'drop',
|
|
564
|
+
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
569
565
|
// @ts-ignore
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
566
|
+
location: { src, ...(map.get(valid.node) ?? position) }
|
|
567
|
+
});
|
|
568
|
+
// @ts-ignore
|
|
569
|
+
context.chi.push(node);
|
|
570
|
+
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
|
|
571
|
+
return node;
|
|
574
572
|
}
|
|
575
573
|
}
|
|
576
574
|
const node = {
|
|
577
575
|
typ: ruleType,
|
|
578
|
-
sel: [...
|
|
576
|
+
sel: [...tokens.reduce((acc, curr, index, array) => {
|
|
577
|
+
if (curr.typ == EnumToken.CommentTokenType) {
|
|
578
|
+
return acc;
|
|
579
|
+
}
|
|
580
|
+
if (curr.typ == EnumToken.WhitespaceTokenType) {
|
|
581
|
+
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
582
|
+
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
583
|
+
combinators.includes(array[index - 1]?.val) ||
|
|
584
|
+
combinators.includes(array[index + 1]?.val)) {
|
|
585
|
+
return acc;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (ruleType == EnumToken.KeyFrameRuleNodeType) {
|
|
589
|
+
if (curr.typ == EnumToken.IdenTokenType && curr.val == 'from') {
|
|
590
|
+
Object.assign(curr, { typ: EnumToken.PercentageTokenType, val: '0' });
|
|
591
|
+
}
|
|
592
|
+
else if (curr.typ == EnumToken.PercentageTokenType && curr.val == '100') {
|
|
593
|
+
Object.assign(curr, { typ: EnumToken.IdenTokenType, val: 'to' });
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
let t = renderToken(curr, { minify: false });
|
|
597
|
+
if (t == ',') {
|
|
598
|
+
acc.push([]);
|
|
599
|
+
// uniqTokens.push([]);
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
acc[acc.length - 1].push(t);
|
|
603
|
+
// uniqTokens[uniqTokens.length - 1].push(curr);
|
|
604
|
+
}
|
|
605
|
+
return acc;
|
|
606
|
+
}, [[]]).reduce((acc, curr) => {
|
|
607
|
+
let i = 0;
|
|
608
|
+
for (; i < curr.length; i++) {
|
|
609
|
+
if (i + 1 < curr.length && curr[i] == '*') {
|
|
610
|
+
if (curr[i] == '*') {
|
|
611
|
+
let index = curr[i + 1] == ' ' ? 2 : 1;
|
|
612
|
+
if (!['>', '~', '+'].includes(curr[index])) {
|
|
613
|
+
curr.splice(i, index);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
acc.set(curr.join(''), curr);
|
|
619
|
+
return acc;
|
|
620
|
+
}, uniq).keys()].join(','),
|
|
579
621
|
chi: []
|
|
580
622
|
};
|
|
581
623
|
Object.defineProperty(node, 'tokens', {
|
|
582
624
|
...definedPropertySettings,
|
|
583
|
-
enumerable:
|
|
625
|
+
enumerable: false,
|
|
584
626
|
value: tokens.slice()
|
|
585
627
|
});
|
|
586
628
|
let raw = [...uniq.values()];
|
|
@@ -660,7 +702,8 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
660
702
|
}
|
|
661
703
|
}
|
|
662
704
|
}
|
|
663
|
-
|
|
705
|
+
const nam = renderToken(name.shift(), { removeComments: true });
|
|
706
|
+
if (value == null || (!nam.startsWith('--') && value.length == 0)) {
|
|
664
707
|
errors.push({
|
|
665
708
|
action: 'drop',
|
|
666
709
|
message: 'doParse: invalid declaration',
|
|
@@ -668,33 +711,30 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
668
711
|
});
|
|
669
712
|
return null;
|
|
670
713
|
}
|
|
714
|
+
for (const { value: token } of walkValues(value, null, {
|
|
715
|
+
fn: (node) => node.typ == EnumToken.FunctionTokenType && node.val == 'calc' ? WalkerOptionEnum.IgnoreChildren : null,
|
|
716
|
+
type: EnumToken.FunctionTokenType
|
|
717
|
+
})) {
|
|
718
|
+
if (token.typ == EnumToken.FunctionTokenType && token.val == 'calc') {
|
|
719
|
+
for (const { value: node, parent } of walkValues(token.chi, token)) {
|
|
720
|
+
// fix expressions starting with '/' or '*' such as '/4' in (1 + 1)/4
|
|
721
|
+
if (node.typ == EnumToken.LiteralTokenType && node.val.length > 0) {
|
|
722
|
+
if (node.val[0] == '/' || node.val[0] == '*') {
|
|
723
|
+
parent.chi.splice(parent.chi.indexOf(node), 1, { typ: node.val[0] == '/' ? EnumToken.Div : EnumToken.Mul }, ...parseString(node.val.slice(1)));
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
671
729
|
const node = {
|
|
672
730
|
typ: EnumToken.DeclarationNodeType,
|
|
673
731
|
// @ts-ignore
|
|
674
|
-
nam
|
|
732
|
+
nam,
|
|
675
733
|
// @ts-ignore
|
|
676
734
|
val: value
|
|
677
735
|
};
|
|
678
736
|
const result = parseDeclarationNode(node, errors, src, position);
|
|
679
737
|
if (result != null) {
|
|
680
|
-
// if (options.validation) {
|
|
681
|
-
//
|
|
682
|
-
// const valid: ValidationResult = validateDeclaration(result, options, context);
|
|
683
|
-
//
|
|
684
|
-
// console.error({valid});
|
|
685
|
-
//
|
|
686
|
-
// if (valid.valid == ValidationLevel.Drop) {
|
|
687
|
-
//
|
|
688
|
-
// errors.push({
|
|
689
|
-
// action: 'drop',
|
|
690
|
-
// message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, {minify: false}), '') + '"',
|
|
691
|
-
// // @ts-ignore
|
|
692
|
-
// location: {src, ...(map.get(valid.node) ?? position)}
|
|
693
|
-
// });
|
|
694
|
-
//
|
|
695
|
-
// return null;
|
|
696
|
-
// }
|
|
697
|
-
// }
|
|
698
738
|
// @ts-ignore
|
|
699
739
|
context.chi.push(result);
|
|
700
740
|
Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
|
|
@@ -777,8 +817,6 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
777
817
|
}
|
|
778
818
|
}
|
|
779
819
|
if (value.typ == EnumToken.ParensTokenType || (value.typ == EnumToken.FunctionTokenType && ['media', 'supports', 'style', 'scroll-state'].includes(value.val))) {
|
|
780
|
-
// @todo parse range and declarations
|
|
781
|
-
// parseDeclaration(parent.chi);
|
|
782
820
|
let i;
|
|
783
821
|
let nameIndex = -1;
|
|
784
822
|
let valueIndex = -1;
|
|
@@ -1053,10 +1091,16 @@ function getTokenType(val, hint) {
|
|
|
1053
1091
|
val: val.slice(0, -1),
|
|
1054
1092
|
chi: []
|
|
1055
1093
|
}
|
|
1056
|
-
:
|
|
1057
|
-
|
|
1094
|
+
: (
|
|
1095
|
+
// https://www.w3.org/TR/selectors-4/#single-colon-pseudos
|
|
1096
|
+
val.startsWith('::') || pseudoElements.includes(val) ? {
|
|
1097
|
+
typ: EnumToken.PseudoElementTokenType,
|
|
1058
1098
|
val
|
|
1059
|
-
}
|
|
1099
|
+
} :
|
|
1100
|
+
{
|
|
1101
|
+
typ: EnumToken.PseudoClassTokenType,
|
|
1102
|
+
val
|
|
1103
|
+
});
|
|
1060
1104
|
}
|
|
1061
1105
|
if (isAtKeyword(val)) {
|
|
1062
1106
|
return {
|
|
@@ -1233,25 +1277,25 @@ function parseTokens(tokens, options = {}) {
|
|
|
1233
1277
|
break;
|
|
1234
1278
|
}
|
|
1235
1279
|
}
|
|
1236
|
-
Object.assign(t, {
|
|
1280
|
+
const attr = Object.assign(t, {
|
|
1237
1281
|
typ: inAttr == 0 ? EnumToken.AttrTokenType : EnumToken.InvalidAttrTokenType,
|
|
1238
1282
|
chi: tokens.splice(i + 1, k - i)
|
|
1239
1283
|
});
|
|
1240
1284
|
// @ts-ignore
|
|
1241
|
-
if (
|
|
1285
|
+
if (attr.chi.at(-1).typ == EnumToken.AttrEndTokenType) {
|
|
1242
1286
|
// @ts-ignore
|
|
1243
|
-
|
|
1287
|
+
attr.chi.pop();
|
|
1244
1288
|
}
|
|
1245
1289
|
// @ts-ignore
|
|
1246
|
-
if (
|
|
1290
|
+
if (attr.chi.length > 1) {
|
|
1247
1291
|
/*(<AttrToken>t).chi =*/
|
|
1248
1292
|
// @ts-ignore
|
|
1249
|
-
parseTokens(
|
|
1293
|
+
parseTokens(attr.chi, t.typ);
|
|
1250
1294
|
}
|
|
1251
|
-
let m =
|
|
1295
|
+
let m = attr.chi.length;
|
|
1252
1296
|
let val;
|
|
1253
|
-
for (m = 0; m <
|
|
1254
|
-
val =
|
|
1297
|
+
for (m = 0; m < attr.chi.length; m++) {
|
|
1298
|
+
val = attr.chi[m];
|
|
1255
1299
|
if (val.typ == EnumToken.StringTokenType) {
|
|
1256
1300
|
const slice = val.val.slice(1, -1);
|
|
1257
1301
|
if ((slice.charAt(0) != '-' || (slice.charAt(0) == '-' && isIdentStart(slice.charCodeAt(1)))) && isIdent(slice)) {
|
|
@@ -1261,55 +1305,55 @@ function parseTokens(tokens, options = {}) {
|
|
|
1261
1305
|
else if (val.typ == EnumToken.LiteralTokenType && val.val == '|') {
|
|
1262
1306
|
let upper = m;
|
|
1263
1307
|
let lower = m;
|
|
1264
|
-
while (++upper <
|
|
1265
|
-
if (
|
|
1308
|
+
while (++upper < attr.chi.length) {
|
|
1309
|
+
if (attr.chi[upper].typ == EnumToken.CommentTokenType) {
|
|
1266
1310
|
continue;
|
|
1267
1311
|
}
|
|
1268
1312
|
break;
|
|
1269
1313
|
}
|
|
1270
1314
|
while (lower-- > 0) {
|
|
1271
|
-
if (
|
|
1315
|
+
if (attr.chi[lower].typ == EnumToken.CommentTokenType) {
|
|
1272
1316
|
continue;
|
|
1273
1317
|
}
|
|
1274
1318
|
break;
|
|
1275
1319
|
}
|
|
1276
1320
|
// @ts-ignore
|
|
1277
|
-
|
|
1321
|
+
attr.chi[m] = {
|
|
1278
1322
|
typ: EnumToken.NameSpaceAttributeTokenType,
|
|
1279
|
-
l:
|
|
1280
|
-
r:
|
|
1323
|
+
l: attr.chi[lower],
|
|
1324
|
+
r: attr.chi[upper]
|
|
1281
1325
|
};
|
|
1282
|
-
|
|
1326
|
+
attr.chi.splice(upper, 1);
|
|
1283
1327
|
if (lower >= 0) {
|
|
1284
|
-
|
|
1328
|
+
attr.chi.splice(lower, 1);
|
|
1285
1329
|
m--;
|
|
1286
1330
|
}
|
|
1287
1331
|
}
|
|
1288
1332
|
else if ([
|
|
1289
1333
|
EnumToken.DashMatchTokenType, EnumToken.StartMatchTokenType, EnumToken.ContainMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DelimTokenType
|
|
1290
|
-
].includes(
|
|
1334
|
+
].includes(attr.chi[m].typ)) {
|
|
1291
1335
|
let upper = m;
|
|
1292
1336
|
let lower = m;
|
|
1293
|
-
while (++upper <
|
|
1294
|
-
if (
|
|
1337
|
+
while (++upper < attr.chi.length) {
|
|
1338
|
+
if (attr.chi[upper].typ == EnumToken.CommentTokenType) {
|
|
1295
1339
|
continue;
|
|
1296
1340
|
}
|
|
1297
1341
|
break;
|
|
1298
1342
|
}
|
|
1299
1343
|
while (lower-- > 0) {
|
|
1300
|
-
if (
|
|
1344
|
+
if (attr.chi[lower].typ == EnumToken.CommentTokenType) {
|
|
1301
1345
|
continue;
|
|
1302
1346
|
}
|
|
1303
1347
|
break;
|
|
1304
1348
|
}
|
|
1305
|
-
val =
|
|
1349
|
+
val = attr.chi[lower];
|
|
1306
1350
|
if (val.typ == EnumToken.StringTokenType) {
|
|
1307
1351
|
const slice = val.val.slice(1, -1);
|
|
1308
1352
|
if ((slice.charAt(0) != '-' || (slice.charAt(0) == '-' && isIdentStart(slice.charCodeAt(1)))) && isIdent(slice)) {
|
|
1309
1353
|
Object.assign(val, { typ: EnumToken.IdenTokenType, val: slice });
|
|
1310
1354
|
}
|
|
1311
1355
|
}
|
|
1312
|
-
val =
|
|
1356
|
+
val = attr.chi[upper];
|
|
1313
1357
|
if (val.typ == EnumToken.StringTokenType) {
|
|
1314
1358
|
const slice = val.val.slice(1, -1);
|
|
1315
1359
|
if ((slice.charAt(0) != '-' || (slice.charAt(0) == '-' && isIdentStart(slice.charCodeAt(1)))) && isIdent(slice)) {
|
|
@@ -1336,7 +1380,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1336
1380
|
upper++;
|
|
1337
1381
|
}
|
|
1338
1382
|
if (upper < t.chi.length &&
|
|
1339
|
-
t.chi[upper].typ == EnumToken.
|
|
1383
|
+
t.chi[upper].typ == EnumToken.IdenTokenType &&
|
|
1340
1384
|
['i', 's'].includes(t.chi[upper].val.toLowerCase())) {
|
|
1341
1385
|
t.chi[m].attr = t.chi[upper].val;
|
|
1342
1386
|
t.chi.splice(upper, 1);
|
|
@@ -1429,7 +1473,9 @@ function parseTokens(tokens, options = {}) {
|
|
|
1429
1473
|
t.typ = EnumToken.ColorTokenType;
|
|
1430
1474
|
// @ts-ignore
|
|
1431
1475
|
t.kin = t.val;
|
|
1476
|
+
// @ts-ignore
|
|
1432
1477
|
if (t.chi[0].typ == EnumToken.IdenTokenType) {
|
|
1478
|
+
// @ts-ignore
|
|
1433
1479
|
if (t.chi[0].val == 'from') {
|
|
1434
1480
|
// @ts-ignore
|
|
1435
1481
|
t.cal = 'rel';
|
|
@@ -1439,10 +1485,11 @@ function parseTokens(tokens, options = {}) {
|
|
|
1439
1485
|
// @ts-ignore
|
|
1440
1486
|
t.cal = 'mix';
|
|
1441
1487
|
}
|
|
1442
|
-
else
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1488
|
+
else { // @ts-ignore
|
|
1489
|
+
if (t.val == 'color') {
|
|
1490
|
+
// @ts-ignore
|
|
1491
|
+
t.cal = 'col';
|
|
1492
|
+
}
|
|
1446
1493
|
}
|
|
1447
1494
|
}
|
|
1448
1495
|
const filter = [EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType];
|
|
@@ -1476,7 +1523,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1476
1523
|
if (t.chi.length > 0) {
|
|
1477
1524
|
if (t.typ == EnumToken.PseudoClassFuncTokenType && t.val == ':is' && options.minify) {
|
|
1478
1525
|
//
|
|
1479
|
-
const count = t.chi.filter(t => t.typ != EnumToken.CommentTokenType).length;
|
|
1526
|
+
const count = t.chi.filter((t) => t.typ != EnumToken.CommentTokenType).length;
|
|
1480
1527
|
if (count == 1 ||
|
|
1481
1528
|
(i == 0 &&
|
|
1482
1529
|
(tokens[i + 1]?.typ == EnumToken.CommaTokenType || tokens.length == i + 1)) ||
|
|
@@ -11,7 +11,7 @@ function parseDeclarationNode(node, errors, src, position) {
|
|
|
11
11
|
while (node.val[0]?.typ == EnumToken.WhitespaceTokenType) {
|
|
12
12
|
node.val.shift();
|
|
13
13
|
}
|
|
14
|
-
if (node.val.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)).length == 0) {
|
|
14
|
+
if (!node.nam.startsWith('--') && node.val.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)).length == 0) {
|
|
15
15
|
errors.push({
|
|
16
16
|
action: 'drop',
|
|
17
17
|
message: 'doParse: invalid declaration',
|