@tbela99/css-parser 1.3.3 → 1.3.4
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 +7 -0
- package/README.md +20 -17
- package/dist/index-umd-web.js +1031 -571
- package/dist/index.cjs +1031 -566
- package/dist/index.d.ts +247 -171
- package/dist/lib/ast/expand.js +5 -10
- package/dist/lib/ast/features/calc.js +3 -2
- package/dist/lib/ast/features/inlinecssvariables.js +5 -3
- package/dist/lib/ast/features/prefix.js +1 -1
- package/dist/lib/ast/features/shorthand.js +1 -0
- package/dist/lib/ast/features/transform.js +13 -19
- package/dist/lib/ast/minify.js +5 -2
- package/dist/lib/ast/transform/compute.js +2 -4
- package/dist/lib/ast/transform/matrix.js +20 -20
- package/dist/lib/ast/transform/minify.js +105 -12
- package/dist/lib/ast/transform/rotate.js +11 -11
- package/dist/lib/ast/transform/scale.js +6 -6
- package/dist/lib/ast/transform/skew.js +4 -4
- package/dist/lib/ast/transform/translate.js +3 -3
- package/dist/lib/ast/transform/utils.js +30 -37
- package/dist/lib/ast/types.js +14 -2
- package/dist/lib/ast/walk.js +61 -49
- package/dist/lib/fs/resolve.js +6 -3
- package/dist/lib/parser/declaration/list.js +3 -1
- package/dist/lib/parser/parse.js +345 -305
- package/dist/lib/parser/tokenize.js +11 -13
- package/dist/lib/renderer/render.js +2 -2
- package/dist/lib/syntax/syntax.js +36 -18
- package/dist/lib/validation/at-rules/container.js +11 -0
- package/dist/lib/validation/at-rules/counter-style.js +11 -0
- package/dist/lib/validation/at-rules/font-feature-values.js +11 -0
- package/dist/lib/validation/at-rules/keyframes.js +11 -0
- package/dist/lib/validation/at-rules/layer.js +11 -0
- package/dist/lib/validation/at-rules/media.js +11 -0
- package/dist/lib/validation/at-rules/page-margin-box.js +11 -0
- package/dist/lib/validation/at-rules/page.js +11 -0
- package/dist/lib/validation/at-rules/supports.js +11 -0
- package/dist/lib/validation/at-rules/when.js +11 -0
- package/dist/lib/validation/config.js +0 -2
- package/dist/lib/validation/config.json.js +21 -1
- package/dist/lib/validation/parser/parse.js +53 -2
- package/dist/lib/validation/syntax.js +199 -36
- package/dist/node.js +17 -12
- package/dist/web.js +11 -11
- package/package.json +6 -3
- package/dist/lib/validation/parser/types.js +0 -54
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { isIdentStart, isIdent, isIdentColor, mathFuncs, isColor, parseColor, isPseudo, pseudoElements, isAtKeyword, isFunction, isNumber, isPercentage,
|
|
1
|
+
import { isIdentStart, isIdent, isIdentColor, mathFuncs, isColor, parseColor, isPseudo, pseudoElements, isAtKeyword, isFunction, isNumber, isPercentage, parseDimension, isHexColor, isHash, mediaTypes } from '../syntax/syntax.js';
|
|
2
2
|
import { EnumToken, ColorType, ValidationLevel, SyntaxValidationResult } from '../ast/types.js';
|
|
3
|
-
import {
|
|
4
|
-
import { walkValues,
|
|
3
|
+
import { definedPropertySettings, minify, combinators } from '../ast/minify.js';
|
|
4
|
+
import { walkValues, WalkerEvent, walk, WalkerOptionEnum } from '../ast/walk.js';
|
|
5
5
|
import { expand } from '../ast/expand.js';
|
|
6
6
|
import './utils/config.js';
|
|
7
7
|
import { parseDeclarationNode } from './utils/declaration.js';
|
|
@@ -11,14 +11,13 @@ import { funcLike, timingFunc, timelineFunc, COLORS_NAMES, systemColors, depreca
|
|
|
11
11
|
import { buildExpression } from '../ast/math/expression.js';
|
|
12
12
|
import { tokenize, tokenizeStream } from './tokenize.js';
|
|
13
13
|
import '../validation/config.js';
|
|
14
|
-
import '../validation/parser/types.js';
|
|
15
14
|
import '../validation/parser/parse.js';
|
|
16
15
|
import { validateSelector } from '../validation/selector.js';
|
|
17
16
|
import { validateAtRule } from '../validation/atrule.js';
|
|
18
17
|
import { splitTokenList } from '../validation/utils/list.js';
|
|
19
18
|
import '../validation/syntaxes/complex-selector.js';
|
|
20
19
|
import { validateKeyframeSelector } from '../validation/syntaxes/keyframe-selector.js';
|
|
21
|
-
import { evaluateSyntax } from '../validation/syntax.js';
|
|
20
|
+
import { isNodeAllowedInContext, evaluateSyntax } from '../validation/syntax.js';
|
|
22
21
|
import { validateAtRuleKeyframes } from '../validation/at-rules/keyframes.js';
|
|
23
22
|
|
|
24
23
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
@@ -43,12 +42,13 @@ function normalizeVisitorKeyName(keyName) {
|
|
|
43
42
|
return keyName.replace(/-([a-z])/g, (all, one) => one.toUpperCase());
|
|
44
43
|
}
|
|
45
44
|
function replaceToken(parent, value, replacement) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
for (const node of (Array.isArray(replacement) ? replacement : [replacement])) {
|
|
46
|
+
if ('parent' in value && value.parent != node.parent) {
|
|
47
|
+
Object.defineProperty(node, 'parent', {
|
|
48
|
+
...definedPropertySettings,
|
|
49
|
+
value: value.parent
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
52
|
}
|
|
53
53
|
if (parent.typ == EnumToken.BinaryExpressionTokenType) {
|
|
54
54
|
if (parent.l == value) {
|
|
@@ -59,14 +59,12 @@ function replaceToken(parent, value, replacement) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
62
|
-
// @ts-ignore
|
|
63
62
|
const target = 'val' in parent && Array.isArray(parent.val) ? parent.val : parent.chi;
|
|
64
63
|
// @ts-ignore
|
|
65
64
|
const index = target.indexOf(value);
|
|
66
65
|
if (index == -1) {
|
|
67
66
|
return;
|
|
68
67
|
}
|
|
69
|
-
// @ts-ignore
|
|
70
68
|
target.splice(index, 1, ...(Array.isArray(replacement) ? replacement : [replacement]));
|
|
71
69
|
}
|
|
72
70
|
}
|
|
@@ -119,6 +117,8 @@ async function doParse(iter, options = {}) {
|
|
|
119
117
|
const stats = {
|
|
120
118
|
src: options.src ?? '',
|
|
121
119
|
bytesIn: 0,
|
|
120
|
+
nodesCount: 0,
|
|
121
|
+
tokensCount: 0,
|
|
122
122
|
importedBytesIn: 0,
|
|
123
123
|
parse: `0ms`,
|
|
124
124
|
minify: `0ms`,
|
|
@@ -147,14 +147,107 @@ async function doParse(iter, options = {}) {
|
|
|
147
147
|
src: ''
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
|
-
let
|
|
151
|
-
let
|
|
150
|
+
let valuesHandlers;
|
|
151
|
+
let preValuesHandlers;
|
|
152
|
+
let postValuesHandlers;
|
|
153
|
+
let preVisitorsHandlersMap;
|
|
154
|
+
let visitorsHandlersMap;
|
|
155
|
+
let postVisitorsHandlersMap;
|
|
152
156
|
const rawTokens = [];
|
|
153
157
|
const imports = [];
|
|
158
|
+
let item;
|
|
159
|
+
let node;
|
|
154
160
|
// @ts-ignore ignore error
|
|
155
161
|
let isAsync = typeof iter[Symbol.asyncIterator] === 'function';
|
|
162
|
+
if (options.visitor != null) {
|
|
163
|
+
valuesHandlers = new Map;
|
|
164
|
+
preValuesHandlers = new Map;
|
|
165
|
+
postValuesHandlers = new Map;
|
|
166
|
+
preVisitorsHandlersMap = new Map;
|
|
167
|
+
visitorsHandlersMap = new Map;
|
|
168
|
+
postVisitorsHandlersMap = new Map;
|
|
169
|
+
const visitors = Object.entries(options.visitor);
|
|
170
|
+
let key;
|
|
171
|
+
let value;
|
|
172
|
+
let i;
|
|
173
|
+
for (i = 0; i < visitors.length; i++) {
|
|
174
|
+
key = visitors[i][0];
|
|
175
|
+
value = visitors[i][1];
|
|
176
|
+
if (Number.isInteger(+key)) {
|
|
177
|
+
visitors.splice(i + 1, 0, ...Object.entries(value));
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (Array.isArray(value)) {
|
|
181
|
+
// @ts-ignore
|
|
182
|
+
visitors.splice(i + 1, 0, ...value.map((item) => [key, item]));
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (key in EnumToken) {
|
|
186
|
+
if (typeof value == 'function') {
|
|
187
|
+
if (!valuesHandlers.has(EnumToken[key])) {
|
|
188
|
+
valuesHandlers.set(EnumToken[key], []);
|
|
189
|
+
}
|
|
190
|
+
valuesHandlers.get(EnumToken[key]).push(value);
|
|
191
|
+
}
|
|
192
|
+
else if (typeof value == 'object' && 'type' in value && 'handler' in value && value.type in WalkerEvent) {
|
|
193
|
+
if (value.type == WalkerEvent.Enter) {
|
|
194
|
+
if (!preValuesHandlers.has(EnumToken[key])) {
|
|
195
|
+
preValuesHandlers.set(EnumToken[key], []);
|
|
196
|
+
}
|
|
197
|
+
preValuesHandlers.get(EnumToken[key]).push(value.handler);
|
|
198
|
+
}
|
|
199
|
+
else if (value.type == WalkerEvent.Leave) {
|
|
200
|
+
if (!postValuesHandlers.has(EnumToken[key])) {
|
|
201
|
+
postValuesHandlers.set(EnumToken[key], []);
|
|
202
|
+
}
|
|
203
|
+
postValuesHandlers.get(EnumToken[key]).push(value.handler);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
errors.push({ action: 'ignore', message: `doParse: visitor.${key} is not a valid key name` });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
else if (['Declaration', 'Rule', 'AtRule', 'KeyframesRule', 'KeyframesAtRule'].includes(key)) {
|
|
211
|
+
if (typeof value == 'function') {
|
|
212
|
+
if (!visitorsHandlersMap.has(key)) {
|
|
213
|
+
visitorsHandlersMap.set(key, []);
|
|
214
|
+
}
|
|
215
|
+
visitorsHandlersMap.get(key).push(value);
|
|
216
|
+
}
|
|
217
|
+
else if (typeof value == 'object') {
|
|
218
|
+
if ('type' in value && 'handler' in value && value.type in WalkerEvent) {
|
|
219
|
+
if (value.type == WalkerEvent.Enter) {
|
|
220
|
+
if (!preVisitorsHandlersMap.has(key)) {
|
|
221
|
+
preVisitorsHandlersMap.set(key, []);
|
|
222
|
+
}
|
|
223
|
+
preVisitorsHandlersMap.get(key).push(value.handler);
|
|
224
|
+
}
|
|
225
|
+
else if (value.type == WalkerEvent.Leave) {
|
|
226
|
+
if (!postVisitorsHandlersMap.has(key)) {
|
|
227
|
+
postVisitorsHandlersMap.set(key, []);
|
|
228
|
+
}
|
|
229
|
+
postVisitorsHandlersMap.get(key).push(value.handler);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
if (!visitorsHandlersMap.has(key)) {
|
|
234
|
+
visitorsHandlersMap.set(key, []);
|
|
235
|
+
}
|
|
236
|
+
visitorsHandlersMap.get(key).push(value);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
errors.push({ action: 'ignore', message: `doParse: visitor.${key} is not a valid key name` });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
errors.push({ action: 'ignore', message: `doParse: visitor.${key} is not a valid key name` });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
156
248
|
while (item = isAsync ? (await iter.next()).value : iter.next().value) {
|
|
157
249
|
stats.bytesIn = item.bytesIn;
|
|
250
|
+
stats.tokensCount++;
|
|
158
251
|
rawTokens.push(item);
|
|
159
252
|
if (item.hint != null && BadTokensTypes.includes(item.hint)) {
|
|
160
253
|
const node = getTokenType(item.token, item.hint);
|
|
@@ -182,7 +275,7 @@ async function doParse(iter, options = {}) {
|
|
|
182
275
|
ast.loc.end = item.end;
|
|
183
276
|
}
|
|
184
277
|
if (item.token == ';' || item.token == '{') {
|
|
185
|
-
node = parseNode(tokens, context, options, errors, src, map, rawTokens);
|
|
278
|
+
node = parseNode(tokens, context, options, errors, src, map, rawTokens, stats);
|
|
186
279
|
rawTokens.length = 0;
|
|
187
280
|
if (node != null) {
|
|
188
281
|
if ('chi' in node) {
|
|
@@ -226,7 +319,7 @@ async function doParse(iter, options = {}) {
|
|
|
226
319
|
map = new Map;
|
|
227
320
|
}
|
|
228
321
|
else if (item.token == '}') {
|
|
229
|
-
parseNode(tokens, context, options, errors, src, map, rawTokens);
|
|
322
|
+
parseNode(tokens, context, options, errors, src, map, rawTokens, stats);
|
|
230
323
|
rawTokens.length = 0;
|
|
231
324
|
if (context.loc != null) {
|
|
232
325
|
context.loc.end = item.end;
|
|
@@ -247,7 +340,7 @@ async function doParse(iter, options = {}) {
|
|
|
247
340
|
}
|
|
248
341
|
}
|
|
249
342
|
if (tokens.length > 0) {
|
|
250
|
-
node = parseNode(tokens, context, options, errors, src, map, rawTokens);
|
|
343
|
+
node = parseNode(tokens, context, options, errors, src, map, rawTokens, stats);
|
|
251
344
|
rawTokens.length = 0;
|
|
252
345
|
if (node != null) {
|
|
253
346
|
if (node.typ == EnumToken.AtRuleNodeType && node.nam == 'import') {
|
|
@@ -310,228 +403,153 @@ async function doParse(iter, options = {}) {
|
|
|
310
403
|
if (options.expandNestingRules) {
|
|
311
404
|
ast = expand(ast);
|
|
312
405
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const postValuesHandlers = new Map;
|
|
316
|
-
const preVisitorsHandlersMap = new Map;
|
|
317
|
-
const visitorsHandlersMap = new Map;
|
|
318
|
-
const postVisitorsHandlersMap = new Map;
|
|
319
|
-
const allValuesHandlers = [];
|
|
406
|
+
let replacement;
|
|
407
|
+
let callable;
|
|
320
408
|
if (options.visitor != null) {
|
|
321
|
-
for (const
|
|
322
|
-
if (
|
|
323
|
-
if (
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
409
|
+
for (const result of walk(ast)) {
|
|
410
|
+
if (valuesHandlers.size > 0 || preVisitorsHandlersMap.size > 0 || visitorsHandlersMap.size > 0 || postVisitorsHandlersMap.size > 0) {
|
|
411
|
+
if ((result.node.typ == EnumToken.DeclarationNodeType &&
|
|
412
|
+
(preVisitorsHandlersMap.has('Declaration') || visitorsHandlersMap.has('Declaration') || postVisitorsHandlersMap.has('Declaration'))) ||
|
|
413
|
+
(result.node.typ == EnumToken.AtRuleNodeType && (preVisitorsHandlersMap.has('AtRule') || visitorsHandlersMap.has('AtRule') || postVisitorsHandlersMap.has('AtRule'))) ||
|
|
414
|
+
(result.node.typ == EnumToken.KeyframesAtRuleNodeType && (preVisitorsHandlersMap.has('KeyframesAtRule') || visitorsHandlersMap.has('KeyframesAtRule') || postVisitorsHandlersMap.has('KeyframesAtRule')))) {
|
|
415
|
+
const handlers = [];
|
|
416
|
+
const key = result.node.typ == EnumToken.DeclarationNodeType ? 'Declaration' : result.node.typ == EnumToken.AtRuleNodeType ? 'AtRule' : 'KeyframesAtRule';
|
|
417
|
+
if (preVisitorsHandlersMap.has(key)) {
|
|
418
|
+
// @ts-ignore
|
|
419
|
+
handlers.push(...preVisitorsHandlersMap.get(key));
|
|
329
420
|
}
|
|
330
|
-
|
|
331
|
-
|
|
421
|
+
if (visitorsHandlersMap.has(key)) {
|
|
422
|
+
// @ts-ignore
|
|
423
|
+
handlers.push(...visitorsHandlersMap.get(key));
|
|
332
424
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
else if (typeof value == 'object') {
|
|
343
|
-
if ('type' in value && 'handler' in value && value.type in WalkerValueEvent) {
|
|
344
|
-
if (WalkerValueEvent[value.type] == WalkerValueEvent.Enter) {
|
|
345
|
-
preVisitorsHandlersMap.set(key, value.handler);
|
|
425
|
+
if (postVisitorsHandlersMap.has(key)) {
|
|
426
|
+
// @ts-ignore
|
|
427
|
+
handlers.push(...postVisitorsHandlersMap.get(key));
|
|
428
|
+
}
|
|
429
|
+
let node = result.node;
|
|
430
|
+
for (const handler of handlers) {
|
|
431
|
+
callable = typeof handler == 'function' ? handler : handler[normalizeVisitorKeyName(node.typ == EnumToken.DeclarationNodeType || node.typ == EnumToken.AtRuleNodeType ? node.nam : node.val)];
|
|
432
|
+
if (callable == null) {
|
|
433
|
+
continue;
|
|
346
434
|
}
|
|
347
|
-
|
|
348
|
-
|
|
435
|
+
replacement = callable(node, result.parent);
|
|
436
|
+
if (replacement == null) {
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
isAsync = replacement instanceof Promise || Object.getPrototypeOf(replacement).constructor.name == 'AsyncFunction';
|
|
440
|
+
if (replacement) {
|
|
441
|
+
replacement = await replacement;
|
|
442
|
+
}
|
|
443
|
+
if (replacement == null || replacement == node) {
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
// @ts-ignore
|
|
447
|
+
node = replacement;
|
|
448
|
+
//
|
|
449
|
+
if (Array.isArray(node)) {
|
|
450
|
+
break;
|
|
349
451
|
}
|
|
350
452
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
else {
|
|
356
|
-
console.warn(`doParse: visitor.${key} is not a valid key name`);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
else {
|
|
360
|
-
console.warn(`doParse: visitor.${key} is not a valid key name`);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
if (preValuesHandlers.size > 0) {
|
|
364
|
-
allValuesHandlers.push(preValuesHandlers);
|
|
365
|
-
}
|
|
366
|
-
if (valuesHandlers.size > 0) {
|
|
367
|
-
allValuesHandlers.push(valuesHandlers);
|
|
368
|
-
}
|
|
369
|
-
if (postValuesHandlers.size > 0) {
|
|
370
|
-
allValuesHandlers.push(postValuesHandlers);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
for (const result of walk(ast)) {
|
|
374
|
-
// if (result.parent != null && !isNodeAllowedInContext(result.node, result.parent as AstNode)) {
|
|
375
|
-
//
|
|
376
|
-
// errors.push({
|
|
377
|
-
// action: 'drop',
|
|
378
|
-
// message: `${EnumToken[result.parent.typ]}: child ${EnumToken[result.node.typ]}${result.node.typ == EnumToken.DeclarationNodeType ? ` '${(result.node as AstDeclaration).nam}'` : result.node.typ == EnumToken.AtRuleNodeType || result.node.typ == EnumToken.KeyframesAtRuleNodeType ? ` '@${(result.node as AstAtRule).nam}'` : ''} not allowed in context${result.parent.typ == EnumToken.AtRuleNodeType ? ` '@${(result.parent as AstAtRule).nam}'` : result.parent.typ == EnumToken.StyleSheetNodeType ? ` 'stylesheet'` : ''}`,
|
|
379
|
-
// // @ts-ignore
|
|
380
|
-
// location: result.node.loc ?? map.get(result.node ) ?? null
|
|
381
|
-
// });
|
|
382
|
-
//
|
|
383
|
-
// // @ts-ignore
|
|
384
|
-
// removeNode(result.node, result.parent as AstNode);
|
|
385
|
-
// continue;
|
|
386
|
-
// }
|
|
387
|
-
if (allValuesHandlers.length > 0 || preVisitorsHandlersMap.size > 0 || visitorsHandlersMap.size > 0 || postVisitorsHandlersMap.size > 0) {
|
|
388
|
-
if ((result.node.typ == EnumToken.DeclarationNodeType &&
|
|
389
|
-
(preVisitorsHandlersMap.has('Declaration') || visitorsHandlersMap.has('Declaration') || postVisitorsHandlersMap.has('Declaration'))) ||
|
|
390
|
-
(result.node.typ == EnumToken.AtRuleNodeType && (preVisitorsHandlersMap.has('AtRule') || visitorsHandlersMap.has('AtRule') || postVisitorsHandlersMap.has('AtRule'))) ||
|
|
391
|
-
(result.node.typ == EnumToken.KeyframesAtRuleNodeType && (preVisitorsHandlersMap.has('KeyframesAtRule') || visitorsHandlersMap.has('KeyframesAtRule') || postVisitorsHandlersMap.has('KeyframesAtRule')))) {
|
|
392
|
-
const handlers = [];
|
|
393
|
-
const key = result.node.typ == EnumToken.DeclarationNodeType ? 'Declaration' : result.node.typ == EnumToken.AtRuleNodeType ? 'AtRule' : 'KeyframesAtRule';
|
|
394
|
-
if (preVisitorsHandlersMap.has(key)) {
|
|
395
|
-
// @ts-ignore
|
|
396
|
-
handlers.push(preVisitorsHandlersMap.get(key));
|
|
397
|
-
}
|
|
398
|
-
if (visitorsHandlersMap.has(key)) {
|
|
399
|
-
// @ts-ignore
|
|
400
|
-
handlers.push(visitorsHandlersMap.get(key));
|
|
401
|
-
}
|
|
402
|
-
if (postVisitorsHandlersMap.has(key)) {
|
|
403
|
-
// @ts-ignore
|
|
404
|
-
handlers.push(postVisitorsHandlersMap.get(key));
|
|
405
|
-
}
|
|
406
|
-
let callable;
|
|
407
|
-
let node = result.node;
|
|
408
|
-
for (const handler of handlers) {
|
|
409
|
-
callable = typeof handler == 'function' ? handler : handler[normalizeVisitorKeyName(node.typ == EnumToken.DeclarationNodeType || node.typ == EnumToken.AtRuleNodeType ? node.nam : node.val)];
|
|
410
|
-
if (callable == null) {
|
|
411
|
-
continue;
|
|
412
|
-
}
|
|
413
|
-
let replacement = callable(node, result.parent);
|
|
414
|
-
if (replacement == null) {
|
|
415
|
-
continue;
|
|
416
|
-
}
|
|
417
|
-
isAsync = replacement instanceof Promise || Object.getPrototypeOf(replacement).constructor.name == 'AsyncFunction';
|
|
418
|
-
if (replacement) {
|
|
419
|
-
replacement = await replacement;
|
|
420
|
-
}
|
|
421
|
-
if (replacement == null || replacement == node) {
|
|
422
|
-
continue;
|
|
423
|
-
}
|
|
424
|
-
// @ts-ignore
|
|
425
|
-
node = replacement;
|
|
426
|
-
//
|
|
427
|
-
if (Array.isArray(node)) {
|
|
428
|
-
break;
|
|
453
|
+
if (node != result.node) {
|
|
454
|
+
// @ts-ignore
|
|
455
|
+
replaceToken(result.parent, result.node, node);
|
|
429
456
|
}
|
|
430
457
|
}
|
|
431
|
-
if (node
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
(result.node.typ == EnumToken.KeyFramesRuleNodeType && (preVisitorsHandlersMap.has('KeyframesRule') || visitorsHandlersMap.has('KeyframesRule') || postVisitorsHandlersMap.has('KeyframesRule')))) {
|
|
438
|
-
const handlers = [];
|
|
439
|
-
const key = result.node.typ == EnumToken.RuleNodeType ? 'Rule' : 'KeyframesRule';
|
|
440
|
-
if (preVisitorsHandlersMap.has(key)) {
|
|
441
|
-
// @ts-ignore
|
|
442
|
-
handlers.push(preVisitorsHandlersMap.get(key));
|
|
443
|
-
}
|
|
444
|
-
if (visitorsHandlersMap.has(key)) {
|
|
445
|
-
// @ts-ignore
|
|
446
|
-
handlers.push(visitorsHandlersMap.get(key));
|
|
447
|
-
}
|
|
448
|
-
if (postVisitorsHandlersMap.has(key)) {
|
|
449
|
-
// @ts-ignore
|
|
450
|
-
handlers.push(postVisitorsHandlersMap.get(key));
|
|
451
|
-
}
|
|
452
|
-
let node = result.node;
|
|
453
|
-
for (const callable of handlers) {
|
|
454
|
-
// @ts-ignore
|
|
455
|
-
let replacement = callable(node, result.parent);
|
|
456
|
-
if (replacement == null) {
|
|
457
|
-
continue;
|
|
458
|
+
else if ((result.node.typ == EnumToken.RuleNodeType && (preVisitorsHandlersMap.has('Rule') || visitorsHandlersMap.has('Rule') || postVisitorsHandlersMap.has('Rule'))) ||
|
|
459
|
+
(result.node.typ == EnumToken.KeyFramesRuleNodeType && (preVisitorsHandlersMap.has('KeyframesRule') || visitorsHandlersMap.has('KeyframesRule') || postVisitorsHandlersMap.has('KeyframesRule')))) {
|
|
460
|
+
const handlers = [];
|
|
461
|
+
const key = result.node.typ == EnumToken.RuleNodeType ? 'Rule' : 'KeyframesRule';
|
|
462
|
+
if (preVisitorsHandlersMap.has(key)) {
|
|
463
|
+
handlers.push(...preVisitorsHandlersMap.get(key));
|
|
458
464
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
replacement = await replacement;
|
|
465
|
+
if (visitorsHandlersMap.has(key)) {
|
|
466
|
+
handlers.push(...visitorsHandlersMap.get(key));
|
|
462
467
|
}
|
|
463
|
-
if (
|
|
464
|
-
|
|
468
|
+
if (postVisitorsHandlersMap.has(key)) {
|
|
469
|
+
handlers.push(...postVisitorsHandlersMap.get(key));
|
|
465
470
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
if (Array.isArray(node)) {
|
|
470
|
-
break;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
// @ts-ignore
|
|
474
|
-
if (node != result.node) {
|
|
475
|
-
// @ts-ignore
|
|
476
|
-
replaceToken(result.parent, result.node, node);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
else if (allValuesHandlers.length > 0) {
|
|
480
|
-
let callable;
|
|
481
|
-
let node = null;
|
|
482
|
-
node = result.node;
|
|
483
|
-
for (const valueHandler of allValuesHandlers) {
|
|
484
|
-
if (valueHandler.has(node.typ)) {
|
|
485
|
-
callable = valueHandler.get(node.typ);
|
|
486
|
-
let replacement = callable(node, result.parent);
|
|
471
|
+
let node = result.node;
|
|
472
|
+
for (const callable of handlers) {
|
|
473
|
+
replacement = callable(node, result.parent);
|
|
487
474
|
if (replacement == null) {
|
|
488
475
|
continue;
|
|
489
476
|
}
|
|
490
477
|
isAsync = replacement instanceof Promise || Object.getPrototypeOf(replacement).constructor.name == 'AsyncFunction';
|
|
491
|
-
if (
|
|
478
|
+
if (replacement) {
|
|
492
479
|
replacement = await replacement;
|
|
493
480
|
}
|
|
494
|
-
if (replacement
|
|
495
|
-
|
|
481
|
+
if (replacement == null || replacement == node) {
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
// @ts-ignore
|
|
485
|
+
node = replacement;
|
|
486
|
+
//
|
|
487
|
+
if (Array.isArray(node)) {
|
|
488
|
+
break;
|
|
496
489
|
}
|
|
497
490
|
}
|
|
498
|
-
}
|
|
499
|
-
if (node != result.node) {
|
|
500
491
|
// @ts-ignore
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
tokens.push(...result.node.val);
|
|
506
|
-
}
|
|
507
|
-
if (tokens.length == 0) {
|
|
508
|
-
continue;
|
|
492
|
+
if (node != result.node) {
|
|
493
|
+
// @ts-ignore
|
|
494
|
+
replaceToken(result.parent, result.node, node);
|
|
495
|
+
}
|
|
509
496
|
}
|
|
510
|
-
|
|
511
|
-
node =
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
497
|
+
else if (valuesHandlers.size > 0) {
|
|
498
|
+
let node = null;
|
|
499
|
+
node = result.node;
|
|
500
|
+
if (valuesHandlers.has(node.typ)) {
|
|
501
|
+
for (const valueHandler of valuesHandlers.get(node.typ)) {
|
|
502
|
+
callable = valueHandler;
|
|
503
|
+
replacement = callable(node, result.parent);
|
|
504
|
+
if (replacement == null) {
|
|
517
505
|
continue;
|
|
518
506
|
}
|
|
519
|
-
isAsync =
|
|
507
|
+
isAsync = replacement instanceof Promise || Object.getPrototypeOf(replacement).constructor.name == 'AsyncFunction';
|
|
520
508
|
if (isAsync) {
|
|
521
|
-
|
|
509
|
+
replacement = await replacement;
|
|
522
510
|
}
|
|
523
|
-
if (
|
|
524
|
-
node =
|
|
525
|
-
}
|
|
526
|
-
//
|
|
527
|
-
if (Array.isArray(node)) {
|
|
528
|
-
break;
|
|
511
|
+
if (replacement != null && replacement != node) {
|
|
512
|
+
node = replacement;
|
|
529
513
|
}
|
|
530
514
|
}
|
|
531
515
|
}
|
|
532
|
-
if (node !=
|
|
516
|
+
if (node != result.node) {
|
|
533
517
|
// @ts-ignore
|
|
534
|
-
replaceToken(parent, value, node);
|
|
518
|
+
replaceToken(result.parent, value, node);
|
|
519
|
+
}
|
|
520
|
+
const tokens = 'tokens' in result.node ? result.node.tokens : [];
|
|
521
|
+
if ('val' in result.node && Array.isArray(result.node.val)) {
|
|
522
|
+
tokens.push(...result.node.val);
|
|
523
|
+
}
|
|
524
|
+
if (tokens.length == 0) {
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
for (const { value, parent, root } of walkValues(tokens, result.node)) {
|
|
528
|
+
node = value;
|
|
529
|
+
if (valuesHandlers.has(node.typ)) {
|
|
530
|
+
for (const valueHandler of valuesHandlers.get(node.typ)) {
|
|
531
|
+
callable = valueHandler;
|
|
532
|
+
let result = callable(node, parent, root);
|
|
533
|
+
if (result == null) {
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
isAsync = result instanceof Promise || Object.getPrototypeOf(result).constructor.name == 'AsyncFunction';
|
|
537
|
+
if (isAsync) {
|
|
538
|
+
result = await result;
|
|
539
|
+
}
|
|
540
|
+
if (result != null && result != node) {
|
|
541
|
+
node = result;
|
|
542
|
+
}
|
|
543
|
+
//
|
|
544
|
+
if (Array.isArray(node)) {
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (node != value) {
|
|
550
|
+
// @ts-ignore
|
|
551
|
+
replaceToken(parent, value, node);
|
|
552
|
+
}
|
|
535
553
|
}
|
|
536
554
|
}
|
|
537
555
|
}
|
|
@@ -571,7 +589,7 @@ function getLastNode(context) {
|
|
|
571
589
|
}
|
|
572
590
|
return null;
|
|
573
591
|
}
|
|
574
|
-
function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
592
|
+
function parseNode(results, context, options, errors, src, map, rawTokens, stats) {
|
|
575
593
|
let tokens = [];
|
|
576
594
|
for (const t of results) {
|
|
577
595
|
const node = getTokenType(t.token, t.hint);
|
|
@@ -594,9 +612,12 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
594
612
|
}
|
|
595
613
|
loc = location;
|
|
596
614
|
context.chi.push(tokens[i]);
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
615
|
+
stats.nodesCount++;
|
|
616
|
+
Object.defineProperty(tokens[i], 'loc', {
|
|
617
|
+
...definedPropertySettings,
|
|
618
|
+
value: loc,
|
|
619
|
+
enumerable: options.sourcemap !== false
|
|
620
|
+
});
|
|
600
621
|
}
|
|
601
622
|
else if (tokens[i].typ != EnumToken.WhitespaceTokenType) {
|
|
602
623
|
break;
|
|
@@ -737,10 +758,10 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
737
758
|
}
|
|
738
759
|
}
|
|
739
760
|
const t = parseAtRulePrelude(parseTokens(tokens, { minify: options.minify }), atRule);
|
|
740
|
-
const raw =
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
}
|
|
761
|
+
const raw = [];
|
|
762
|
+
for (const curr of t) {
|
|
763
|
+
raw.push(renderToken(curr, { removeComments: true, convertColor: false }));
|
|
764
|
+
}
|
|
744
765
|
const nam = renderToken(atRule, { removeComments: true });
|
|
745
766
|
// @ts-ignore
|
|
746
767
|
const node = {
|
|
@@ -756,10 +777,12 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
756
777
|
node.chi = [];
|
|
757
778
|
}
|
|
758
779
|
loc = map.get(atRule);
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
780
|
+
Object.defineProperty(node, 'loc', {
|
|
781
|
+
...definedPropertySettings,
|
|
782
|
+
value: loc,
|
|
783
|
+
enumerable: options.sourcemap !== false
|
|
784
|
+
});
|
|
785
|
+
node.loc.end = { ...map.get(delim).end };
|
|
763
786
|
let isValid = true;
|
|
764
787
|
if (node.nam == 'else') {
|
|
765
788
|
const prev = getLastNode(context);
|
|
@@ -773,20 +796,31 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
773
796
|
}
|
|
774
797
|
}
|
|
775
798
|
// @ts-ignore
|
|
776
|
-
const
|
|
799
|
+
const skipValidate = (options.validation & ValidationLevel.AtRule) == 0;
|
|
800
|
+
const isAllowed = skipValidate || isNodeAllowedInContext(node, context);
|
|
801
|
+
// @ts-ignore
|
|
802
|
+
const valid = skipValidate ? {
|
|
777
803
|
valid: SyntaxValidationResult.Valid,
|
|
778
804
|
error: '',
|
|
779
805
|
node,
|
|
780
806
|
syntax: '@' + node.nam
|
|
781
|
-
} :
|
|
807
|
+
} : !isAllowed ? {
|
|
808
|
+
valid: SyntaxValidationResult.Drop,
|
|
809
|
+
node,
|
|
810
|
+
syntax: '@' + node.nam,
|
|
811
|
+
error: `${EnumToken[context.typ]}: child ${EnumToken[node.typ]} not allowed in context${context.typ == EnumToken.AtRuleNodeType ? ` '@${context.nam}'` : context.typ == EnumToken.StyleSheetNodeType ? ` 'stylesheet'` : ''}`} : isValid ? (node.typ == EnumToken.KeyframesAtRuleNodeType ? validateAtRuleKeyframes(node) : validateAtRule(node, options, context)) : {
|
|
782
812
|
valid: SyntaxValidationResult.Drop,
|
|
783
813
|
node,
|
|
784
814
|
syntax: '@' + node.nam,
|
|
785
815
|
error: '@' + node.nam + ' not allowed here'};
|
|
786
816
|
if (valid.valid == SyntaxValidationResult.Drop) {
|
|
817
|
+
let message = '';
|
|
818
|
+
for (const token of tokens) {
|
|
819
|
+
message += renderToken(token, { minify: false });
|
|
820
|
+
}
|
|
787
821
|
errors.push({
|
|
788
822
|
action: 'drop',
|
|
789
|
-
message: valid.error + ' - "' +
|
|
823
|
+
message: valid.error + ' - "' + message + '"',
|
|
790
824
|
node,
|
|
791
825
|
// @ts-ignore
|
|
792
826
|
location: { src, ...(map.get(valid.node) ?? location) }
|
|
@@ -795,13 +829,17 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
795
829
|
node.typ = EnumToken.InvalidAtRuleTokenType;
|
|
796
830
|
}
|
|
797
831
|
else {
|
|
798
|
-
node.val =
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
832
|
+
node.val = '';
|
|
833
|
+
for (const token of node.tokens) {
|
|
834
|
+
node.val += renderToken(token, {
|
|
835
|
+
minify: false,
|
|
836
|
+
convertColor: false,
|
|
837
|
+
removeComments: true
|
|
838
|
+
});
|
|
839
|
+
}
|
|
803
840
|
}
|
|
804
841
|
context.chi.push(node);
|
|
842
|
+
stats.nodesCount++;
|
|
805
843
|
Object.defineProperties(node, {
|
|
806
844
|
parent: { ...definedPropertySettings, value: context },
|
|
807
845
|
validSyntax: { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid }
|
|
@@ -899,16 +937,23 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
899
937
|
value: tokens.slice()
|
|
900
938
|
});
|
|
901
939
|
loc = location;
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
940
|
+
Object.defineProperty(node, 'loc', {
|
|
941
|
+
...definedPropertySettings,
|
|
942
|
+
value: loc,
|
|
943
|
+
enumerable: options.sourcemap !== false
|
|
944
|
+
});
|
|
906
945
|
context.chi.push(node);
|
|
907
946
|
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
|
|
908
947
|
// @ts-ignore
|
|
909
|
-
const
|
|
948
|
+
const skipValidate = (options.validation & ValidationLevel.Selector) == 0;
|
|
949
|
+
const isAllowed = skipValidate || isNodeAllowedInContext(node, context);
|
|
950
|
+
// @ts-ignore
|
|
951
|
+
const valid = skipValidate ? {
|
|
910
952
|
valid: SyntaxValidationResult.Valid,
|
|
911
953
|
error: null
|
|
954
|
+
} : !isAllowed ? {
|
|
955
|
+
valid: SyntaxValidationResult.Drop,
|
|
956
|
+
error: `${EnumToken[context.typ]}: child ${EnumToken[node.typ]} not allowed in context${context.typ == EnumToken.AtRuleNodeType ? ` '@${context.nam}'` : context.typ == EnumToken.StyleSheetNodeType ? ` 'stylesheet'` : ''}`
|
|
912
957
|
} : ruleType == EnumToken.KeyFramesRuleNodeType ? validateKeyframeSelector(tokens) : validateSelector(tokens, options, context);
|
|
913
958
|
if (valid.valid != SyntaxValidationResult.Valid) {
|
|
914
959
|
// @ts-ignore
|
|
@@ -1018,11 +1063,13 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
1018
1063
|
nam,
|
|
1019
1064
|
val: []
|
|
1020
1065
|
};
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1066
|
+
Object.defineProperty(node, 'loc', {
|
|
1067
|
+
...definedPropertySettings,
|
|
1068
|
+
value: location,
|
|
1069
|
+
enumerable: options.sourcemap !== false
|
|
1070
|
+
});
|
|
1025
1071
|
context.chi.push(node);
|
|
1072
|
+
stats.nodesCount++;
|
|
1026
1073
|
}
|
|
1027
1074
|
return null;
|
|
1028
1075
|
}
|
|
@@ -1046,22 +1093,31 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
1046
1093
|
nam,
|
|
1047
1094
|
val: value
|
|
1048
1095
|
};
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1096
|
+
Object.defineProperty(node, 'loc', {
|
|
1097
|
+
...definedPropertySettings,
|
|
1098
|
+
value: location,
|
|
1099
|
+
enumerable: options.sourcemap !== false
|
|
1100
|
+
});
|
|
1101
|
+
node.loc.end = { ...map.get(delim).end };
|
|
1053
1102
|
// do not allow declarations in style sheets
|
|
1054
1103
|
if (context.typ == EnumToken.StyleSheetNodeType && options.lenient) {
|
|
1055
|
-
|
|
1056
|
-
node.typ = EnumToken.InvalidDeclarationNodeType;
|
|
1104
|
+
Object.assign(node, { typ: EnumToken.InvalidDeclarationNodeType });
|
|
1057
1105
|
context.chi.push(node);
|
|
1106
|
+
stats.nodesCount++;
|
|
1058
1107
|
return null;
|
|
1059
1108
|
}
|
|
1060
1109
|
const result = parseDeclarationNode(node, errors, location);
|
|
1061
1110
|
Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
|
|
1062
1111
|
if (result != null) {
|
|
1063
|
-
if (options.validation
|
|
1064
|
-
const
|
|
1112
|
+
if (options.validation & ValidationLevel.Declaration) {
|
|
1113
|
+
const isAllowed = isNodeAllowedInContext(node, context);
|
|
1114
|
+
// @ts-ignore
|
|
1115
|
+
const valid = !isAllowed ? {
|
|
1116
|
+
valid: SyntaxValidationResult.Drop,
|
|
1117
|
+
error: `${EnumToken[node.typ]} not allowed in context${context.typ == EnumToken.AtRuleNodeType ? ` '@${context.nam}'` : context.typ == EnumToken.StyleSheetNodeType ? ` 'stylesheet'` : ''}`,
|
|
1118
|
+
node,
|
|
1119
|
+
syntax: null
|
|
1120
|
+
} : evaluateSyntax(result, context, options);
|
|
1065
1121
|
Object.defineProperty(result, 'validSyntax', {
|
|
1066
1122
|
...definedPropertySettings,
|
|
1067
1123
|
value: valid.valid == SyntaxValidationResult.Valid
|
|
@@ -1077,11 +1133,11 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
1077
1133
|
if (!options.lenient) {
|
|
1078
1134
|
return null;
|
|
1079
1135
|
}
|
|
1080
|
-
|
|
1081
|
-
node.typ = EnumToken.InvalidDeclarationNodeType;
|
|
1136
|
+
Object.assign(node, { typ: EnumToken.InvalidDeclarationNodeType });
|
|
1082
1137
|
}
|
|
1083
1138
|
}
|
|
1084
1139
|
context.chi.push(result);
|
|
1140
|
+
stats.nodesCount++;
|
|
1085
1141
|
}
|
|
1086
1142
|
return null;
|
|
1087
1143
|
}
|
|
@@ -1093,7 +1149,6 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
|
|
|
1093
1149
|
* @param atRule
|
|
1094
1150
|
*/
|
|
1095
1151
|
function parseAtRulePrelude(tokens, atRule) {
|
|
1096
|
-
// @ts-ignore
|
|
1097
1152
|
for (const { value, parent } of walkValues(tokens, null, null, true)) {
|
|
1098
1153
|
if (value.typ == EnumToken.CommentTokenType ||
|
|
1099
1154
|
value.typ == EnumToken.WhitespaceTokenType ||
|
|
@@ -1129,16 +1184,14 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
1129
1184
|
}
|
|
1130
1185
|
if (atRule.val == 'page' && value.typ == EnumToken.PseudoClassTokenType) {
|
|
1131
1186
|
if ([':left', ':right', ':first', ':blank'].includes(value.val)) {
|
|
1132
|
-
|
|
1133
|
-
value.typ = EnumToken.PseudoPageTokenType;
|
|
1187
|
+
Object.assign(value, { typ: EnumToken.PseudoPageTokenType });
|
|
1134
1188
|
}
|
|
1135
1189
|
}
|
|
1136
1190
|
if (atRule.val == 'layer') {
|
|
1137
1191
|
if (parent == null && value.typ == EnumToken.LiteralTokenType) {
|
|
1138
1192
|
if (value.val.charAt(0) == '.') {
|
|
1139
1193
|
if (isIdent(value.val.slice(1))) {
|
|
1140
|
-
|
|
1141
|
-
value.typ = EnumToken.ClassSelectorTokenType;
|
|
1194
|
+
Object.assign(value, { typ: EnumToken.ClassSelectorTokenType });
|
|
1142
1195
|
}
|
|
1143
1196
|
}
|
|
1144
1197
|
}
|
|
@@ -1147,8 +1200,7 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
1147
1200
|
if (value.typ == EnumToken.IdenTokenType) {
|
|
1148
1201
|
if (parent == null && mediaTypes.some((t) => {
|
|
1149
1202
|
if (val === t) {
|
|
1150
|
-
|
|
1151
|
-
value.typ = EnumToken.MediaFeatureTokenType;
|
|
1203
|
+
Object.assign(value, { typ: EnumToken.MediaFeatureTokenType });
|
|
1152
1204
|
return true;
|
|
1153
1205
|
}
|
|
1154
1206
|
return false;
|
|
@@ -1156,18 +1208,15 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
1156
1208
|
continue;
|
|
1157
1209
|
}
|
|
1158
1210
|
if (value.typ == EnumToken.IdenTokenType && 'and' === val) {
|
|
1159
|
-
|
|
1160
|
-
value.typ = EnumToken.MediaFeatureAndTokenType;
|
|
1211
|
+
Object.assign(value, { typ: EnumToken.MediaFeatureAndTokenType });
|
|
1161
1212
|
continue;
|
|
1162
1213
|
}
|
|
1163
1214
|
if (value.typ == EnumToken.IdenTokenType && 'or' === val) {
|
|
1164
|
-
|
|
1165
|
-
value.typ = EnumToken.MediaFeatureOrTokenType;
|
|
1215
|
+
Object.assign(value, { typ: EnumToken.MediaFeatureOrTokenType });
|
|
1166
1216
|
continue;
|
|
1167
1217
|
}
|
|
1168
1218
|
if (value.typ == EnumToken.IdenTokenType &&
|
|
1169
1219
|
['not', 'only'].some((t) => val === t)) {
|
|
1170
|
-
// @ts-ignore
|
|
1171
1220
|
const array = parent?.chi ?? tokens;
|
|
1172
1221
|
const startIndex = array.indexOf(value);
|
|
1173
1222
|
let index = startIndex + 1;
|
|
@@ -1212,12 +1261,15 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
1212
1261
|
if (value.chi[i].typ == EnumToken.CommentTokenType || value.chi[i].typ == EnumToken.WhitespaceTokenType) {
|
|
1213
1262
|
continue;
|
|
1214
1263
|
}
|
|
1215
|
-
if (value.chi[i].typ == EnumToken.LiteralTokenType && value.chi[i].val.startsWith(':')
|
|
1216
|
-
value.chi.
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1264
|
+
if (value.chi[i].typ == EnumToken.LiteralTokenType && value.chi[i].val.startsWith(':')) {
|
|
1265
|
+
const dimension = parseDimension(value.chi[i].val.slice(1));
|
|
1266
|
+
if (dimension != null) {
|
|
1267
|
+
value.chi.splice(i, 1, {
|
|
1268
|
+
typ: EnumToken.ColonTokenType,
|
|
1269
|
+
}, Object.assign(value.chi[i], dimension));
|
|
1270
|
+
i--;
|
|
1271
|
+
continue;
|
|
1272
|
+
}
|
|
1221
1273
|
}
|
|
1222
1274
|
if (nameIndex != -1 && value.chi[i].typ == EnumToken.PseudoClassTokenType) {
|
|
1223
1275
|
value.chi.splice(i, 1, {
|
|
@@ -1244,11 +1296,10 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
1244
1296
|
const val = value.chi.splice(valueIndex, 1)[0];
|
|
1245
1297
|
const node = value.chi.splice(nameIndex, 1)[0];
|
|
1246
1298
|
// 'background'
|
|
1247
|
-
// @ts-ignore
|
|
1248
1299
|
if (node.typ == EnumToken.ColorTokenType && node.kin == ColorType.DPSYS) {
|
|
1300
|
+
Object.assign(node, { typ: EnumToken.IdenTokenType });
|
|
1249
1301
|
// @ts-ignore
|
|
1250
1302
|
delete node.kin;
|
|
1251
|
-
node.typ = EnumToken.IdenTokenType;
|
|
1252
1303
|
}
|
|
1253
1304
|
while (value.chi[0]?.typ == EnumToken.WhitespaceTokenType) {
|
|
1254
1305
|
value.chi.shift();
|
|
@@ -1303,43 +1354,35 @@ function parseSelector(tokens) {
|
|
|
1303
1354
|
}
|
|
1304
1355
|
if (parent == null) {
|
|
1305
1356
|
if (value.typ == EnumToken.GtTokenType) {
|
|
1306
|
-
|
|
1307
|
-
value.typ = EnumToken.ChildCombinatorTokenType;
|
|
1357
|
+
Object.assign(value, { typ: EnumToken.ChildCombinatorTokenType });
|
|
1308
1358
|
}
|
|
1309
1359
|
else if (value.typ == EnumToken.LiteralTokenType) {
|
|
1310
1360
|
if (value.val.charAt(0) == '&') {
|
|
1311
|
-
|
|
1312
|
-
value.typ = EnumToken.NestingSelectorTokenType;
|
|
1361
|
+
Object.assign(value, { typ: EnumToken.NestingSelectorTokenType });
|
|
1313
1362
|
// @ts-ignore
|
|
1314
1363
|
delete value.val;
|
|
1315
1364
|
}
|
|
1316
1365
|
else if (value.val.charAt(0) == '.') {
|
|
1317
1366
|
if (!isIdent(value.val.slice(1))) {
|
|
1318
|
-
|
|
1319
|
-
value.typ = EnumToken.InvalidClassSelectorTokenType;
|
|
1367
|
+
Object.assign(value, { typ: EnumToken.InvalidClassSelectorTokenType });
|
|
1320
1368
|
}
|
|
1321
1369
|
else {
|
|
1322
|
-
|
|
1323
|
-
value.typ = EnumToken.ClassSelectorTokenType;
|
|
1370
|
+
Object.assign(value, { typ: EnumToken.ClassSelectorTokenType });
|
|
1324
1371
|
}
|
|
1325
1372
|
}
|
|
1326
1373
|
if (['*', '>', '+', '~'].includes(value.val)) {
|
|
1327
1374
|
switch (value.val) {
|
|
1328
1375
|
case '*':
|
|
1329
|
-
|
|
1330
|
-
value.typ = EnumToken.UniversalSelectorTokenType;
|
|
1376
|
+
Object.assign(value, { typ: EnumToken.UniversalSelectorTokenType });
|
|
1331
1377
|
break;
|
|
1332
1378
|
case '>':
|
|
1333
|
-
|
|
1334
|
-
value.typ = EnumToken.ChildCombinatorTokenType;
|
|
1379
|
+
Object.assign(value, { typ: EnumToken.ChildCombinatorTokenType });
|
|
1335
1380
|
break;
|
|
1336
1381
|
case '+':
|
|
1337
|
-
|
|
1338
|
-
value.typ = EnumToken.NextSiblingCombinatorTokenType;
|
|
1382
|
+
Object.assign(value, { typ: EnumToken.NextSiblingCombinatorTokenType });
|
|
1339
1383
|
break;
|
|
1340
1384
|
case '~':
|
|
1341
|
-
|
|
1342
|
-
value.typ = EnumToken.SubsequentSiblingCombinatorTokenType;
|
|
1385
|
+
Object.assign(value, { typ: EnumToken.SubsequentSiblingCombinatorTokenType });
|
|
1343
1386
|
break;
|
|
1344
1387
|
}
|
|
1345
1388
|
// @ts-ignore
|
|
@@ -1352,12 +1395,10 @@ function parseSelector(tokens) {
|
|
|
1352
1395
|
if (!isIdent(value.val.slice(1))) {
|
|
1353
1396
|
continue;
|
|
1354
1397
|
}
|
|
1355
|
-
|
|
1356
|
-
value.typ = EnumToken.HashTokenType;
|
|
1398
|
+
Object.assign(value, { typ: EnumToken.HashTokenType });
|
|
1357
1399
|
}
|
|
1358
1400
|
else {
|
|
1359
|
-
|
|
1360
|
-
value.typ = EnumToken.IdenTokenType;
|
|
1401
|
+
Object.assign(value, { typ: EnumToken.IdenTokenType });
|
|
1361
1402
|
}
|
|
1362
1403
|
// @ts-ignore
|
|
1363
1404
|
delete value.kin;
|
|
@@ -1420,15 +1461,17 @@ function parseString(src, options = { location: false }) {
|
|
|
1420
1461
|
return acc;
|
|
1421
1462
|
}
|
|
1422
1463
|
const token = getTokenType(t.token, t.hint);
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1464
|
+
Object.defineProperty(token, 'loc', {
|
|
1465
|
+
...definedPropertySettings,
|
|
1466
|
+
value: { sta: t.sta },
|
|
1467
|
+
enumerable: options.location !== false
|
|
1468
|
+
});
|
|
1426
1469
|
acc.push(token);
|
|
1427
1470
|
return acc;
|
|
1428
1471
|
}, []));
|
|
1429
1472
|
}
|
|
1430
1473
|
/**
|
|
1431
|
-
* get token type from a string
|
|
1474
|
+
* get the token type from a string
|
|
1432
1475
|
* @param val
|
|
1433
1476
|
* @param hint
|
|
1434
1477
|
*/
|
|
@@ -1464,7 +1507,7 @@ function getTokenType(val, hint) {
|
|
|
1464
1507
|
case '>':
|
|
1465
1508
|
return { typ: EnumToken.GtTokenType };
|
|
1466
1509
|
}
|
|
1467
|
-
if (isPseudo(val)) {
|
|
1510
|
+
if (val.charAt(0) == ':' && isPseudo(val)) {
|
|
1468
1511
|
return val.endsWith('(') ? {
|
|
1469
1512
|
typ: EnumToken.PseudoClassFuncTokenType,
|
|
1470
1513
|
val: val.slice(0, -1),
|
|
@@ -1481,13 +1524,13 @@ function getTokenType(val, hint) {
|
|
|
1481
1524
|
val
|
|
1482
1525
|
});
|
|
1483
1526
|
}
|
|
1484
|
-
if (isAtKeyword(val)) {
|
|
1527
|
+
if (val.charAt(0) == '@' && isAtKeyword(val)) {
|
|
1485
1528
|
return {
|
|
1486
1529
|
typ: EnumToken.AtRuleTokenType,
|
|
1487
1530
|
val: val.slice(1)
|
|
1488
1531
|
};
|
|
1489
1532
|
}
|
|
1490
|
-
if (isFunction(val)) {
|
|
1533
|
+
if (val.endsWith('(') && isFunction(val)) {
|
|
1491
1534
|
val = val.slice(0, -1);
|
|
1492
1535
|
if (val == 'url') {
|
|
1493
1536
|
return {
|
|
@@ -1535,15 +1578,12 @@ function getTokenType(val, hint) {
|
|
|
1535
1578
|
val: +val.slice(0, -1)
|
|
1536
1579
|
};
|
|
1537
1580
|
}
|
|
1538
|
-
if (
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
};
|
|
1543
|
-
}
|
|
1544
|
-
if (isDimension(val)) {
|
|
1545
|
-
return parseDimension(val);
|
|
1581
|
+
// if (isDimension(val)) {
|
|
1582
|
+
const dimension = parseDimension(val);
|
|
1583
|
+
if (dimension != null) {
|
|
1584
|
+
return dimension;
|
|
1546
1585
|
}
|
|
1586
|
+
// }
|
|
1547
1587
|
const v = val.toLowerCase();
|
|
1548
1588
|
if (v == 'currentcolor' || v == 'transparent' || v in COLORS_NAMES) {
|
|
1549
1589
|
return {
|