@tbela99/css-parser 0.7.1 → 0.9.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/.editorconfig +484 -0
- package/README.md +140 -84
- package/dist/index-umd-web.js +8461 -51655
- package/dist/index.cjs +8437 -51636
- package/dist/index.d.ts +220 -68
- package/dist/lib/ast/expand.js +46 -9
- package/dist/lib/ast/features/calc.js +76 -12
- package/dist/lib/ast/features/inlinecssvariables.js +6 -1
- package/dist/lib/ast/features/prefix.js +17 -9
- package/dist/lib/ast/features/shorthand.js +1 -0
- package/dist/lib/ast/math/expression.js +299 -11
- package/dist/lib/ast/math/math.js +7 -1
- package/dist/lib/ast/minify.js +30 -16
- package/dist/lib/ast/types.js +59 -49
- package/dist/lib/ast/walk.js +92 -18
- package/dist/lib/parser/declaration/list.js +1 -0
- package/dist/lib/parser/declaration/map.js +60 -52
- package/dist/lib/parser/declaration/set.js +1 -12
- package/dist/lib/parser/parse.js +371 -119
- package/dist/lib/parser/tokenize.js +31 -6
- package/dist/lib/parser/utils/declaration.js +2 -2
- package/dist/lib/parser/utils/type.js +6 -6
- package/dist/lib/renderer/color/a98rgb.js +1 -0
- package/dist/lib/renderer/color/color.js +1 -0
- package/dist/lib/renderer/color/colormix.js +1 -0
- package/dist/lib/renderer/color/hex.js +2 -1
- package/dist/lib/renderer/color/hsl.js +2 -1
- package/dist/lib/renderer/color/hwb.js +3 -2
- package/dist/lib/renderer/color/lab.js +2 -1
- package/dist/lib/renderer/color/lch.js +2 -1
- package/dist/lib/renderer/color/oklab.js +3 -2
- package/dist/lib/renderer/color/oklch.js +2 -1
- package/dist/lib/renderer/color/p3.js +2 -1
- package/dist/lib/renderer/color/prophotoRgb.js +56 -0
- package/dist/lib/renderer/color/prophotorgb.js +1 -1
- package/dist/lib/renderer/color/rec2020.js +1 -0
- package/dist/lib/renderer/color/relativecolor.js +52 -28
- package/dist/lib/renderer/color/rgb.js +2 -1
- package/dist/lib/renderer/color/srgb.js +3 -2
- package/dist/lib/renderer/color/utils/components.js +1 -0
- package/dist/lib/renderer/color/utils/constants.js +2 -1
- package/dist/lib/renderer/color/xyz.js +2 -1
- package/dist/lib/renderer/color/xyzd50.js +1 -0
- package/dist/lib/renderer/render.js +62 -12
- package/dist/lib/syntax/syntax.js +362 -4
- package/dist/lib/validation/at-rules/container.js +353 -0
- package/dist/lib/validation/at-rules/counter-style.js +78 -0
- package/dist/lib/validation/at-rules/custom-media.js +52 -0
- package/dist/lib/validation/at-rules/document.js +114 -0
- package/dist/lib/validation/at-rules/else.js +5 -0
- package/dist/lib/validation/at-rules/font-feature-values.js +52 -0
- package/dist/lib/validation/at-rules/import.js +199 -0
- package/dist/lib/validation/at-rules/keyframes.js +70 -0
- package/dist/lib/validation/at-rules/layer.js +30 -0
- package/dist/lib/validation/at-rules/media.js +254 -0
- package/dist/lib/validation/at-rules/namespace.js +85 -0
- package/dist/lib/validation/at-rules/page-margin-box.js +56 -0
- package/dist/lib/validation/at-rules/page.js +88 -0
- package/dist/lib/validation/at-rules/supports.js +262 -0
- package/dist/lib/validation/at-rules/when.js +178 -0
- package/dist/lib/validation/atrule.js +187 -0
- package/dist/lib/validation/config.js +35 -2
- package/dist/lib/validation/config.json.js +1683 -50905
- package/dist/lib/validation/declaration.js +102 -0
- package/dist/lib/validation/parser/parse.js +1137 -7
- package/dist/lib/validation/parser/types.js +28 -12
- package/dist/lib/validation/selector.js +26 -444
- package/dist/lib/validation/syntax.js +1475 -0
- package/dist/lib/validation/syntaxes/complex-selector-list.js +45 -0
- package/dist/lib/validation/syntaxes/complex-selector.js +53 -0
- package/dist/lib/validation/syntaxes/compound-selector.js +226 -0
- package/dist/lib/validation/syntaxes/family-name.js +91 -0
- package/dist/lib/validation/syntaxes/image.js +29 -0
- package/dist/lib/validation/syntaxes/keyframe-block-list.js +27 -0
- package/dist/lib/validation/syntaxes/keyframe-selector.js +137 -0
- package/dist/lib/validation/syntaxes/layer-name.js +67 -0
- package/dist/lib/validation/syntaxes/relative-selector-list.js +57 -0
- package/dist/lib/validation/syntaxes/relative-selector.js +36 -0
- package/dist/lib/validation/syntaxes/selector-list.js +5 -0
- package/dist/lib/validation/syntaxes/selector.js +5 -0
- package/dist/lib/validation/syntaxes/url.js +75 -0
- package/dist/lib/validation/utils/list.js +24 -0
- package/dist/lib/validation/utils/whitespace.js +22 -0
- package/dist/node/index.js +5 -5
- package/dist/web/index.js +5 -1
- package/dist/web/load.js +1 -0
- package/package.json +16 -14
- package/dist/lib/ast/utils/minifyfeature.js +0 -9
- package/dist/lib/iterable/weakset.js +0 -58
- package/dist/lib/parser/utils/syntax.js +0 -450
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import { isPseudo, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension,
|
|
1
|
+
import { webkitPseudoAliasMap, isIdentStart, isIdent, mathFuncs, isColor, isHexColor, isPseudo, 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
5
|
import { walkValues, walk } from '../ast/walk.js';
|
|
6
6
|
import { expand } from '../ast/expand.js';
|
|
7
|
-
import {
|
|
7
|
+
import { parseDeclarationNode } from './utils/declaration.js';
|
|
8
8
|
import { renderToken } from '../renderer/render.js';
|
|
9
9
|
import { COLORS_NAMES, systemColors, deprecatedSystemColors } from '../renderer/color/utils/constants.js';
|
|
10
10
|
import { tokenize } from './tokenize.js';
|
|
11
|
+
import '../validation/config.js';
|
|
12
|
+
import '../validation/parser/types.js';
|
|
13
|
+
import '../validation/parser/parse.js';
|
|
11
14
|
import { validateSelector } from '../validation/selector.js';
|
|
15
|
+
import { validateAtRule } from '../validation/atrule.js';
|
|
16
|
+
import '../validation/syntaxes/complex-selector.js';
|
|
12
17
|
|
|
13
18
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
14
19
|
const trimWhiteSpace = [EnumToken.CommentTokenType, EnumToken.GtTokenType, EnumToken.GteTokenType, EnumToken.LtTokenType, EnumToken.LteTokenType, EnumToken.ColumnCombinatorTokenType];
|
|
@@ -25,51 +30,14 @@ const enumTokenHints = new Set([
|
|
|
25
30
|
EnumToken.StartMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DashMatchTokenType, EnumToken.ContainMatchTokenType,
|
|
26
31
|
EnumToken.EOFTokenType
|
|
27
32
|
]);
|
|
28
|
-
const webkitPseudoAliasMap = {
|
|
29
|
-
'-webkit-autofill': 'autofill',
|
|
30
|
-
'-webkit-any': 'is',
|
|
31
|
-
'-moz-any': 'is',
|
|
32
|
-
'-webkit-border-after': 'border-block-end',
|
|
33
|
-
'-webkit-border-after-color': 'border-block-end-color',
|
|
34
|
-
'-webkit-border-after-style': 'border-block-end-style',
|
|
35
|
-
'-webkit-border-after-width': 'border-block-end-width',
|
|
36
|
-
'-webkit-border-before': 'border-block-start',
|
|
37
|
-
'-webkit-border-before-color': 'border-block-start-color',
|
|
38
|
-
'-webkit-border-before-style': 'border-block-start-style',
|
|
39
|
-
'-webkit-border-before-width': 'border-block-start-width',
|
|
40
|
-
'-webkit-border-end': 'border-inline-end',
|
|
41
|
-
'-webkit-border-end-color': 'border-inline-end-color',
|
|
42
|
-
'-webkit-border-end-style': 'border-inline-end-style',
|
|
43
|
-
'-webkit-border-end-width': 'border-inline-end-width',
|
|
44
|
-
'-webkit-border-start': 'border-inline-start',
|
|
45
|
-
'-webkit-border-start-color': 'border-inline-start-color',
|
|
46
|
-
'-webkit-border-start-style': 'border-inline-start-style',
|
|
47
|
-
'-webkit-border-start-width': 'border-inline-start-width',
|
|
48
|
-
'-webkit-box-align': 'align-items',
|
|
49
|
-
'-webkit-box-direction': 'flex-direction',
|
|
50
|
-
'-webkit-box-flex': 'flex-grow',
|
|
51
|
-
'-webkit-box-lines': 'flex-flow',
|
|
52
|
-
'-webkit-box-ordinal-group': 'order',
|
|
53
|
-
'-webkit-box-orient': 'flex-direction',
|
|
54
|
-
'-webkit-box-pack': 'justify-content',
|
|
55
|
-
'-webkit-column-break-after': 'break-after',
|
|
56
|
-
'-webkit-column-break-before': 'break-before',
|
|
57
|
-
'-webkit-column-break-inside': 'break-inside',
|
|
58
|
-
'-webkit-font-feature-settings': 'font-feature-settings',
|
|
59
|
-
'-webkit-hyphenate-character': 'hyphenate-character',
|
|
60
|
-
'-webkit-initial-letter': 'initial-letter',
|
|
61
|
-
'-webkit-margin-end': 'margin-block-end',
|
|
62
|
-
'-webkit-margin-start': 'margin-block-start',
|
|
63
|
-
'-webkit-padding-after': 'padding-block-end',
|
|
64
|
-
'-webkit-padding-before': 'padding-block-start',
|
|
65
|
-
'-webkit-padding-end': 'padding-inline-end',
|
|
66
|
-
'-webkit-padding-start': 'padding-inline-start',
|
|
67
|
-
'-webkit-min-device-pixel-ratio': 'min-resolution',
|
|
68
|
-
'-webkit-max-device-pixel-ratio': 'max-resolution'
|
|
69
|
-
};
|
|
70
33
|
function reject(reason) {
|
|
71
34
|
throw new Error(reason ?? 'Parsing aborted');
|
|
72
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* parse css string
|
|
38
|
+
* @param iterator
|
|
39
|
+
* @param options
|
|
40
|
+
*/
|
|
73
41
|
async function doParse(iterator, options = {}) {
|
|
74
42
|
if (options.signal != null) {
|
|
75
43
|
options.signal.addEventListener('abort', reject);
|
|
@@ -90,7 +58,8 @@ async function doParse(iterator, options = {}) {
|
|
|
90
58
|
inlineCssVariables: false,
|
|
91
59
|
setParent: true,
|
|
92
60
|
removePrefix: false,
|
|
93
|
-
validation:
|
|
61
|
+
validation: true,
|
|
62
|
+
lenient: true,
|
|
94
63
|
...options
|
|
95
64
|
};
|
|
96
65
|
if (options.expandNestingRules) {
|
|
@@ -129,9 +98,10 @@ async function doParse(iterator, options = {}) {
|
|
|
129
98
|
}
|
|
130
99
|
const iter = tokenize(iterator);
|
|
131
100
|
let item;
|
|
101
|
+
const rawTokens = [];
|
|
132
102
|
while (item = iter.next().value) {
|
|
133
103
|
stats.bytesIn = item.bytesIn;
|
|
134
|
-
|
|
104
|
+
rawTokens.push(item);
|
|
135
105
|
// doParse error
|
|
136
106
|
if (item.hint != null && BadTokensTypes.includes(item.hint)) {
|
|
137
107
|
// bad token
|
|
@@ -141,15 +111,15 @@ async function doParse(iterator, options = {}) {
|
|
|
141
111
|
tokens.push(item);
|
|
142
112
|
}
|
|
143
113
|
if (item.token == ';' || item.token == '{') {
|
|
144
|
-
let node = await parseNode(tokens, context, stats, options, errors, src, map);
|
|
114
|
+
let node = await parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
115
|
+
rawTokens.length = 0;
|
|
145
116
|
if (node != null) {
|
|
117
|
+
// @ts-ignore
|
|
146
118
|
stack.push(node);
|
|
147
119
|
// @ts-ignore
|
|
148
120
|
context = node;
|
|
149
121
|
}
|
|
150
122
|
else if (item.token == '{') {
|
|
151
|
-
// node == null
|
|
152
|
-
// consume and throw away until the closing '}' or EOF
|
|
153
123
|
let inBlock = 1;
|
|
154
124
|
do {
|
|
155
125
|
item = iter.next().value;
|
|
@@ -168,18 +138,23 @@ async function doParse(iterator, options = {}) {
|
|
|
168
138
|
map = new Map;
|
|
169
139
|
}
|
|
170
140
|
else if (item.token == '}') {
|
|
171
|
-
await parseNode(tokens, context, stats, options, errors, src, map);
|
|
141
|
+
await parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
142
|
+
rawTokens.length = 0;
|
|
172
143
|
const previousNode = stack.pop();
|
|
173
144
|
// @ts-ignore
|
|
174
145
|
context = stack[stack.length - 1] ?? ast;
|
|
146
|
+
// @ts-ignore
|
|
175
147
|
if (previousNode != null && previousNode.typ == EnumToken.InvalidRuleTokenType) {
|
|
148
|
+
// @ts-ignore
|
|
176
149
|
const index = context.chi.findIndex(node => node == previousNode);
|
|
177
150
|
if (index > -1) {
|
|
151
|
+
// @ts-ignore
|
|
178
152
|
context.chi.splice(index, 1);
|
|
179
153
|
}
|
|
180
154
|
}
|
|
181
155
|
// @ts-ignore
|
|
182
156
|
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
157
|
+
// @ts-ignore
|
|
183
158
|
context.chi.pop();
|
|
184
159
|
}
|
|
185
160
|
tokens = [];
|
|
@@ -187,7 +162,8 @@ async function doParse(iterator, options = {}) {
|
|
|
187
162
|
}
|
|
188
163
|
}
|
|
189
164
|
if (tokens.length > 0) {
|
|
190
|
-
await parseNode(tokens, context, stats, options, errors, src, map);
|
|
165
|
+
await parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
166
|
+
rawTokens.length = 0;
|
|
191
167
|
if (context != null && context.typ == EnumToken.InvalidRuleTokenType) {
|
|
192
168
|
const index = context.chi.findIndex(node => node == context);
|
|
193
169
|
if (index > -1) {
|
|
@@ -199,8 +175,10 @@ async function doParse(iterator, options = {}) {
|
|
|
199
175
|
const previousNode = stack.pop();
|
|
200
176
|
// @ts-ignore
|
|
201
177
|
context = stack[stack.length - 1] ?? ast;
|
|
178
|
+
// remove empty nodes
|
|
202
179
|
// @ts-ignore
|
|
203
180
|
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
181
|
+
// @ts-ignore
|
|
204
182
|
context.chi.pop();
|
|
205
183
|
continue;
|
|
206
184
|
}
|
|
@@ -250,25 +228,6 @@ async function doParse(iterator, options = {}) {
|
|
|
250
228
|
minify(ast, options, true, errors, false);
|
|
251
229
|
}
|
|
252
230
|
}
|
|
253
|
-
if (options.setParent) {
|
|
254
|
-
const nodes = [ast];
|
|
255
|
-
let node;
|
|
256
|
-
while ((node = nodes.shift())) {
|
|
257
|
-
// @ts-ignore
|
|
258
|
-
if (node.chi.length > 0) {
|
|
259
|
-
// @ts-ignore
|
|
260
|
-
for (const child of node.chi) {
|
|
261
|
-
if (child.parent != node) {
|
|
262
|
-
Object.defineProperty(child, 'parent', { ...definedPropertySettings, value: node });
|
|
263
|
-
}
|
|
264
|
-
if ('chi' in child && child.chi.length > 0) {
|
|
265
|
-
// @ts-ignore
|
|
266
|
-
nodes.push(child);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
231
|
const endTime = performance.now();
|
|
273
232
|
if (options.signal != null) {
|
|
274
233
|
options.signal.removeEventListener('abort', reject);
|
|
@@ -284,9 +243,18 @@ async function doParse(iterator, options = {}) {
|
|
|
284
243
|
total: `${(endTime - startTime).toFixed(2)}ms`
|
|
285
244
|
}
|
|
286
245
|
};
|
|
287
|
-
// });
|
|
288
246
|
}
|
|
289
|
-
|
|
247
|
+
function getLastNode(context) {
|
|
248
|
+
let i = context.chi.length;
|
|
249
|
+
while (i--) {
|
|
250
|
+
if ([EnumToken.CommentTokenType, EnumToken.CDOCOMMTokenType, EnumToken.WhitespaceTokenType].includes(context.chi[i].typ)) {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
return context.chi[i];
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
async function parseNode(results, context, stats, options, errors, src, map, rawTokens) {
|
|
290
258
|
let tokens = [];
|
|
291
259
|
for (const t of results) {
|
|
292
260
|
const node = getTokenType(t.token, t.hint);
|
|
@@ -341,28 +309,18 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
341
309
|
if (tokens[0]?.typ == EnumToken.AtRuleTokenType) {
|
|
342
310
|
const atRule = tokens.shift();
|
|
343
311
|
const position = map.get(atRule);
|
|
344
|
-
if (atRule.val == 'charset') {
|
|
345
|
-
if (position.ind > 0) {
|
|
346
|
-
errors.push({
|
|
347
|
-
action: 'drop',
|
|
348
|
-
message: 'doParse: invalid @charset',
|
|
349
|
-
location: { src, ...position }
|
|
350
|
-
});
|
|
351
|
-
return null;
|
|
352
|
-
}
|
|
353
|
-
if (options.removeCharset) {
|
|
354
|
-
return null;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
312
|
// @ts-ignore
|
|
358
313
|
while ([EnumToken.WhitespaceTokenType].includes(tokens[0]?.typ)) {
|
|
359
314
|
tokens.shift();
|
|
360
315
|
}
|
|
361
316
|
if (atRule.val == 'import') {
|
|
362
317
|
// only @charset and @layer are accepted before @import
|
|
318
|
+
// @ts-ignore
|
|
363
319
|
if (context.chi.length > 0) {
|
|
320
|
+
// @ts-ignore
|
|
364
321
|
let i = context.chi.length;
|
|
365
322
|
while (i--) {
|
|
323
|
+
// @ts-ignore
|
|
366
324
|
const type = context.chi[i].typ;
|
|
367
325
|
if (type == EnumToken.CommentNodeType) {
|
|
368
326
|
continue;
|
|
@@ -371,6 +329,7 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
371
329
|
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
372
330
|
return null;
|
|
373
331
|
}
|
|
332
|
+
// @ts-ignore
|
|
374
333
|
const name = context.chi[i].nam;
|
|
375
334
|
if (name != 'charset' && name != 'import' && name != 'layer') {
|
|
376
335
|
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
@@ -428,6 +387,7 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
428
387
|
stats.importedBytesIn += root.stats.bytesIn;
|
|
429
388
|
if (root.ast.chi.length > 0) {
|
|
430
389
|
// @todo - filter charset, layer and scope
|
|
390
|
+
// @ts-ignore
|
|
431
391
|
context.chi.push(...root.ast.chi);
|
|
432
392
|
}
|
|
433
393
|
if (root.errors.length > 0) {
|
|
@@ -445,16 +405,59 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
445
405
|
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
446
406
|
// allowed nesting at-rules
|
|
447
407
|
// there must be a top level rule in the stack
|
|
448
|
-
|
|
408
|
+
if (atRule.val == 'charset') {
|
|
409
|
+
let spaces = 0;
|
|
410
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/@charset
|
|
411
|
+
for (let k = 1; k < rawTokens.length; k++) {
|
|
412
|
+
if (rawTokens[k].hint == EnumToken.WhitespaceTokenType) {
|
|
413
|
+
spaces += rawTokens[k].len;
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
if (rawTokens[k].hint == EnumToken.CommentTokenType) {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
if (rawTokens[k].hint == EnumToken.CDOCOMMTokenType) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
if (spaces > 1) {
|
|
423
|
+
errors.push({
|
|
424
|
+
action: 'drop',
|
|
425
|
+
message: '@charset must have only one space',
|
|
426
|
+
// @ts-ignore
|
|
427
|
+
location: { src, ...(map.get(atRule) ?? position) }
|
|
428
|
+
});
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
if (rawTokens[k].hint != EnumToken.StringTokenType || rawTokens[k].token[0] != '"') {
|
|
432
|
+
errors.push({
|
|
433
|
+
action: 'drop',
|
|
434
|
+
message: '@charset expects a "<charset>"',
|
|
435
|
+
// @ts-ignore
|
|
436
|
+
location: { src, ...(map.get(atRule) ?? position) }
|
|
437
|
+
});
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
if (options.removeCharset) {
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
const t = parseAtRulePrelude(parseTokens(tokens, { minify: options.minify }), atRule);
|
|
447
|
+
const raw = t.reduce((acc, curr) => {
|
|
449
448
|
acc.push(renderToken(curr, { removeComments: true }));
|
|
450
449
|
return acc;
|
|
451
450
|
}, []);
|
|
452
451
|
const node = {
|
|
453
452
|
typ: EnumToken.AtRuleNodeType,
|
|
454
453
|
nam: renderToken(atRule, { removeComments: true }),
|
|
454
|
+
tokens: t,
|
|
455
455
|
val: raw.join('')
|
|
456
456
|
};
|
|
457
|
-
Object.
|
|
457
|
+
Object.defineProperties(node, {
|
|
458
|
+
tokens: { ...definedPropertySettings, enumerable: true, value: tokens.slice() },
|
|
459
|
+
raw: { ...definedPropertySettings, value: raw }
|
|
460
|
+
});
|
|
458
461
|
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
459
462
|
node.chi = [];
|
|
460
463
|
}
|
|
@@ -465,8 +468,41 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
465
468
|
if (options.sourcemap) {
|
|
466
469
|
node.loc = loc;
|
|
467
470
|
}
|
|
471
|
+
if (options.validation) {
|
|
472
|
+
let isValid = true;
|
|
473
|
+
if (node.nam == 'else') {
|
|
474
|
+
const prev = getLastNode(context);
|
|
475
|
+
if (prev != null && prev.typ == EnumToken.AtRuleNodeType && ['when', 'else'].includes(prev.nam)) {
|
|
476
|
+
if (prev.nam == 'else') {
|
|
477
|
+
isValid = Array.isArray(prev.tokens) && prev.tokens.length > 0;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
isValid = false;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
const valid = isValid ? validateAtRule(node, options, context) : {
|
|
485
|
+
valid: ValidationLevel.Drop,
|
|
486
|
+
node,
|
|
487
|
+
syntax: '@' + node.nam,
|
|
488
|
+
error: '@' + node.nam + ' not allowed here'};
|
|
489
|
+
if (valid.valid == ValidationLevel.Drop) {
|
|
490
|
+
errors.push({
|
|
491
|
+
action: 'drop',
|
|
492
|
+
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
493
|
+
// @ts-ignore
|
|
494
|
+
location: { src, ...(map.get(valid.node) ?? position) }
|
|
495
|
+
});
|
|
496
|
+
// @ts-ignore
|
|
497
|
+
node.typ = EnumToken.InvalidAtRuleTokenType;
|
|
498
|
+
}
|
|
499
|
+
else {
|
|
500
|
+
node.val = node.tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false, removeComments: true }), '');
|
|
501
|
+
}
|
|
502
|
+
}
|
|
468
503
|
// @ts-ignore
|
|
469
504
|
context.chi.push(node);
|
|
505
|
+
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
|
|
470
506
|
return delim.typ == EnumToken.BlockStartTokenType ? node : null;
|
|
471
507
|
}
|
|
472
508
|
else {
|
|
@@ -474,7 +510,6 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
474
510
|
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
475
511
|
const position = map.get(tokens[0]);
|
|
476
512
|
const uniq = new Map;
|
|
477
|
-
// const uniqTokens: Token[][] = [[]];
|
|
478
513
|
parseTokens(tokens, { minify: true }).reduce((acc, curr, index, array) => {
|
|
479
514
|
if (curr.typ == EnumToken.CommentTokenType) {
|
|
480
515
|
return acc;
|
|
@@ -514,21 +549,28 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
514
549
|
}, uniq);
|
|
515
550
|
const ruleType = context.typ == EnumToken.AtRuleNodeType && context.nam == 'keyframes' ? EnumToken.KeyFrameRuleNodeType : EnumToken.RuleNodeType;
|
|
516
551
|
if (ruleType == EnumToken.RuleNodeType) {
|
|
517
|
-
|
|
518
|
-
if (
|
|
519
|
-
|
|
520
|
-
|
|
552
|
+
parseSelector(tokens);
|
|
553
|
+
if (options.validation) {
|
|
554
|
+
// @ts-ignore
|
|
555
|
+
const valid = validateSelector(tokens, options, context);
|
|
556
|
+
if (valid.valid != ValidationLevel.Valid) {
|
|
557
|
+
const node = {
|
|
558
|
+
typ: EnumToken.InvalidRuleTokenType,
|
|
559
|
+
// @ts-ignore
|
|
560
|
+
sel: tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), ''),
|
|
561
|
+
chi: []
|
|
562
|
+
};
|
|
563
|
+
errors.push({
|
|
564
|
+
action: 'drop',
|
|
565
|
+
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
566
|
+
// @ts-ignore
|
|
567
|
+
location: { src, ...(map.get(valid.node) ?? position) }
|
|
568
|
+
});
|
|
521
569
|
// @ts-ignore
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
action: 'drop',
|
|
527
|
-
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
528
|
-
location: { src, ...(map.get(valid.node) ?? position) }
|
|
529
|
-
});
|
|
530
|
-
context.chi.push(node);
|
|
531
|
-
return node;
|
|
570
|
+
context.chi.push(node);
|
|
571
|
+
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
|
|
572
|
+
return node;
|
|
573
|
+
}
|
|
532
574
|
}
|
|
533
575
|
}
|
|
534
576
|
const node = {
|
|
@@ -536,6 +578,11 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
536
578
|
sel: [...uniq.keys()].join(','),
|
|
537
579
|
chi: []
|
|
538
580
|
};
|
|
581
|
+
Object.defineProperty(node, 'tokens', {
|
|
582
|
+
...definedPropertySettings,
|
|
583
|
+
enumerable: true,
|
|
584
|
+
value: tokens.slice()
|
|
585
|
+
});
|
|
539
586
|
let raw = [...uniq.values()];
|
|
540
587
|
Object.defineProperty(node, 'raw', {
|
|
541
588
|
enumerable: false,
|
|
@@ -552,18 +599,39 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
552
599
|
}
|
|
553
600
|
// @ts-ignore
|
|
554
601
|
context.chi.push(node);
|
|
602
|
+
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
|
|
555
603
|
return node;
|
|
556
604
|
}
|
|
557
605
|
else {
|
|
558
|
-
// declaration
|
|
559
|
-
// @ts-ignore
|
|
560
606
|
let name = null;
|
|
561
|
-
// @ts-ignore
|
|
562
607
|
let value = null;
|
|
563
608
|
for (let i = 0; i < tokens.length; i++) {
|
|
564
609
|
if (tokens[i].typ == EnumToken.CommentTokenType) {
|
|
565
610
|
continue;
|
|
566
611
|
}
|
|
612
|
+
if (name == null && [EnumToken.IdenTokenType, EnumToken.DashedIdenTokenType].includes(tokens[i].typ)) {
|
|
613
|
+
name = tokens.slice(0, i + 1);
|
|
614
|
+
}
|
|
615
|
+
else if (name != null && funcLike.concat([
|
|
616
|
+
EnumToken.LiteralTokenType,
|
|
617
|
+
EnumToken.IdenTokenType, EnumToken.DashedIdenTokenType,
|
|
618
|
+
EnumToken.PseudoClassTokenType, EnumToken.PseudoClassFuncTokenType
|
|
619
|
+
]).includes(tokens[i].typ)) {
|
|
620
|
+
if (tokens[i].val.charAt(0) == ':') {
|
|
621
|
+
Object.assign(tokens[i], getTokenType(tokens[i].val.slice(1)));
|
|
622
|
+
}
|
|
623
|
+
if ('chi' in tokens[i]) {
|
|
624
|
+
tokens[i].typ = EnumToken.FunctionTokenType;
|
|
625
|
+
}
|
|
626
|
+
value = parseTokens(tokens.slice(i), {
|
|
627
|
+
parseColor: options.parseColor,
|
|
628
|
+
src: options.src,
|
|
629
|
+
resolveUrls: options.resolveUrls,
|
|
630
|
+
resolve: options.resolve,
|
|
631
|
+
cwd: options.cwd
|
|
632
|
+
});
|
|
633
|
+
break;
|
|
634
|
+
}
|
|
567
635
|
if (tokens[i].typ == EnumToken.ColonTokenType) {
|
|
568
636
|
name = tokens.slice(0, i);
|
|
569
637
|
value = parseTokens(tokens.slice(i + 1), {
|
|
@@ -573,6 +641,7 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
573
641
|
resolve: options.resolve,
|
|
574
642
|
cwd: options.cwd
|
|
575
643
|
});
|
|
644
|
+
break;
|
|
576
645
|
}
|
|
577
646
|
}
|
|
578
647
|
if (name == null) {
|
|
@@ -606,15 +675,175 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
606
675
|
// @ts-ignore
|
|
607
676
|
val: value
|
|
608
677
|
};
|
|
609
|
-
const result =
|
|
678
|
+
const result = parseDeclarationNode(node, errors, src, position);
|
|
610
679
|
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
|
+
// }
|
|
611
698
|
// @ts-ignore
|
|
612
|
-
context.chi.push(
|
|
699
|
+
context.chi.push(result);
|
|
700
|
+
Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
|
|
613
701
|
}
|
|
614
702
|
return null;
|
|
615
703
|
}
|
|
616
704
|
}
|
|
617
705
|
}
|
|
706
|
+
/**
|
|
707
|
+
* parse at-rule prelude
|
|
708
|
+
* @param tokens
|
|
709
|
+
* @param atRule
|
|
710
|
+
*/
|
|
711
|
+
function parseAtRulePrelude(tokens, atRule) {
|
|
712
|
+
// @ts-ignore
|
|
713
|
+
for (const { value, parent } of walkValues(tokens, null, null, true)) {
|
|
714
|
+
if (value.typ == EnumToken.CommentTokenType ||
|
|
715
|
+
value.typ == EnumToken.WhitespaceTokenType ||
|
|
716
|
+
value.typ == EnumToken.CommaTokenType) {
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
if (atRule.val == 'page' && value.typ == EnumToken.PseudoClassTokenType) {
|
|
720
|
+
if ([':left', ':right', ':first', ':blank'].includes(value.val)) {
|
|
721
|
+
// @ts-ignore
|
|
722
|
+
value.typ = EnumToken.PseudoPageTokenType;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
if (atRule.val == 'layer') {
|
|
726
|
+
if (parent == null && value.typ == EnumToken.LiteralTokenType) {
|
|
727
|
+
if (value.val.charAt(0) == '.') {
|
|
728
|
+
if (isIdent(value.val.slice(1))) {
|
|
729
|
+
// @ts-ignore
|
|
730
|
+
value.typ = EnumToken.ClassSelectorTokenType;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
if (value.typ == EnumToken.IdenTokenType) {
|
|
736
|
+
if (parent == null && mediaTypes.some((t) => {
|
|
737
|
+
if (value.val.localeCompare(t, 'en', { sensitivity: 'base' }) == 0) {
|
|
738
|
+
// @ts-ignore
|
|
739
|
+
value.typ = EnumToken.MediaFeatureTokenType;
|
|
740
|
+
return true;
|
|
741
|
+
}
|
|
742
|
+
return false;
|
|
743
|
+
})) {
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
if (value.typ == EnumToken.IdenTokenType && 'and'.localeCompare(value.val, 'en', { sensitivity: 'base' }) == 0) {
|
|
747
|
+
// @ts-ignore
|
|
748
|
+
value.typ = EnumToken.MediaFeatureAndTokenType;
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
if (value.typ == EnumToken.IdenTokenType && 'or'.localeCompare(value.val, 'en', { sensitivity: 'base' }) == 0) {
|
|
752
|
+
// @ts-ignore
|
|
753
|
+
value.typ = EnumToken.MediaFeatureOrTokenType;
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
if (value.typ == EnumToken.IdenTokenType &&
|
|
757
|
+
['not', 'only'].some((t) => t.localeCompare(value.val, 'en', { sensitivity: 'base' }) == 0)) {
|
|
758
|
+
// @ts-ignore
|
|
759
|
+
const array = parent?.chi ?? tokens;
|
|
760
|
+
const startIndex = array.indexOf(value);
|
|
761
|
+
let index = startIndex + 1;
|
|
762
|
+
if (index == 0) {
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
while (index < array.length && [EnumToken.CommentTokenType, EnumToken.WhitespaceTokenType].includes(array[index].typ)) {
|
|
766
|
+
index++;
|
|
767
|
+
}
|
|
768
|
+
if (array[index] == null || array[index].typ == EnumToken.CommaTokenType) {
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
Object.assign(array[startIndex], {
|
|
772
|
+
typ: value.val.toLowerCase() == 'not' ? EnumToken.MediaFeatureNotTokenType : EnumToken.MediaFeatureOnlyTokenType,
|
|
773
|
+
val: array[index]
|
|
774
|
+
});
|
|
775
|
+
array.splice(startIndex + 1, index - startIndex);
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
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
|
+
let i;
|
|
783
|
+
let nameIndex = -1;
|
|
784
|
+
let valueIndex = -1;
|
|
785
|
+
const dashedIdent = value.typ == EnumToken.FunctionTokenType && value.val == 'style';
|
|
786
|
+
for (let i = 0; i < value.chi.length; i++) {
|
|
787
|
+
if (value.chi[i].typ == EnumToken.CommentTokenType || value.chi[i].typ == EnumToken.WhitespaceTokenType) {
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
if ((dashedIdent && value.chi[i].typ == EnumToken.DashedIdenTokenType) || value.chi[i].typ == EnumToken.IdenTokenType || value.chi[i].typ == EnumToken.FunctionTokenType || value.chi[i].typ == EnumToken.ColorTokenType) {
|
|
791
|
+
nameIndex = i;
|
|
792
|
+
}
|
|
793
|
+
break;
|
|
794
|
+
}
|
|
795
|
+
if (nameIndex == -1) {
|
|
796
|
+
continue;
|
|
797
|
+
}
|
|
798
|
+
for (let i = nameIndex + 1; i < value.chi.length; i++) {
|
|
799
|
+
if (value.chi[i].typ == EnumToken.CommentTokenType || value.chi[i].typ == EnumToken.WhitespaceTokenType) {
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
valueIndex = i;
|
|
803
|
+
break;
|
|
804
|
+
}
|
|
805
|
+
if (valueIndex == -1) {
|
|
806
|
+
// @ts-ignore
|
|
807
|
+
// value.chi[nameIndex].typ = EnumToken.MediaFeatureTokenType;
|
|
808
|
+
continue;
|
|
809
|
+
// return tokens;
|
|
810
|
+
}
|
|
811
|
+
for (i = nameIndex + 1; i < value.chi.length; i++) {
|
|
812
|
+
if ([
|
|
813
|
+
EnumToken.GtTokenType, EnumToken.LtTokenType,
|
|
814
|
+
EnumToken.GteTokenType, EnumToken.LteTokenType,
|
|
815
|
+
EnumToken.ColonTokenType
|
|
816
|
+
].includes(value.chi[valueIndex].typ)) {
|
|
817
|
+
const val = value.chi.splice(valueIndex, 1)[0];
|
|
818
|
+
const node = value.chi.splice(nameIndex, 1)[0];
|
|
819
|
+
// 'background'
|
|
820
|
+
// @ts-ignore
|
|
821
|
+
if (node.typ == EnumToken.ColorTokenType && node.kin == 'dpsys') {
|
|
822
|
+
// @ts-ignore
|
|
823
|
+
delete node.kin;
|
|
824
|
+
node.typ = EnumToken.IdenTokenType;
|
|
825
|
+
}
|
|
826
|
+
while (value.chi[0]?.typ == EnumToken.WhitespaceTokenType) {
|
|
827
|
+
value.chi.shift();
|
|
828
|
+
}
|
|
829
|
+
const t = [{
|
|
830
|
+
typ: EnumToken.MediaQueryConditionTokenType,
|
|
831
|
+
l: node,
|
|
832
|
+
op: { typ: val.typ },
|
|
833
|
+
r: value.chi.slice()
|
|
834
|
+
}];
|
|
835
|
+
value.chi.length = 0;
|
|
836
|
+
value.chi.push(...t);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return tokens;
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* parse selector
|
|
845
|
+
* @param tokens
|
|
846
|
+
*/
|
|
618
847
|
function parseSelector(tokens) {
|
|
619
848
|
for (const { value, previousValue, nextValue, parent } of walkValues(tokens)) {
|
|
620
849
|
if (value.typ == EnumToken.CommentTokenType ||
|
|
@@ -754,6 +983,15 @@ function parseSelector(tokens) {
|
|
|
754
983
|
}
|
|
755
984
|
return tokens;
|
|
756
985
|
}
|
|
986
|
+
// export async function parseDeclarations(src: string, options: ParserOptions = {}): Promise<AstDeclaration[]> {
|
|
987
|
+
//
|
|
988
|
+
// return doParse(`.x{${src}`, options).then((result: ParseResult) => <AstDeclaration[]>(<AstRule>result.ast.chi[0]).chi.filter(t => t.typ == EnumToken.DeclarationNodeType));
|
|
989
|
+
// }
|
|
990
|
+
/**
|
|
991
|
+
* parse string
|
|
992
|
+
* @param src
|
|
993
|
+
* @param options
|
|
994
|
+
*/
|
|
757
995
|
function parseString(src, options = { location: false }) {
|
|
758
996
|
return parseTokens([...tokenize(src)].map(t => {
|
|
759
997
|
const token = getTokenType(t.token, t.hint);
|
|
@@ -764,9 +1002,6 @@ function parseString(src, options = { location: false }) {
|
|
|
764
1002
|
}));
|
|
765
1003
|
}
|
|
766
1004
|
function getTokenType(val, hint) {
|
|
767
|
-
// if (val === '' && hint == null) {
|
|
768
|
-
// throw new Error('empty string?');
|
|
769
|
-
// }
|
|
770
1005
|
if (hint != null) {
|
|
771
1006
|
return enumTokenHints.has(hint) ? { typ: hint } : { typ: hint, val };
|
|
772
1007
|
}
|
|
@@ -838,7 +1073,7 @@ function getTokenType(val, hint) {
|
|
|
838
1073
|
chi: []
|
|
839
1074
|
};
|
|
840
1075
|
}
|
|
841
|
-
if (['linear-gradient', 'radial-gradient', 'repeating-linear-gradient', 'repeating-radial-gradient', 'conic-gradient', 'image', 'image-set', 'element', 'cross-fade'].includes(val)) {
|
|
1076
|
+
if (['linear-gradient', 'radial-gradient', 'repeating-linear-gradient', 'repeating-radial-gradient', 'conic-gradient', 'image', 'image-set', 'element', 'cross-fade', 'paint'].includes(val)) {
|
|
842
1077
|
return {
|
|
843
1078
|
typ: EnumToken.ImageFunctionTokenType,
|
|
844
1079
|
val,
|
|
@@ -938,17 +1173,28 @@ function getTokenType(val, hint) {
|
|
|
938
1173
|
val
|
|
939
1174
|
};
|
|
940
1175
|
}
|
|
1176
|
+
/**
|
|
1177
|
+
* parse token list
|
|
1178
|
+
* @param tokens
|
|
1179
|
+
* @param options
|
|
1180
|
+
*/
|
|
941
1181
|
function parseTokens(tokens, options = {}) {
|
|
942
1182
|
for (let i = 0; i < tokens.length; i++) {
|
|
943
1183
|
const t = tokens[i];
|
|
1184
|
+
if (t.typ == EnumToken.PseudoClassFuncTokenType) {
|
|
1185
|
+
if (t.val.slice(1) in webkitPseudoAliasMap) {
|
|
1186
|
+
t.val = ':' + webkitPseudoAliasMap[t.val.slice(1)];
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
else if (t.typ == EnumToken.PseudoClassTokenType) {
|
|
1190
|
+
if (t.val.slice(1) in webkitPseudoAliasMap) {
|
|
1191
|
+
t.val = ':' + webkitPseudoAliasMap[t.val.slice(1)];
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
944
1194
|
if (t.typ == EnumToken.WhitespaceTokenType && ((i == 0 ||
|
|
945
1195
|
i + 1 == tokens.length ||
|
|
946
1196
|
[EnumToken.CommaTokenType, EnumToken.GteTokenType, EnumToken.LteTokenType, EnumToken.ColumnCombinatorTokenType].includes(tokens[i + 1].typ)) ||
|
|
947
|
-
(i > 0 &&
|
|
948
|
-
// tokens[i + 1]?.typ != Literal ||
|
|
949
|
-
// funcLike.includes(tokens[i - 1].typ) &&
|
|
950
|
-
// !['var', 'calc'].includes((<FunctionToken>tokens[i - 1]).val)))) &&
|
|
951
|
-
trimWhiteSpace.includes(tokens[i - 1].typ)))) {
|
|
1197
|
+
(i > 0 && trimWhiteSpace.includes(tokens[i - 1].typ)))) {
|
|
952
1198
|
tokens.splice(i--, 1);
|
|
953
1199
|
continue;
|
|
954
1200
|
}
|
|
@@ -1040,7 +1286,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1040
1286
|
}
|
|
1041
1287
|
}
|
|
1042
1288
|
else if ([
|
|
1043
|
-
EnumToken.DashMatchTokenType, EnumToken.StartMatchTokenType, EnumToken.ContainMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType
|
|
1289
|
+
EnumToken.DashMatchTokenType, EnumToken.StartMatchTokenType, EnumToken.ContainMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DelimTokenType
|
|
1044
1290
|
].includes(t.chi[m].typ)) {
|
|
1045
1291
|
let upper = m;
|
|
1046
1292
|
let lower = m;
|
|
@@ -1070,9 +1316,15 @@ function parseTokens(tokens, options = {}) {
|
|
|
1070
1316
|
Object.assign(val, { typ: EnumToken.IdenTokenType, val: slice });
|
|
1071
1317
|
}
|
|
1072
1318
|
}
|
|
1319
|
+
// @ts-ignore
|
|
1320
|
+
const typ = t.chi[m].typ;
|
|
1321
|
+
// @ts-ignore
|
|
1073
1322
|
t.chi[m] = {
|
|
1074
1323
|
typ: EnumToken.MatchExpressionTokenType,
|
|
1075
|
-
op:
|
|
1324
|
+
op: {
|
|
1325
|
+
// @ts-ignore
|
|
1326
|
+
typ: typ == EnumToken.DelimTokenType ? EnumToken.EqualMatchTokenType : typ
|
|
1327
|
+
},
|
|
1076
1328
|
l: t.chi[lower],
|
|
1077
1329
|
r: t.chi[upper]
|
|
1078
1330
|
};
|
|
@@ -1141,7 +1393,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1141
1393
|
// @ts-ignore
|
|
1142
1394
|
parseTokens(t.chi, options);
|
|
1143
1395
|
}
|
|
1144
|
-
if (t.typ == EnumToken.FunctionTokenType && t.val
|
|
1396
|
+
if (t.typ == EnumToken.FunctionTokenType && mathFuncs.includes(t.val)) {
|
|
1145
1397
|
for (const { value, parent } of walkValues(t.chi)) {
|
|
1146
1398
|
if (value.typ == EnumToken.WhitespaceTokenType) {
|
|
1147
1399
|
const p = (parent ?? t);
|