@tbela99/css-parser 1.4.2 → 1.4.3
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/.nyc_output/4874b20e-6f53-4d7a-be5a-cf68316925f2.json +1 -0
- package/.nyc_output/6193bc4c-6f5f-4898-8950-c628825e6342.json +1 -0
- package/.nyc_output/processinfo/4874b20e-6f53-4d7a-be5a-cf68316925f2.json +1 -0
- package/.nyc_output/processinfo/6193bc4c-6f5f-4898-8950-c628825e6342.json +1 -0
- package/.repl_history +4 -0
- package/CHANGELOG.md +164 -4
- package/README.md +43 -0
- package/badges/coverage.svg +20 -0
- package/deno.lock +2861 -0
- package/dist/config.json.js +33 -1
- package/dist/index-umd-web.js +24382 -18476
- package/dist/index.cjs +24522 -18618
- package/dist/index.d.ts +1396 -929
- package/dist/lib/ast/clone.d.ts +10 -0
- package/dist/lib/ast/clone.js +45 -0
- package/dist/lib/ast/expand.d.ts +14 -0
- package/dist/lib/ast/expand.js +89 -64
- package/dist/lib/ast/features/calc.d.ts +10 -0
- package/dist/lib/ast/features/calc.js +62 -24
- package/dist/lib/ast/features/if.d.ts +10 -0
- package/dist/lib/ast/features/if.js +215 -0
- package/dist/lib/ast/features/index.d.ts +6 -0
- package/dist/lib/ast/features/index.js +1 -0
- package/dist/lib/ast/features/inlinecssvariables.d.ts +15 -0
- package/dist/lib/ast/features/inlinecssvariables.js +32 -27
- package/dist/lib/ast/features/prefix.d.ts +8 -0
- package/dist/lib/ast/features/prefix.js +68 -43
- package/dist/lib/ast/features/shorthand.d.ts +12 -0
- package/dist/lib/ast/features/shorthand.js +6 -9
- package/dist/lib/ast/features/transform.d.ts +10 -0
- package/dist/lib/ast/features/transform.js +9 -13
- package/dist/lib/ast/features/type.d.ts +15 -0
- package/dist/lib/ast/find.d.ts +165 -0
- package/dist/lib/ast/find.js +175 -0
- package/dist/lib/ast/math/expression.d.ts +18 -0
- package/dist/lib/ast/math/expression.js +140 -98
- package/dist/lib/ast/math/math.d.ts +6 -0
- package/dist/lib/ast/math/math.js +30 -41
- package/dist/lib/ast/minify.d.ts +19 -0
- package/dist/lib/ast/minify.js +541 -217
- package/dist/lib/ast/transform/compute.d.ts +8 -0
- package/dist/lib/ast/transform/compute.js +82 -69
- package/dist/lib/ast/transform/matrix.d.ts +22 -0
- package/dist/lib/ast/transform/matrix.js +12 -26
- package/dist/lib/ast/transform/minify.d.ts +5 -0
- package/dist/lib/ast/transform/minify.js +20 -20
- package/dist/lib/ast/transform/perspective.d.ts +3 -0
- package/dist/lib/ast/transform/perspective.js +1 -1
- package/dist/lib/ast/transform/rotate.d.ts +12 -0
- package/dist/lib/ast/transform/rotate.js +1 -1
- package/dist/lib/ast/transform/scale.d.ts +6 -0
- package/dist/lib/ast/transform/scale.js +1 -1
- package/dist/lib/ast/transform/skew.d.ts +4 -0
- package/dist/lib/ast/transform/skew.js +1 -1
- package/dist/lib/ast/transform/translate.d.ts +6 -0
- package/dist/lib/ast/transform/translate.js +1 -1
- package/dist/lib/ast/transform/utils.d.ts +9 -0
- package/dist/lib/ast/types.d.ts +903 -0
- package/dist/lib/ast/types.js +277 -23
- package/dist/lib/ast/walk.d.ts +162 -0
- package/dist/lib/ast/walk.js +116 -60
- package/dist/lib/fs/resolve.d.ts +20 -0
- package/dist/lib/fs/resolve.js +37 -45
- package/dist/lib/parser/declaration/list.d.ts +16 -0
- package/dist/lib/parser/declaration/list.js +26 -24
- package/dist/lib/parser/declaration/map.d.ts +15 -0
- package/dist/lib/parser/declaration/map.js +140 -95
- package/dist/lib/parser/declaration/set.d.ts +9 -0
- package/dist/lib/parser/declaration/set.js +30 -25
- package/dist/lib/parser/node.d.ts +7 -0
- package/dist/lib/parser/parse.d.ts +107 -0
- package/dist/lib/parser/parse.js +1454 -1445
- package/dist/lib/parser/tokenize.d.ts +57 -0
- package/dist/lib/parser/tokenize.js +557 -404
- package/dist/lib/parser/utils/at-rule-container.d.ts +5 -0
- package/dist/lib/parser/utils/at-rule-container.js +486 -0
- package/dist/lib/parser/utils/at-rule-font-feature-values.d.ts +5 -0
- package/dist/lib/parser/utils/at-rule-font-feature-values.js +13 -0
- package/dist/lib/parser/utils/at-rule-generic.d.ts +5 -0
- package/dist/lib/parser/utils/at-rule-generic.js +118 -0
- package/dist/lib/parser/utils/at-rule-import.d.ts +5 -0
- package/dist/lib/parser/utils/at-rule-import.js +393 -0
- package/dist/lib/parser/utils/at-rule-media.d.ts +5 -0
- package/dist/lib/parser/utils/at-rule-media.js +603 -0
- package/dist/lib/parser/utils/at-rule-page.d.ts +5 -0
- package/dist/lib/parser/utils/at-rule-page.js +28 -0
- package/dist/lib/parser/utils/at-rule-support.d.ts +5 -0
- package/dist/lib/parser/utils/at-rule-support.js +366 -0
- package/dist/lib/parser/utils/at-rule-token.d.ts +1 -0
- package/dist/lib/parser/utils/at-rule-when-else.d.ts +5 -0
- package/dist/lib/parser/utils/at-rule-when-else.js +363 -0
- package/dist/lib/parser/utils/at-rule.d.ts +13 -0
- package/dist/lib/parser/utils/at-rule.js +37 -0
- package/dist/lib/parser/utils/cache.d.ts +6 -0
- package/dist/lib/parser/utils/cache.js +19 -0
- package/dist/lib/parser/utils/config.d.ts +2 -0
- package/dist/lib/parser/utils/config.js +1 -0
- package/dist/lib/parser/utils/declaration-list.d.ts +5 -0
- package/dist/lib/parser/utils/declaration.d.ts +18 -0
- package/dist/lib/parser/utils/declaration.js +569 -91
- package/dist/lib/parser/utils/eq.d.ts +1 -0
- package/dist/lib/parser/utils/hash.d.ts +21 -0
- package/dist/lib/parser/utils/hash.js +1 -1
- package/dist/lib/parser/utils/selector.d.ts +5 -0
- package/dist/lib/parser/utils/selector.js +476 -0
- package/dist/lib/parser/utils/text.d.ts +3 -0
- package/dist/lib/parser/utils/text.js +17 -1
- package/dist/lib/parser/utils/token.d.ts +14 -0
- package/dist/lib/parser/utils/token.js +102 -0
- package/dist/lib/parser/utils/type.d.ts +2 -0
- package/dist/lib/parser/utils/type.js +29 -18
- package/dist/lib/renderer/render.d.ts +28 -0
- package/dist/lib/renderer/render.js +421 -262
- package/dist/lib/renderer/sourcemap/lib/encode.d.ts +1 -0
- package/dist/lib/renderer/sourcemap/sourcemap.d.ts +26 -0
- package/dist/lib/renderer/sourcemap/sourcemap.js +17 -7
- package/dist/lib/syntax/color/a98rgb.d.ts +2 -0
- package/dist/lib/syntax/color/a98rgb.js +8 -12
- package/dist/lib/syntax/color/cmyk.d.ts +10 -0
- package/dist/lib/syntax/color/cmyk.js +23 -21
- package/dist/lib/syntax/color/color-mix.d.ts +2 -0
- package/dist/lib/syntax/color/color-mix.js +88 -77
- package/dist/lib/syntax/color/color.d.ts +42 -0
- package/dist/lib/syntax/color/color.js +65 -68
- package/dist/lib/syntax/color/hex.d.ts +16 -0
- package/dist/lib/syntax/color/hex.js +27 -31
- package/dist/lib/syntax/color/hsl.d.ts +20 -0
- package/dist/lib/syntax/color/hsl.js +5 -12
- package/dist/lib/syntax/color/hsv.d.ts +2 -0
- package/dist/lib/syntax/color/hwb.d.ts +21 -0
- package/dist/lib/syntax/color/hwb.js +8 -21
- package/dist/lib/syntax/color/lab.d.ts +25 -0
- package/dist/lib/syntax/color/lab.js +20 -21
- package/dist/lib/syntax/color/lch.d.ts +23 -0
- package/dist/lib/syntax/color/lch.js +13 -15
- package/dist/lib/syntax/color/oklab.d.ts +22 -0
- package/dist/lib/syntax/color/oklab.js +20 -39
- package/dist/lib/syntax/color/oklch.d.ts +20 -0
- package/dist/lib/syntax/color/oklch.js +14 -16
- package/dist/lib/syntax/color/p3.d.ts +6 -0
- package/dist/lib/syntax/color/p3.js +0 -8
- package/dist/lib/syntax/color/prophotorgb.d.ts +2 -0
- package/dist/lib/syntax/color/rec2020.d.ts +2 -0
- package/dist/lib/syntax/color/rec2020.js +9 -13
- package/dist/lib/syntax/color/relativecolor.d.ts +13 -0
- package/dist/lib/syntax/color/relativecolor.js +68 -41
- package/dist/lib/syntax/color/rgb.d.ts +20 -0
- package/dist/lib/syntax/color/rgb.js +14 -18
- package/dist/lib/syntax/color/srgb.d.ts +23 -0
- package/dist/lib/syntax/color/srgb.js +27 -26
- package/dist/lib/syntax/color/utils/components.d.ts +2 -0
- package/dist/lib/syntax/color/utils/components.js +30 -14
- package/dist/lib/syntax/color/utils/distance.d.ts +18 -0
- package/dist/lib/syntax/color/utils/distance.js +1 -8
- package/dist/lib/syntax/color/utils/matrix.d.ts +6 -0
- package/dist/lib/syntax/color/xyz.d.ts +5 -0
- package/dist/lib/syntax/color/xyz.js +8 -20
- package/dist/lib/syntax/color/xyzd50.d.ts +4 -0
- package/dist/lib/syntax/color/xyzd50.js +6 -20
- package/dist/lib/syntax/constants.d.ts +67 -0
- package/dist/lib/syntax/constants.js +436 -0
- package/dist/lib/syntax/syntax.d.ts +38 -0
- package/dist/lib/syntax/syntax.js +533 -568
- package/dist/lib/validation/config.d.ts +14 -0
- package/dist/lib/validation/config.js +72 -33
- package/dist/lib/validation/config.json.js +1159 -74
- package/dist/lib/validation/json.d.ts +2 -0
- package/dist/lib/validation/match.d.ts +38 -0
- package/dist/lib/validation/match.js +2985 -0
- package/dist/lib/validation/parser/parse.d.ts +8 -0
- package/dist/lib/validation/parser/parse.js +684 -935
- package/dist/lib/validation/parser/typedef.d.ts +95 -0
- package/dist/lib/validation/parser/typedef.js +100 -0
- package/dist/lib/validation/utils/list.d.ts +4 -0
- package/dist/lib/validation/utils/list.js +4 -11
- package/dist/lib/validation/utils/whitespace.d.ts +2 -0
- package/dist/lib/validation/utils/whitespace.js +2 -8
- package/dist/node.d.ts +207 -0
- package/dist/node.js +42 -39
- package/dist/web.d.ts +169 -0
- package/dist/web.js +38 -33
- package/package.json +15 -12
- package/playground/index.html +1328 -0
- package/playground/sw.js +55 -0
- package/playground/tree.js +176 -0
- package/dist/lib/syntax/color/utils/constants.js +0 -214
- package/dist/lib/syntax/utils.js +0 -70
- package/dist/lib/validation/at-rules/container.js +0 -342
- package/dist/lib/validation/at-rules/counter-style.js +0 -90
- package/dist/lib/validation/at-rules/custom-media.js +0 -50
- package/dist/lib/validation/at-rules/document.js +0 -89
- package/dist/lib/validation/at-rules/else.js +0 -5
- package/dist/lib/validation/at-rules/font-feature-values.js +0 -63
- package/dist/lib/validation/at-rules/import.js +0 -150
- package/dist/lib/validation/at-rules/keyframes.js +0 -67
- package/dist/lib/validation/at-rules/layer.js +0 -41
- package/dist/lib/validation/at-rules/media.js +0 -255
- package/dist/lib/validation/at-rules/namespace.js +0 -81
- package/dist/lib/validation/at-rules/page-margin-box.js +0 -64
- package/dist/lib/validation/at-rules/page.js +0 -100
- package/dist/lib/validation/at-rules/supports.js +0 -295
- package/dist/lib/validation/at-rules/when.js +0 -185
- package/dist/lib/validation/atrule.js +0 -184
- package/dist/lib/validation/selector.js +0 -36
- package/dist/lib/validation/syntax.js +0 -1073
- package/dist/lib/validation/syntaxes/complex-selector-list.js +0 -27
- package/dist/lib/validation/syntaxes/complex-selector.js +0 -52
- package/dist/lib/validation/syntaxes/compound-selector.js +0 -196
- package/dist/lib/validation/syntaxes/family-name.js +0 -57
- package/dist/lib/validation/syntaxes/keyframe-selector.js +0 -36
- package/dist/lib/validation/syntaxes/layer-name.js +0 -57
- package/dist/lib/validation/syntaxes/relative-selector-list.js +0 -31
- package/dist/lib/validation/syntaxes/relative-selector.js +0 -38
- package/dist/lib/validation/syntaxes/selector-list.js +0 -5
- package/dist/lib/validation/syntaxes/selector.js +0 -5
- package/dist/lib/validation/syntaxes/url.js +0 -40
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,77 +1,81 @@
|
|
|
1
|
-
import { isIdentStart, isIdent,
|
|
2
|
-
import {
|
|
3
|
-
import { definedPropertySettings, minify, combinators } from '../ast/minify.js';
|
|
4
|
-
import { walkValues, WalkerEvent, walk, WalkerOptionEnum } from '../ast/walk.js';
|
|
5
|
-
import { expand } from '../ast/expand.js';
|
|
6
|
-
import './utils/config.js';
|
|
7
|
-
import { parseDeclarationNode } from './utils/declaration.js';
|
|
8
|
-
import { camelize, dasherize } from './utils/text.js';
|
|
1
|
+
import { isIdentColor, isIdentStart, isIdent, isColor, parseColor } from '../syntax/syntax.js';
|
|
2
|
+
import { camelize, equalsIgnoreCase, dasherize } from './utils/text.js';
|
|
9
3
|
import { renderToken } from '../renderer/render.js';
|
|
10
|
-
import '../
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
4
|
+
import { EnumToken, ValidationLevel, ModuleCaseTransformEnum, ModuleScopeEnumOptions } from '../ast/types.js';
|
|
5
|
+
import { minify } from '../ast/minify.js';
|
|
6
|
+
import { expand } from '../ast/expand.js';
|
|
7
|
+
import { WalkerEvent, walk, walkValues } from '../ast/walk.js';
|
|
13
8
|
import { tokenize, tokenizeStream } from './tokenize.js';
|
|
14
|
-
import '../
|
|
15
|
-
import '../validation/parser/parse.js';
|
|
16
|
-
import { validateSelector } from '../validation/selector.js';
|
|
17
|
-
import { validateAtRule } from '../validation/atrule.js';
|
|
9
|
+
import { definedPropertySettings, tokensfuncDefMap, funcLike, mathFuncs, urlTokenMatcher, pageMarginBoxType } from '../syntax/constants.js';
|
|
18
10
|
import { splitTokenList } from '../validation/utils/list.js';
|
|
19
|
-
import '../
|
|
20
|
-
import { validateKeyframeSelector } from '../validation/syntaxes/keyframe-selector.js';
|
|
21
|
-
import { isNodeAllowedInContext, evaluateSyntax } from '../validation/syntax.js';
|
|
22
|
-
import { validateAtRuleKeyframes } from '../validation/at-rules/keyframes.js';
|
|
11
|
+
import { buildExpression } from '../ast/math/expression.js';
|
|
23
12
|
import { hashAlgorithms, hash } from './utils/hash.js';
|
|
13
|
+
import { parseSelector } from './utils/selector.js';
|
|
14
|
+
import { parseDeclaration } from './utils/declaration.js';
|
|
15
|
+
import { getSyntaxRule } from '../validation/config.js';
|
|
16
|
+
import { matchSelectorSyntax, trimArray, matchAllSyntax, createValidationContext } from '../validation/match.js';
|
|
17
|
+
import { ValidationSyntaxGroupEnum } from '../validation/parser/typedef.js';
|
|
18
|
+
import { matchAtRuleImportSyntax } from './utils/at-rule-import.js';
|
|
19
|
+
import { matchAtRuleWhenElseSyntax } from './utils/at-rule-when-else.js';
|
|
20
|
+
import { parseAtRuleSupportSyntax } from './utils/at-rule-support.js';
|
|
21
|
+
import { replaceToken, trimWhiteSpaceTokens } from './utils/token.js';
|
|
22
|
+
import { parseAtRuleContainerQueryList } from './utils/at-rule-container.js';
|
|
23
|
+
import { parseMediaqueryList } from './utils/at-rule-media.js';
|
|
24
|
+
import { matchAtRuleSyntax } from './utils/at-rule.js';
|
|
25
|
+
import { parseAtRulePage } from './utils/at-rule-page.js';
|
|
26
|
+
import { parseAtRuleFontFeatureValues } from './utils/at-rule-font-feature-values.js';
|
|
27
|
+
import { matchGenericSyntax } from './utils/at-rule-generic.js';
|
|
28
|
+
import { memoize } from './utils/cache.js';
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
function renderTokens(tokens, options) {
|
|
31
|
+
if (tokens == null || tokens.length === 0)
|
|
32
|
+
return "";
|
|
33
|
+
if (options != null)
|
|
34
|
+
return tokens.map((t) => renderToken(t, options)).join("");
|
|
35
|
+
return tokens.map((t) => renderToken(t)).join("");
|
|
36
|
+
}
|
|
37
|
+
const trimWhiteSpace = [
|
|
38
|
+
EnumToken.CommentTokenType,
|
|
39
|
+
EnumToken.GtTokenType,
|
|
40
|
+
EnumToken.GteTokenType,
|
|
41
|
+
EnumToken.LtTokenType,
|
|
42
|
+
EnumToken.LteTokenType,
|
|
43
|
+
EnumToken.ColumnCombinatorTokenType,
|
|
44
|
+
];
|
|
27
45
|
const BadTokensTypes = [
|
|
28
46
|
EnumToken.BadCommentTokenType,
|
|
29
47
|
EnumToken.BadCdoTokenType,
|
|
30
48
|
EnumToken.BadUrlTokenType,
|
|
31
|
-
EnumToken.BadStringTokenType
|
|
49
|
+
EnumToken.BadStringTokenType,
|
|
32
50
|
];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
EnumToken.CommaTokenType, EnumToken.GtTokenType, EnumToken.LtTokenType, EnumToken.GteTokenType, EnumToken.LteTokenType, EnumToken.CommaTokenType,
|
|
37
|
-
EnumToken.StartMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DashMatchTokenType, EnumToken.ContainMatchTokenType,
|
|
38
|
-
EnumToken.EOFTokenType
|
|
39
|
-
]);
|
|
40
|
-
function reject(reason) {
|
|
41
|
-
throw new Error(reason ?? 'Parsing aborted');
|
|
42
|
-
}
|
|
51
|
+
let keyNameCounter = 0;
|
|
52
|
+
let keyNameCache = {};
|
|
53
|
+
const forbiddenStartCharacters = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].map((c) => c.charCodeAt(0));
|
|
43
54
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* @param
|
|
47
|
-
* @param
|
|
55
|
+
* short-scoped name generator.
|
|
56
|
+
*
|
|
57
|
+
* @param localName
|
|
58
|
+
* @param filePath
|
|
59
|
+
* @param pattern
|
|
60
|
+
* @param hashLength
|
|
61
|
+
*
|
|
62
|
+
* @returns string
|
|
48
63
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
...definedPropertySettings,
|
|
54
|
-
value: value.parent
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (parent.typ == EnumToken.BinaryExpressionTokenType) {
|
|
59
|
-
if (parent.l == value) {
|
|
60
|
-
parent.l = replacement;
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
parent.r = replacement;
|
|
64
|
-
}
|
|
64
|
+
const getShortNameGenerator = memoize((localName, filePath, pattern, hashLength = 5) => {
|
|
65
|
+
const key = `${localName}_${filePath}_${pattern}_${hashLength}`;
|
|
66
|
+
if (key in keyNameCache) {
|
|
67
|
+
return keyNameCache[key];
|
|
65
68
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
target.splice(index, 1, ...(Array.isArray(replacement) ? replacement : [replacement]));
|
|
69
|
+
let value = keyNameCounter.toString(36);
|
|
70
|
+
keyNameCounter++;
|
|
71
|
+
while (forbiddenStartCharacters.includes(value.charCodeAt(0))) {
|
|
72
|
+
value = keyNameCounter.toString(36);
|
|
73
|
+
keyNameCounter++;
|
|
74
74
|
}
|
|
75
|
+
return (keyNameCache[key] = value);
|
|
76
|
+
});
|
|
77
|
+
function reject(reason) {
|
|
78
|
+
throw new Error(reason ?? "Parsing aborted");
|
|
75
79
|
}
|
|
76
80
|
/**
|
|
77
81
|
* transform case of key name
|
|
@@ -81,7 +85,7 @@ function replaceToken(parent, value, replacement) {
|
|
|
81
85
|
* @throws Error
|
|
82
86
|
* @private
|
|
83
87
|
*/
|
|
84
|
-
|
|
88
|
+
const getKeyName = memoize((key, how) => {
|
|
85
89
|
switch (how) {
|
|
86
90
|
case ModuleCaseTransformEnum.CamelCase:
|
|
87
91
|
case ModuleCaseTransformEnum.CamelCaseOnly:
|
|
@@ -91,7 +95,7 @@ function getKeyName(key, how) {
|
|
|
91
95
|
return dasherize(key);
|
|
92
96
|
}
|
|
93
97
|
return key;
|
|
94
|
-
}
|
|
98
|
+
});
|
|
95
99
|
/**
|
|
96
100
|
* generate scoped name
|
|
97
101
|
* @param localName
|
|
@@ -102,46 +106,46 @@ function getKeyName(key, how) {
|
|
|
102
106
|
* @throws Error
|
|
103
107
|
* @private
|
|
104
108
|
*/
|
|
105
|
-
|
|
106
|
-
if (localName.startsWith(
|
|
109
|
+
const generateScopedName = memoize(async (localName, filePath, pattern, hashLength = 5) => {
|
|
110
|
+
if (localName.startsWith("--")) {
|
|
107
111
|
localName = localName.slice(2);
|
|
108
112
|
}
|
|
109
113
|
const matches = /.*?(([^/]+)\/)?([^/\\]*?)(\.([^?/]+))?([?].*)?$/.exec(filePath);
|
|
110
|
-
const folder = matches?.[2]?.replace?.(/[^A-Za-z0-9_-]/g, "_") ??
|
|
111
|
-
const fileBase = matches?.[3] ??
|
|
112
|
-
const ext = matches?.[5] ??
|
|
114
|
+
const folder = matches?.[2]?.replace?.(/[^A-Za-z0-9_-]/g, "_") ?? "";
|
|
115
|
+
const fileBase = matches?.[3] ?? "";
|
|
116
|
+
const ext = matches?.[5] ?? "";
|
|
113
117
|
const path = filePath.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
114
118
|
// sanitize localName for safe char set (replace spaces/illegal chars)
|
|
115
119
|
const safeLocal = localName.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
116
120
|
const hashString = `${localName}::${filePath}`;
|
|
117
|
-
let result =
|
|
121
|
+
let result = "";
|
|
118
122
|
let inParens = 0;
|
|
119
|
-
let key =
|
|
123
|
+
let key = "";
|
|
120
124
|
let position = 0;
|
|
121
|
-
// Compose final scoped name. Ensure the entire class doesn't start with digit:
|
|
125
|
+
// Compose final scoped name. Ensure the entire class doesn't start with a digit:
|
|
122
126
|
for (const char of pattern) {
|
|
123
127
|
position += char.length;
|
|
124
|
-
if (char ==
|
|
128
|
+
if (char == "[") {
|
|
125
129
|
inParens++;
|
|
126
130
|
if (inParens != 1) {
|
|
127
131
|
throw new Error(`Unexpected character: '${char} at position ${position - 1}' in pattern '${pattern}'`);
|
|
128
132
|
}
|
|
129
133
|
continue;
|
|
130
134
|
}
|
|
131
|
-
if (char ==
|
|
135
|
+
if (char == "]") {
|
|
132
136
|
inParens--;
|
|
133
137
|
if (inParens != 0) {
|
|
134
138
|
throw new Error(`Unexpected character: '${char}:${position - 1}'`);
|
|
135
139
|
}
|
|
136
140
|
let hashAlgo = null;
|
|
137
141
|
let length = null;
|
|
138
|
-
if (key.includes(
|
|
139
|
-
const parts = key.split(
|
|
142
|
+
if (key.includes(":")) {
|
|
143
|
+
const parts = key.split(":");
|
|
140
144
|
if (parts.length == 2) {
|
|
141
145
|
// @ts-ignore
|
|
142
146
|
[key, length] = parts;
|
|
143
147
|
// @ts-ignore
|
|
144
|
-
if (key ==
|
|
148
|
+
if (key == "hash" && hashAlgorithms.includes(length)) {
|
|
145
149
|
// @ts-ignore
|
|
146
150
|
hashAlgo = length;
|
|
147
151
|
length = null;
|
|
@@ -155,29 +159,35 @@ async function generateScopedName(localName, filePath, pattern, hashLength = 5)
|
|
|
155
159
|
throw new Error(`Unsupported hash length: '${length}'. expecting format [hash:length] or [hash:hash-algo:length]`);
|
|
156
160
|
}
|
|
157
161
|
}
|
|
162
|
+
const slice = length != null && length != fileBase.length;
|
|
158
163
|
switch (key) {
|
|
159
|
-
case
|
|
164
|
+
case "hash":
|
|
160
165
|
result += await hash(hashString, length ?? hashLength, hashAlgo);
|
|
161
166
|
break;
|
|
162
|
-
case
|
|
163
|
-
|
|
167
|
+
case "name":
|
|
168
|
+
// @ts-expect-error
|
|
169
|
+
result += slice ? fileBase.slice(0, +length) : fileBase;
|
|
164
170
|
break;
|
|
165
|
-
case
|
|
166
|
-
|
|
171
|
+
case "local":
|
|
172
|
+
// @ts-expect-error
|
|
173
|
+
result += slice ? safeLocal.slice(0, +length) : localName;
|
|
167
174
|
break;
|
|
168
|
-
case
|
|
169
|
-
|
|
175
|
+
case "ext":
|
|
176
|
+
// @ts-expect-error
|
|
177
|
+
result += slice ? ext.slice(0, +length) : ext;
|
|
170
178
|
break;
|
|
171
|
-
case
|
|
172
|
-
|
|
179
|
+
case "path":
|
|
180
|
+
// @ts-expect-error
|
|
181
|
+
result += slice ? path.slice(0, +length) : path;
|
|
173
182
|
break;
|
|
174
|
-
case
|
|
175
|
-
|
|
183
|
+
case "folder":
|
|
184
|
+
// @ts-expect-error
|
|
185
|
+
result += slice ? folder.slice(0, +length) : folder;
|
|
176
186
|
break;
|
|
177
187
|
default:
|
|
178
188
|
throw new Error(`Unsupported key: '${key}'`);
|
|
179
189
|
}
|
|
180
|
-
key =
|
|
190
|
+
key = "";
|
|
181
191
|
continue;
|
|
182
192
|
}
|
|
183
193
|
if (inParens > 0) {
|
|
@@ -188,8 +198,8 @@ async function generateScopedName(localName, filePath, pattern, hashLength = 5)
|
|
|
188
198
|
}
|
|
189
199
|
}
|
|
190
200
|
// if leading char is digit, prefix underscore (very rare)
|
|
191
|
-
return (/^[0-9]/.test(result) ?
|
|
192
|
-
}
|
|
201
|
+
return (/^[0-9]/.test(result) ? "_" : "") + result;
|
|
202
|
+
});
|
|
193
203
|
/**
|
|
194
204
|
* parse css string
|
|
195
205
|
* @param iter
|
|
@@ -200,13 +210,14 @@ async function generateScopedName(localName, filePath, pattern, hashLength = 5)
|
|
|
200
210
|
*/
|
|
201
211
|
async function doParse(iter, options = {}) {
|
|
202
212
|
if (options.signal != null) {
|
|
203
|
-
options.signal.addEventListener(
|
|
213
|
+
options.signal.addEventListener("abort", reject);
|
|
204
214
|
}
|
|
205
215
|
options = {
|
|
206
|
-
src:
|
|
216
|
+
src: "",
|
|
207
217
|
sourcemap: false,
|
|
208
218
|
minify: true,
|
|
209
219
|
pass: 1,
|
|
220
|
+
expandIfSyntax: false,
|
|
210
221
|
parseColor: true,
|
|
211
222
|
nestingRules: true,
|
|
212
223
|
resolveImport: false,
|
|
@@ -222,9 +233,9 @@ async function doParse(iter, options = {}) {
|
|
|
222
233
|
removePrefix: false,
|
|
223
234
|
validation: ValidationLevel.Default,
|
|
224
235
|
lenient: true,
|
|
225
|
-
...options
|
|
236
|
+
...options,
|
|
226
237
|
};
|
|
227
|
-
if (typeof options.validation ==
|
|
238
|
+
if (typeof options.validation == "boolean") {
|
|
228
239
|
options.validation = options.validation ? ValidationLevel.All : ValidationLevel.None;
|
|
229
240
|
}
|
|
230
241
|
if (options.module) {
|
|
@@ -241,36 +252,36 @@ async function doParse(iter, options = {}) {
|
|
|
241
252
|
const src = options.src;
|
|
242
253
|
const stack = [];
|
|
243
254
|
const stats = {
|
|
244
|
-
src: options.src ??
|
|
255
|
+
src: options.src ?? "",
|
|
245
256
|
bytesIn: 0,
|
|
246
257
|
nodesCount: 0,
|
|
247
258
|
tokensCount: 0,
|
|
248
259
|
importedBytesIn: 0,
|
|
260
|
+
tokenize: `0ms`,
|
|
249
261
|
parse: `0ms`,
|
|
250
262
|
minify: `0ms`,
|
|
251
263
|
total: `0ms`,
|
|
252
|
-
imports: []
|
|
264
|
+
imports: [],
|
|
253
265
|
};
|
|
254
266
|
let ast = {
|
|
255
267
|
typ: EnumToken.StyleSheetNodeType,
|
|
256
|
-
chi: []
|
|
268
|
+
chi: [],
|
|
257
269
|
};
|
|
258
270
|
let tokens = [];
|
|
259
|
-
let map = new Map;
|
|
260
271
|
let context = ast;
|
|
261
272
|
if (options.sourcemap) {
|
|
262
273
|
ast.loc = {
|
|
263
274
|
sta: {
|
|
264
275
|
ind: 0,
|
|
265
276
|
lin: 1,
|
|
266
|
-
col: 1
|
|
277
|
+
col: 1,
|
|
267
278
|
},
|
|
268
279
|
end: {
|
|
269
280
|
ind: 0,
|
|
270
281
|
lin: 1,
|
|
271
|
-
col: 1
|
|
282
|
+
col: 1,
|
|
272
283
|
},
|
|
273
|
-
src:
|
|
284
|
+
src: "",
|
|
274
285
|
};
|
|
275
286
|
}
|
|
276
287
|
let valuesHandlers;
|
|
@@ -279,19 +290,19 @@ async function doParse(iter, options = {}) {
|
|
|
279
290
|
let preVisitorsHandlersMap;
|
|
280
291
|
let visitorsHandlersMap;
|
|
281
292
|
let postVisitorsHandlersMap;
|
|
282
|
-
const rawTokens = [];
|
|
283
293
|
const imports = [];
|
|
284
294
|
let item;
|
|
285
295
|
let node;
|
|
286
296
|
// @ts-ignore ignore error
|
|
287
|
-
let isAsync = typeof iter[Symbol.asyncIterator] ===
|
|
297
|
+
let isAsync = typeof iter[Symbol.asyncIterator] === "function";
|
|
298
|
+
let parensMatch = 0;
|
|
288
299
|
if (options.visitor != null) {
|
|
289
|
-
valuesHandlers = new Map;
|
|
290
|
-
preValuesHandlers = new Map;
|
|
291
|
-
postValuesHandlers = new Map;
|
|
292
|
-
preVisitorsHandlersMap = new Map;
|
|
293
|
-
visitorsHandlersMap = new Map;
|
|
294
|
-
postVisitorsHandlersMap = new Map;
|
|
300
|
+
valuesHandlers = new Map();
|
|
301
|
+
preValuesHandlers = new Map();
|
|
302
|
+
postValuesHandlers = new Map();
|
|
303
|
+
preVisitorsHandlersMap = new Map();
|
|
304
|
+
visitorsHandlersMap = new Map();
|
|
305
|
+
postVisitorsHandlersMap = new Map();
|
|
295
306
|
const visitors = Object.entries(options.visitor);
|
|
296
307
|
let key;
|
|
297
308
|
let value;
|
|
@@ -309,181 +320,195 @@ async function doParse(iter, options = {}) {
|
|
|
309
320
|
continue;
|
|
310
321
|
}
|
|
311
322
|
if (key in EnumToken) {
|
|
312
|
-
if (typeof value ==
|
|
323
|
+
if (typeof value == "function") {
|
|
313
324
|
if (!valuesHandlers.has(EnumToken[key])) {
|
|
314
325
|
valuesHandlers.set(EnumToken[key], []);
|
|
315
326
|
}
|
|
316
327
|
valuesHandlers.get(EnumToken[key]).push(value);
|
|
317
328
|
}
|
|
318
|
-
else if (typeof value ==
|
|
329
|
+
else if (typeof value == "object" &&
|
|
330
|
+
"type" in value &&
|
|
331
|
+
"handler" in value &&
|
|
332
|
+
value.type in WalkerEvent) {
|
|
319
333
|
if (value.type == WalkerEvent.Enter) {
|
|
320
334
|
if (!preValuesHandlers.has(EnumToken[key])) {
|
|
321
335
|
preValuesHandlers.set(EnumToken[key], []);
|
|
322
336
|
}
|
|
323
|
-
preValuesHandlers
|
|
337
|
+
preValuesHandlers
|
|
338
|
+
.get(EnumToken[key])
|
|
339
|
+
.push(value.handler);
|
|
324
340
|
}
|
|
325
341
|
else if (value.type == WalkerEvent.Leave) {
|
|
326
342
|
if (!postValuesHandlers.has(EnumToken[key])) {
|
|
327
343
|
postValuesHandlers.set(EnumToken[key], []);
|
|
328
344
|
}
|
|
329
|
-
postValuesHandlers
|
|
345
|
+
postValuesHandlers
|
|
346
|
+
.get(EnumToken[key])
|
|
347
|
+
.push(value.handler);
|
|
330
348
|
}
|
|
331
349
|
}
|
|
332
350
|
else {
|
|
333
|
-
errors.push({ action:
|
|
351
|
+
errors.push({ action: "ignore", message: `doParse: visitor.${key} is not a valid key name` });
|
|
334
352
|
}
|
|
335
353
|
}
|
|
336
|
-
else if ([
|
|
337
|
-
if (typeof value ==
|
|
354
|
+
else if (["Declaration", "Rule", "AtRule", "KeyframesRule", "KeyframesAtRule"].includes(key)) {
|
|
355
|
+
if (typeof value == "function") {
|
|
338
356
|
if (!visitorsHandlersMap.has(key)) {
|
|
339
357
|
visitorsHandlersMap.set(key, []);
|
|
340
358
|
}
|
|
341
|
-
visitorsHandlersMap
|
|
359
|
+
visitorsHandlersMap
|
|
360
|
+
.get(key)
|
|
361
|
+
.push(value);
|
|
342
362
|
}
|
|
343
|
-
else if (typeof value ==
|
|
344
|
-
if (
|
|
363
|
+
else if (typeof value == "object") {
|
|
364
|
+
if ("type" in value && "handler" in value && value.type in WalkerEvent) {
|
|
345
365
|
if (value.type == WalkerEvent.Enter) {
|
|
346
366
|
if (!preVisitorsHandlersMap.has(key)) {
|
|
347
367
|
preVisitorsHandlersMap.set(key, []);
|
|
348
368
|
}
|
|
349
|
-
preVisitorsHandlersMap
|
|
369
|
+
preVisitorsHandlersMap
|
|
370
|
+
.get(key)
|
|
371
|
+
.push(value.handler);
|
|
350
372
|
}
|
|
351
373
|
else if (value.type == WalkerEvent.Leave) {
|
|
352
374
|
if (!postVisitorsHandlersMap.has(key)) {
|
|
353
375
|
postVisitorsHandlersMap.set(key, []);
|
|
354
376
|
}
|
|
355
|
-
postVisitorsHandlersMap
|
|
377
|
+
postVisitorsHandlersMap
|
|
378
|
+
.get(key)
|
|
379
|
+
.push(value.handler);
|
|
356
380
|
}
|
|
357
381
|
}
|
|
358
382
|
else {
|
|
359
383
|
if (!visitorsHandlersMap.has(key)) {
|
|
360
384
|
visitorsHandlersMap.set(key, []);
|
|
361
385
|
}
|
|
362
|
-
visitorsHandlersMap
|
|
386
|
+
visitorsHandlersMap
|
|
387
|
+
.get(key)
|
|
388
|
+
.push(value);
|
|
363
389
|
}
|
|
364
390
|
}
|
|
365
391
|
else {
|
|
366
|
-
errors.push({ action:
|
|
392
|
+
errors.push({ action: "ignore", message: `doParse: visitor.${key} is not a valid key name` });
|
|
367
393
|
}
|
|
368
394
|
}
|
|
369
395
|
else {
|
|
370
|
-
errors.push({ action:
|
|
396
|
+
errors.push({ action: "ignore", message: `doParse: visitor.${key} is not a valid key name` });
|
|
371
397
|
}
|
|
372
398
|
}
|
|
373
399
|
}
|
|
374
|
-
|
|
400
|
+
if (Array.isArray(iter)) {
|
|
401
|
+
// @ts-expect-error
|
|
402
|
+
iter = iter[Symbol.iterator]();
|
|
403
|
+
}
|
|
404
|
+
while ((item = isAsync
|
|
405
|
+
? // @ts-expect-error
|
|
406
|
+
(await iter.next()).value
|
|
407
|
+
: // @ts-expect-error
|
|
408
|
+
iter.next().value)) {
|
|
375
409
|
stats.bytesIn = item.bytesIn;
|
|
376
410
|
stats.tokensCount++;
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
411
|
+
if (options.sourcemap !== false) {
|
|
412
|
+
Object.defineProperty(item.token, "loc", {
|
|
413
|
+
...definedPropertySettings,
|
|
414
|
+
value: item.token.loc,
|
|
415
|
+
enumerable: true,
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
if (BadTokensTypes.includes(item.token.typ)) {
|
|
419
|
+
tokens.push(item.token);
|
|
380
420
|
errors.push({
|
|
381
|
-
action:
|
|
382
|
-
message:
|
|
421
|
+
action: "drop",
|
|
422
|
+
message: "Bad token",
|
|
383
423
|
syntax: null,
|
|
384
|
-
node,
|
|
385
|
-
location:
|
|
386
|
-
src,
|
|
387
|
-
sta: item.sta,
|
|
388
|
-
end: item.end
|
|
389
|
-
}
|
|
424
|
+
node: item.token,
|
|
425
|
+
location: item.token.loc,
|
|
390
426
|
});
|
|
391
427
|
// bad token
|
|
392
428
|
continue;
|
|
393
429
|
}
|
|
394
|
-
if (item.
|
|
395
|
-
|
|
430
|
+
if (item.token.typ === EnumToken.StartParensTokenType || tokensfuncDefMap.has(item.token.typ)) {
|
|
431
|
+
parensMatch++;
|
|
396
432
|
}
|
|
397
|
-
else if (
|
|
398
|
-
|
|
399
|
-
stack[i].loc.end = { ...item.end };
|
|
400
|
-
}
|
|
401
|
-
ast.loc.end = item.end;
|
|
433
|
+
else if (item.token.typ === EnumToken.EndParensTokenType && parensMatch > 0) {
|
|
434
|
+
parensMatch--;
|
|
402
435
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
436
|
+
tokens.push(item.token);
|
|
437
|
+
if ((parensMatch === 0 &&
|
|
438
|
+
(item.token.typ === EnumToken.SemiColonTokenType ||
|
|
439
|
+
item.token.typ === EnumToken.BlockStartTokenType)) ||
|
|
440
|
+
item.token.typ === EnumToken.EOFTokenType) {
|
|
441
|
+
node = parseNode(tokens, context, options, errors, stats);
|
|
406
442
|
if (node != null) {
|
|
407
|
-
if (
|
|
443
|
+
if ("chi" in node) {
|
|
408
444
|
stack.push(node);
|
|
409
445
|
context = node;
|
|
410
446
|
}
|
|
411
|
-
else if (node.typ == EnumToken.AtRuleNodeType && node.nam
|
|
447
|
+
else if (node.typ == EnumToken.AtRuleNodeType && node.nam === "import") {
|
|
412
448
|
imports.push(node);
|
|
413
449
|
}
|
|
414
450
|
}
|
|
415
|
-
else if (item.token ==
|
|
451
|
+
else if (item.token.typ == EnumToken.BlockStartTokenType) {
|
|
416
452
|
let inBlock = 1;
|
|
417
|
-
tokens = [item];
|
|
453
|
+
tokens = [item.token];
|
|
418
454
|
do {
|
|
419
|
-
item = isAsync
|
|
455
|
+
item = isAsync
|
|
456
|
+
? // @ts-expect-error
|
|
457
|
+
(await iter.next()).value
|
|
458
|
+
: // @ts-expect-error
|
|
459
|
+
iter.next().value;
|
|
420
460
|
if (item == null) {
|
|
421
461
|
break;
|
|
422
462
|
}
|
|
423
|
-
tokens.push(item);
|
|
424
|
-
if (item.token
|
|
463
|
+
tokens.push(item.token);
|
|
464
|
+
if (item.token.typ === EnumToken.BlockStartTokenType) {
|
|
425
465
|
inBlock++;
|
|
426
466
|
}
|
|
427
|
-
else if (item.token
|
|
467
|
+
else if (item.token.typ === EnumToken.BlockEndTokenType) {
|
|
428
468
|
inBlock--;
|
|
429
469
|
}
|
|
430
470
|
} while (inBlock != 0);
|
|
431
471
|
if (tokens.length > 0) {
|
|
432
472
|
errors.push({
|
|
433
|
-
action:
|
|
434
|
-
message:
|
|
435
|
-
rawTokens: tokens.slice(),
|
|
473
|
+
action: "drop",
|
|
474
|
+
message: "invalid block",
|
|
436
475
|
location: {
|
|
437
476
|
src,
|
|
438
|
-
sta: tokens[0].sta,
|
|
439
|
-
end: tokens[tokens.length - 1].end
|
|
440
|
-
}
|
|
477
|
+
sta: tokens[0].loc.sta,
|
|
478
|
+
end: tokens[tokens.length - 1].loc.end,
|
|
479
|
+
},
|
|
441
480
|
});
|
|
442
481
|
}
|
|
443
482
|
}
|
|
444
483
|
tokens = [];
|
|
445
|
-
map = new Map;
|
|
446
484
|
}
|
|
447
|
-
else if (item.token
|
|
448
|
-
parseNode(tokens, context, options, errors,
|
|
449
|
-
rawTokens.length = 0;
|
|
485
|
+
else if (item.token.typ === EnumToken.BlockEndTokenType) {
|
|
486
|
+
parseNode(tokens, context, options, errors, stats);
|
|
450
487
|
if (context.loc != null) {
|
|
451
|
-
context.loc.end = item.end;
|
|
488
|
+
context.loc.end = item.token.loc.end;
|
|
452
489
|
}
|
|
453
490
|
const previousNode = stack.pop();
|
|
454
491
|
context = (stack[stack.length - 1] ?? ast);
|
|
455
|
-
if (
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
492
|
+
if (options.removeEmpty &&
|
|
493
|
+
previousNode != null &&
|
|
494
|
+
previousNode.chi.length == 0 &&
|
|
495
|
+
context.chi[context.chi.length - 1] == previousNode) {
|
|
462
496
|
context.chi.pop();
|
|
463
497
|
}
|
|
464
498
|
tokens = [];
|
|
465
|
-
map = new Map;
|
|
466
499
|
}
|
|
467
500
|
}
|
|
468
501
|
if (tokens.length > 0) {
|
|
469
|
-
node = parseNode(tokens, context, options, errors,
|
|
470
|
-
rawTokens.length = 0;
|
|
502
|
+
node = parseNode(tokens, context, options, errors, stats);
|
|
471
503
|
if (node != null) {
|
|
472
|
-
if (node.typ == EnumToken.AtRuleNodeType && node.
|
|
504
|
+
if (node.typ == EnumToken.AtRuleNodeType && "import" === node.val) {
|
|
473
505
|
imports.push(node);
|
|
474
506
|
}
|
|
475
|
-
|
|
507
|
+
if ("chi" in node /* && node.typ != EnumToken.InvalidRuleNodeType */) {
|
|
476
508
|
stack.push(node);
|
|
477
509
|
context = node;
|
|
478
510
|
}
|
|
479
511
|
}
|
|
480
|
-
if (context != null && context.typ == EnumToken.InvalidRuleTokenType) {
|
|
481
|
-
// @ts-ignore ignore error
|
|
482
|
-
const index = context.chi.findIndex((node) => node === context);
|
|
483
|
-
if (index > -1) {
|
|
484
|
-
context.chi.splice(index, 1);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
512
|
}
|
|
488
513
|
if (imports.length > 0 && options.resolveImport) {
|
|
489
514
|
await Promise.all(imports.map(async (node) => {
|
|
@@ -491,17 +516,22 @@ async function doParse(iter, options = {}) {
|
|
|
491
516
|
const url = token.typ == EnumToken.StringTokenType ? token.val.slice(1, -1) : token.val;
|
|
492
517
|
try {
|
|
493
518
|
const result = options.load(url, options.src);
|
|
494
|
-
const stream = result instanceof Promise || Object.getPrototypeOf(result).constructor.name ==
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
519
|
+
const stream = result instanceof Promise || Object.getPrototypeOf(result).constructor.name == "AsyncFunction"
|
|
520
|
+
? await result
|
|
521
|
+
: result;
|
|
522
|
+
const root = await doParse(stream instanceof ReadableStream
|
|
523
|
+
? tokenizeStream(stream)
|
|
524
|
+
: tokenize({
|
|
525
|
+
stream,
|
|
526
|
+
src: options.resolve(url, options.src || options.cwd).relative,
|
|
527
|
+
buffer: "",
|
|
528
|
+
offset: 0,
|
|
529
|
+
position: { ind: 0, lin: 1, col: 1 },
|
|
530
|
+
currentPosition: { ind: -1, lin: 1, col: 0 },
|
|
531
|
+
}), Object.assign({}, options, {
|
|
502
532
|
minify: false,
|
|
503
533
|
setParent: false,
|
|
504
|
-
src: options.resolve(url, options.src).
|
|
534
|
+
src: options.resolve(url, options.src || options.cwd).relative,
|
|
505
535
|
}));
|
|
506
536
|
stats.importedBytesIn += root.stats.bytesIn;
|
|
507
537
|
stats.imports.push(root.stats);
|
|
@@ -512,7 +542,7 @@ async function doParse(iter, options = {}) {
|
|
|
512
542
|
}
|
|
513
543
|
catch (error) {
|
|
514
544
|
// @ts-ignore ignore error
|
|
515
|
-
errors.push({ action:
|
|
545
|
+
errors.push({ action: "ignore", message: ("doParse: " + error.message), error });
|
|
516
546
|
}
|
|
517
547
|
}));
|
|
518
548
|
}
|
|
@@ -520,10 +550,25 @@ async function doParse(iter, options = {}) {
|
|
|
520
550
|
const previousNode = stack.pop();
|
|
521
551
|
context = (stack[stack.length - 1] ?? ast);
|
|
522
552
|
// remove empty nodes
|
|
523
|
-
if (options.removeEmpty &&
|
|
553
|
+
if (options.removeEmpty &&
|
|
554
|
+
previousNode != null &&
|
|
555
|
+
previousNode.chi.length == 0 &&
|
|
556
|
+
context.chi[context.chi.length - 1] == previousNode) {
|
|
524
557
|
context.chi.pop();
|
|
525
558
|
continue;
|
|
526
559
|
}
|
|
560
|
+
// remove invalid nodes
|
|
561
|
+
if (!options.lenient &&
|
|
562
|
+
previousNode?.parent != null &&
|
|
563
|
+
// @ts-expect-error
|
|
564
|
+
(previousNode.typ == EnumToken.InvalidRuleNodeType || previousNode.typ == EnumToken.InvalidAtRuleNodeType)) {
|
|
565
|
+
for (let i = context.chi.length - 1; i >= 0; i--) {
|
|
566
|
+
if (context.chi[i] == previousNode) {
|
|
567
|
+
context.chi.splice(i, 1);
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
527
572
|
break;
|
|
528
573
|
}
|
|
529
574
|
const endParseTime = performance.now();
|
|
@@ -533,17 +578,35 @@ async function doParse(iter, options = {}) {
|
|
|
533
578
|
let replacement;
|
|
534
579
|
let callable;
|
|
535
580
|
if (options.visitor != null) {
|
|
581
|
+
let parens;
|
|
536
582
|
for (const result of walk(ast)) {
|
|
537
|
-
|
|
583
|
+
parens = null;
|
|
584
|
+
if (valuesHandlers.size > 0 ||
|
|
585
|
+
preVisitorsHandlersMap.size > 0 ||
|
|
586
|
+
visitorsHandlersMap.size > 0 ||
|
|
587
|
+
postVisitorsHandlersMap.size > 0) {
|
|
538
588
|
if ((result.node.typ == EnumToken.DeclarationNodeType &&
|
|
539
|
-
(preVisitorsHandlersMap.has(
|
|
540
|
-
|
|
541
|
-
|
|
589
|
+
(preVisitorsHandlersMap.has("Declaration") ||
|
|
590
|
+
visitorsHandlersMap.has("Declaration") ||
|
|
591
|
+
postVisitorsHandlersMap.has("Declaration"))) ||
|
|
592
|
+
(result.node.typ == EnumToken.AtRuleNodeType &&
|
|
593
|
+
(preVisitorsHandlersMap.has("AtRule") ||
|
|
594
|
+
visitorsHandlersMap.has("AtRule") ||
|
|
595
|
+
postVisitorsHandlersMap.has("AtRule"))) ||
|
|
596
|
+
(result.node.typ == EnumToken.KeyframesAtRuleNodeType &&
|
|
597
|
+
(preVisitorsHandlersMap.has("KeyframesAtRule") ||
|
|
598
|
+
visitorsHandlersMap.has("KeyframesAtRule") ||
|
|
599
|
+
postVisitorsHandlersMap.has("KeyframesAtRule")))) {
|
|
542
600
|
const handlers = [];
|
|
543
|
-
const key = result.node.typ == EnumToken.DeclarationNodeType
|
|
601
|
+
const key = result.node.typ == EnumToken.DeclarationNodeType
|
|
602
|
+
? "Declaration"
|
|
603
|
+
: result.node.typ == EnumToken.AtRuleNodeType
|
|
604
|
+
? "AtRule"
|
|
605
|
+
: "KeyframesAtRule";
|
|
544
606
|
if (preVisitorsHandlersMap.has(key)) {
|
|
545
|
-
|
|
546
|
-
|
|
607
|
+
handlers.push(
|
|
608
|
+
// @ts-expect-error
|
|
609
|
+
...preVisitorsHandlersMap.get(key));
|
|
547
610
|
}
|
|
548
611
|
if (visitorsHandlersMap.has(key)) {
|
|
549
612
|
// @ts-ignore
|
|
@@ -555,15 +618,30 @@ async function doParse(iter, options = {}) {
|
|
|
555
618
|
}
|
|
556
619
|
let node = result.node;
|
|
557
620
|
for (const handler of handlers) {
|
|
558
|
-
callable =
|
|
621
|
+
callable =
|
|
622
|
+
typeof handler == "function"
|
|
623
|
+
? handler
|
|
624
|
+
: handler[camelize(node.typ === EnumToken.DeclarationNodeType ||
|
|
625
|
+
node.typ === EnumToken.AtRuleNodeType
|
|
626
|
+
? node.nam
|
|
627
|
+
: node.val)];
|
|
559
628
|
if (callable == null) {
|
|
560
629
|
continue;
|
|
561
630
|
}
|
|
562
|
-
|
|
631
|
+
// @ts-expect-error
|
|
632
|
+
replacement = callable(node, result.parent, ast, function* () {
|
|
633
|
+
if (parens == null) {
|
|
634
|
+
// @ts-expect-error
|
|
635
|
+
parens = [...result.parents()];
|
|
636
|
+
}
|
|
637
|
+
yield* parens[Symbol.iterator]();
|
|
638
|
+
});
|
|
563
639
|
if (replacement == null) {
|
|
564
640
|
continue;
|
|
565
641
|
}
|
|
566
|
-
isAsync =
|
|
642
|
+
isAsync =
|
|
643
|
+
replacement instanceof Promise ||
|
|
644
|
+
Object.getPrototypeOf(replacement).constructor.name == "AsyncFunction";
|
|
567
645
|
if (replacement) {
|
|
568
646
|
replacement = await replacement;
|
|
569
647
|
}
|
|
@@ -572,20 +650,24 @@ async function doParse(iter, options = {}) {
|
|
|
572
650
|
}
|
|
573
651
|
// @ts-ignore
|
|
574
652
|
node = replacement;
|
|
575
|
-
//
|
|
576
653
|
if (Array.isArray(node)) {
|
|
577
654
|
break;
|
|
578
655
|
}
|
|
579
656
|
}
|
|
580
657
|
if (node != result.node) {
|
|
581
|
-
// @ts-ignore
|
|
582
658
|
replaceToken(result.parent, result.node, node);
|
|
583
659
|
}
|
|
584
660
|
}
|
|
585
|
-
else if ((result.node.typ == EnumToken.RuleNodeType &&
|
|
586
|
-
(
|
|
661
|
+
else if ((result.node.typ == EnumToken.RuleNodeType &&
|
|
662
|
+
(preVisitorsHandlersMap.has("Rule") ||
|
|
663
|
+
visitorsHandlersMap.has("Rule") ||
|
|
664
|
+
postVisitorsHandlersMap.has("Rule"))) ||
|
|
665
|
+
(result.node.typ == EnumToken.KeyFramesRuleNodeType &&
|
|
666
|
+
(preVisitorsHandlersMap.has("KeyframesRule") ||
|
|
667
|
+
visitorsHandlersMap.has("KeyframesRule") ||
|
|
668
|
+
postVisitorsHandlersMap.has("KeyframesRule")))) {
|
|
587
669
|
const handlers = [];
|
|
588
|
-
const key = result.node.typ == EnumToken.RuleNodeType ?
|
|
670
|
+
const key = result.node.typ == EnumToken.RuleNodeType ? "Rule" : "KeyframesRule";
|
|
589
671
|
if (preVisitorsHandlersMap.has(key)) {
|
|
590
672
|
handlers.push(...preVisitorsHandlersMap.get(key));
|
|
591
673
|
}
|
|
@@ -597,11 +679,21 @@ async function doParse(iter, options = {}) {
|
|
|
597
679
|
}
|
|
598
680
|
let node = result.node;
|
|
599
681
|
for (const callable of handlers) {
|
|
600
|
-
replacement = callable(node, result.parent
|
|
682
|
+
replacement = callable(node, result.parent, result.root,
|
|
683
|
+
// @ts-expect-error
|
|
684
|
+
function* () {
|
|
685
|
+
if (parens == null) {
|
|
686
|
+
// @ts-expect-error
|
|
687
|
+
parens = [...result.parents()];
|
|
688
|
+
}
|
|
689
|
+
yield* parens[Symbol.iterator]();
|
|
690
|
+
});
|
|
601
691
|
if (replacement == null) {
|
|
602
692
|
continue;
|
|
603
693
|
}
|
|
604
|
-
isAsync =
|
|
694
|
+
isAsync =
|
|
695
|
+
replacement instanceof Promise ||
|
|
696
|
+
Object.getPrototypeOf(replacement).constructor.name == "AsyncFunction";
|
|
605
697
|
if (replacement) {
|
|
606
698
|
replacement = await replacement;
|
|
607
699
|
}
|
|
@@ -627,11 +719,21 @@ async function doParse(iter, options = {}) {
|
|
|
627
719
|
if (valuesHandlers.has(node.typ)) {
|
|
628
720
|
for (const valueHandler of valuesHandlers.get(node.typ)) {
|
|
629
721
|
callable = valueHandler;
|
|
630
|
-
replacement = callable(node, result.parent
|
|
722
|
+
replacement = callable(node, result.parent, ast,
|
|
723
|
+
// @ts-expect-error
|
|
724
|
+
function* () {
|
|
725
|
+
if (parens == null) {
|
|
726
|
+
// @ts-expect-error
|
|
727
|
+
parens = [...result.parents()];
|
|
728
|
+
}
|
|
729
|
+
yield* parens[Symbol.iterator]();
|
|
730
|
+
});
|
|
631
731
|
if (replacement == null) {
|
|
632
732
|
continue;
|
|
633
733
|
}
|
|
634
|
-
isAsync =
|
|
734
|
+
isAsync =
|
|
735
|
+
replacement instanceof Promise ||
|
|
736
|
+
Object.getPrototypeOf(replacement).constructor.name == "AsyncFunction";
|
|
635
737
|
if (isAsync) {
|
|
636
738
|
replacement = await replacement;
|
|
637
739
|
}
|
|
@@ -644,30 +746,39 @@ async function doParse(iter, options = {}) {
|
|
|
644
746
|
// @ts-ignore
|
|
645
747
|
replaceToken(result.parent, value, node);
|
|
646
748
|
}
|
|
647
|
-
const tokens =
|
|
648
|
-
if (
|
|
749
|
+
const tokens = Array.isArray(result.node.tokens) ? result.node.tokens : [];
|
|
750
|
+
if (Array.isArray(result.node.val)) {
|
|
649
751
|
tokens.push(...result.node.val);
|
|
650
752
|
}
|
|
651
753
|
if (tokens.length == 0) {
|
|
652
754
|
continue;
|
|
653
755
|
}
|
|
654
|
-
for (const { value, parent, root } of walkValues(tokens, result.node)) {
|
|
756
|
+
for (const { value, parent, root, parents } of walkValues(tokens, result.node)) {
|
|
655
757
|
node = value;
|
|
656
758
|
if (valuesHandlers.has(node.typ)) {
|
|
759
|
+
let parens = null;
|
|
657
760
|
for (const valueHandler of valuesHandlers.get(node.typ)) {
|
|
658
761
|
callable = valueHandler;
|
|
659
|
-
|
|
762
|
+
// @ts-expect-error
|
|
763
|
+
let result = callable(node, parent, root, function* () {
|
|
764
|
+
if (parens == null) {
|
|
765
|
+
// @ts-expect-error
|
|
766
|
+
parens = [...parents()];
|
|
767
|
+
}
|
|
768
|
+
yield* parens[Symbol.iterator]();
|
|
769
|
+
});
|
|
660
770
|
if (result == null) {
|
|
661
771
|
continue;
|
|
662
772
|
}
|
|
663
|
-
isAsync =
|
|
773
|
+
isAsync =
|
|
774
|
+
result instanceof Promise ||
|
|
775
|
+
Object.getPrototypeOf(result).constructor.name == "AsyncFunction";
|
|
664
776
|
if (isAsync) {
|
|
665
777
|
result = await result;
|
|
666
778
|
}
|
|
667
779
|
if (result != null && result != node) {
|
|
668
780
|
node = result;
|
|
669
781
|
}
|
|
670
|
-
//
|
|
671
782
|
if (Array.isArray(node)) {
|
|
672
783
|
break;
|
|
673
784
|
}
|
|
@@ -699,32 +810,38 @@ async function doParse(iter, options = {}) {
|
|
|
699
810
|
...stats,
|
|
700
811
|
parse: `${(endParseTime - startTime).toFixed(2)}ms`,
|
|
701
812
|
minify: `${(endTime - endParseTime).toFixed(2)}ms`,
|
|
702
|
-
|
|
703
|
-
|
|
813
|
+
tokenize: `${(options?.parseInfo?.time ?? 0).toFixed(2)}ms`,
|
|
814
|
+
total: `${(endTime - startTime).toFixed(2)}ms`,
|
|
815
|
+
},
|
|
704
816
|
};
|
|
705
817
|
if (options.module) {
|
|
706
818
|
const moduleSettings = {
|
|
707
819
|
hashLength: 5,
|
|
708
|
-
filePath:
|
|
820
|
+
filePath: "",
|
|
709
821
|
scoped: ModuleScopeEnumOptions.Local,
|
|
710
822
|
naming: ModuleCaseTransformEnum.IgnoreCase,
|
|
711
|
-
pattern:
|
|
823
|
+
pattern: "",
|
|
712
824
|
generateScopedName,
|
|
713
|
-
...(typeof options.module !=
|
|
825
|
+
...(typeof options.module != "object" ? {} : options.module),
|
|
714
826
|
};
|
|
715
827
|
const parseModuleTime = performance.now();
|
|
716
828
|
const namesMapping = {};
|
|
717
|
-
const global = new Set;
|
|
718
|
-
const processed = new Set;
|
|
719
|
-
const pattern = typeof options.module ==
|
|
829
|
+
const global = new Set();
|
|
830
|
+
const processed = new Set();
|
|
831
|
+
const pattern = typeof options.module == "boolean" ? null : moduleSettings.pattern;
|
|
720
832
|
const importMapping = {};
|
|
721
833
|
const cssVariablesMap = {};
|
|
722
834
|
const importedCssVariables = {};
|
|
723
835
|
let mapping = {};
|
|
724
836
|
let revMapping = {};
|
|
725
|
-
let filePath = typeof options.module ==
|
|
726
|
-
|
|
727
|
-
|
|
837
|
+
let filePath = typeof options.module == "boolean"
|
|
838
|
+
? options.src
|
|
839
|
+
: (moduleSettings.filePath ?? options.src);
|
|
840
|
+
filePath =
|
|
841
|
+
filePath === ""
|
|
842
|
+
? options.src
|
|
843
|
+
: options.resolve(filePath, options.dirname(options.src), options.cwd).relative;
|
|
844
|
+
if (typeof options.module == "number") {
|
|
728
845
|
if (options.module & ModuleCaseTransformEnum.CamelCase) {
|
|
729
846
|
moduleSettings.naming = ModuleCaseTransformEnum.CamelCase;
|
|
730
847
|
}
|
|
@@ -744,44 +861,59 @@ async function doParse(iter, options = {}) {
|
|
|
744
861
|
// @ts-ignore
|
|
745
862
|
moduleSettings.scoped |= ModuleScopeEnumOptions.Pure;
|
|
746
863
|
}
|
|
864
|
+
if (options.module & ModuleScopeEnumOptions.Shortest) {
|
|
865
|
+
// @ts-ignore
|
|
866
|
+
moduleSettings.scoped |= ModuleScopeEnumOptions.Shortest;
|
|
867
|
+
}
|
|
747
868
|
if (options.module & ModuleScopeEnumOptions.ICSS) {
|
|
748
869
|
// @ts-ignore
|
|
749
870
|
moduleSettings.scoped |= ModuleScopeEnumOptions.ICSS;
|
|
750
871
|
}
|
|
751
872
|
}
|
|
752
|
-
if (typeof moduleSettings.scoped ==
|
|
753
|
-
moduleSettings.scoped = moduleSettings.scoped
|
|
873
|
+
if (typeof moduleSettings.scoped == "boolean") {
|
|
874
|
+
moduleSettings.scoped = moduleSettings.scoped
|
|
875
|
+
? ModuleScopeEnumOptions.Local
|
|
876
|
+
: ModuleScopeEnumOptions.Global;
|
|
877
|
+
}
|
|
878
|
+
if (moduleSettings.scoped & ModuleScopeEnumOptions.Shortest) {
|
|
879
|
+
moduleSettings.generateScopedName = getShortNameGenerator;
|
|
754
880
|
}
|
|
755
881
|
moduleSettings.filePath = filePath;
|
|
756
|
-
moduleSettings.pattern =
|
|
882
|
+
moduleSettings.pattern =
|
|
883
|
+
pattern != null && pattern !== "" ? pattern : filePath === "" ? `[local]_[hash]` : `[local]_[hash]_[name]`;
|
|
757
884
|
for (const { node, parent } of walk(ast)) {
|
|
758
885
|
if (node.typ == EnumToken.CssVariableImportTokenType) {
|
|
759
|
-
const url = node.val.find(t => t.typ == EnumToken.StringTokenType).val.slice(1, -1);
|
|
886
|
+
const url = node.val.find((t) => t.typ == EnumToken.StringTokenType).val.slice(1, -1);
|
|
760
887
|
const src = options.resolve(url, options.dirname(options.src), options.cwd);
|
|
761
888
|
const result = options.load(url, options.src);
|
|
762
|
-
const stream = result instanceof Promise || Object.getPrototypeOf(result).constructor.name ==
|
|
763
|
-
|
|
889
|
+
const stream = result instanceof Promise || Object.getPrototypeOf(result).constructor.name == "AsyncFunction"
|
|
890
|
+
? await result
|
|
891
|
+
: result;
|
|
892
|
+
const parseInfo = {
|
|
764
893
|
stream,
|
|
765
|
-
buffer:
|
|
894
|
+
buffer: "",
|
|
766
895
|
offset: 0,
|
|
896
|
+
time: 0,
|
|
767
897
|
position: { ind: 0, lin: 1, col: 1 },
|
|
768
|
-
currentPosition: { ind: -1, lin: 1, col: 0 }
|
|
769
|
-
}
|
|
898
|
+
currentPosition: { ind: -1, lin: 1, col: 0 },
|
|
899
|
+
};
|
|
900
|
+
const root = await doParse(stream instanceof ReadableStream ? tokenizeStream(stream, parseInfo) : tokenize(parseInfo), Object.assign({}, options, {
|
|
770
901
|
minify: false,
|
|
771
902
|
setParent: false,
|
|
772
|
-
src: src.relative
|
|
903
|
+
src: src.relative,
|
|
773
904
|
}));
|
|
905
|
+
options.parseInfo.time += parseInfo.time;
|
|
774
906
|
cssVariablesMap[node.nam] = root.cssModuleVariables;
|
|
775
907
|
parent.chi.splice(parent.chi.indexOf(node), 1);
|
|
776
908
|
continue;
|
|
777
909
|
}
|
|
778
910
|
if (node.typ == EnumToken.CssVariableDeclarationMapTokenType) {
|
|
779
|
-
const from = node.from.find(t => t.typ == EnumToken.IdenTokenType || isIdentColor(t));
|
|
911
|
+
const from = node.from.find((t) => t.typ == EnumToken.IdenTokenType || isIdentColor(t));
|
|
780
912
|
if (!(from.val in cssVariablesMap)) {
|
|
781
913
|
errors.push({
|
|
782
914
|
node,
|
|
783
915
|
message: `could not resolve @value import from '${from.val}'`,
|
|
784
|
-
action:
|
|
916
|
+
action: "drop",
|
|
785
917
|
});
|
|
786
918
|
}
|
|
787
919
|
else {
|
|
@@ -791,7 +923,7 @@ async function doParse(iter, options = {}) {
|
|
|
791
923
|
errors.push({
|
|
792
924
|
node,
|
|
793
925
|
message: `value '${token.val}' is not exported from '${from.val}'`,
|
|
794
|
-
action:
|
|
926
|
+
action: "drop",
|
|
795
927
|
});
|
|
796
928
|
continue;
|
|
797
929
|
}
|
|
@@ -814,29 +946,27 @@ async function doParse(iter, options = {}) {
|
|
|
814
946
|
continue;
|
|
815
947
|
}
|
|
816
948
|
if (node.typ == EnumToken.DeclarationNodeType) {
|
|
817
|
-
if (node.nam.startsWith(
|
|
949
|
+
if (node.nam.startsWith("--")) {
|
|
818
950
|
if (!(node.nam in namesMapping)) {
|
|
819
|
-
let result =
|
|
951
|
+
let result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
952
|
+
? node.nam
|
|
953
|
+
: moduleSettings.generateScopedName(node.nam, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
|
|
820
954
|
let value = result instanceof Promise ? await result : result;
|
|
821
|
-
mapping[node.nam] =
|
|
955
|
+
mapping[node.nam] =
|
|
956
|
+
"--" +
|
|
957
|
+
(moduleSettings.naming & ModuleCaseTransformEnum.DashCaseOnly ||
|
|
958
|
+
moduleSettings.naming & ModuleCaseTransformEnum.CamelCaseOnly
|
|
959
|
+
? getKeyName(value, moduleSettings.naming)
|
|
960
|
+
: value);
|
|
822
961
|
revMapping[node.nam] = node.nam;
|
|
823
962
|
}
|
|
824
963
|
node.nam = mapping[node.nam];
|
|
825
964
|
}
|
|
826
|
-
if (
|
|
965
|
+
if (equalsIgnoreCase("composes", node.nam)) {
|
|
827
966
|
const tokens = [];
|
|
828
|
-
let isValid = true;
|
|
967
|
+
// let isValid: boolean = true;
|
|
829
968
|
for (const token of node.val) {
|
|
830
969
|
if (token.typ == EnumToken.ComposesSelectorNodeType) {
|
|
831
|
-
if (!(token.r == null || token.r.typ == EnumToken.StringTokenType || token.r.typ == EnumToken.IdenTokenType)) {
|
|
832
|
-
errors.push({
|
|
833
|
-
action: 'drop',
|
|
834
|
-
message: `composes '${EnumToken[token.r.typ]}' is not supported`,
|
|
835
|
-
node
|
|
836
|
-
});
|
|
837
|
-
isValid = false;
|
|
838
|
-
break;
|
|
839
|
-
}
|
|
840
970
|
tokens.push(token);
|
|
841
971
|
}
|
|
842
972
|
}
|
|
@@ -845,14 +975,12 @@ async function doParse(iter, options = {}) {
|
|
|
845
975
|
while (parentRule != null && parentRule.typ != EnumToken.RuleNodeType) {
|
|
846
976
|
parentRule = parentRule.parent;
|
|
847
977
|
}
|
|
848
|
-
if (!isValid || tokens.length == 0) {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
});
|
|
855
|
-
}
|
|
978
|
+
if ( /* !isValid || */tokens.length == 0) {
|
|
979
|
+
errors.push({
|
|
980
|
+
action: "drop",
|
|
981
|
+
message: `composes is empty`,
|
|
982
|
+
node,
|
|
983
|
+
});
|
|
856
984
|
parentRule.chi.splice(parentRule.chi.indexOf(node), 1);
|
|
857
985
|
continue;
|
|
858
986
|
}
|
|
@@ -860,13 +988,21 @@ async function doParse(iter, options = {}) {
|
|
|
860
988
|
// composes: a b c;
|
|
861
989
|
if (token.r == null) {
|
|
862
990
|
for (const rule of token.l) {
|
|
863
|
-
if (rule.typ == EnumToken.WhitespaceTokenType ||
|
|
991
|
+
if (rule.typ == EnumToken.WhitespaceTokenType ||
|
|
992
|
+
rule.typ == EnumToken.CommentTokenType) {
|
|
864
993
|
continue;
|
|
865
994
|
}
|
|
866
995
|
if (!(rule.val in mapping)) {
|
|
867
|
-
let result =
|
|
996
|
+
let result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
997
|
+
? rule.val
|
|
998
|
+
: moduleSettings.generateScopedName(rule.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
|
|
868
999
|
let value = result instanceof Promise ? await result : result;
|
|
869
|
-
mapping[rule.val] =
|
|
1000
|
+
mapping[rule.val] =
|
|
1001
|
+
(rule.typ == EnumToken.DashedIdenTokenType ? "--" : "") +
|
|
1002
|
+
(moduleSettings.naming & ModuleCaseTransformEnum.DashCaseOnly ||
|
|
1003
|
+
moduleSettings.naming & ModuleCaseTransformEnum.CamelCaseOnly
|
|
1004
|
+
? getKeyName(value, moduleSettings.naming)
|
|
1005
|
+
: value);
|
|
870
1006
|
revMapping[mapping[rule.val]] = rule.val;
|
|
871
1007
|
}
|
|
872
1008
|
if (parentRule != null) {
|
|
@@ -875,7 +1011,12 @@ async function doParse(iter, options = {}) {
|
|
|
875
1011
|
const val = tk.val.slice(1);
|
|
876
1012
|
if (val in revMapping) {
|
|
877
1013
|
const key = revMapping[val];
|
|
878
|
-
mapping[key] = [
|
|
1014
|
+
mapping[key] = [
|
|
1015
|
+
...new Set([
|
|
1016
|
+
...mapping[key].split(" "),
|
|
1017
|
+
mapping[rule.val],
|
|
1018
|
+
]),
|
|
1019
|
+
].join(" ");
|
|
879
1020
|
}
|
|
880
1021
|
}
|
|
881
1022
|
}
|
|
@@ -887,19 +1028,25 @@ async function doParse(iter, options = {}) {
|
|
|
887
1028
|
const url = token.r.val.slice(1, -1);
|
|
888
1029
|
const src = options.resolve(url, options.dirname(options.src), options.cwd);
|
|
889
1030
|
const result = options.load(url, options.src);
|
|
890
|
-
const stream = result instanceof Promise ||
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
1031
|
+
const stream = result instanceof Promise ||
|
|
1032
|
+
Object.getPrototypeOf(result).constructor.name == "AsyncFunction"
|
|
1033
|
+
? await result
|
|
1034
|
+
: result;
|
|
1035
|
+
const root = await doParse(stream instanceof ReadableStream
|
|
1036
|
+
? tokenizeStream(stream)
|
|
1037
|
+
: tokenize({
|
|
1038
|
+
stream,
|
|
1039
|
+
buffer: "",
|
|
1040
|
+
offset: 0,
|
|
1041
|
+
position: { ind: 0, lin: 1, col: 1 },
|
|
1042
|
+
currentPosition: { ind: -1, lin: 1, col: 0 },
|
|
1043
|
+
}), Object.assign({}, options, {
|
|
898
1044
|
minify: false,
|
|
899
1045
|
setParent: false,
|
|
900
|
-
src: src.relative
|
|
1046
|
+
src: src.relative,
|
|
901
1047
|
}));
|
|
902
|
-
const srcIndex = (src.relative.startsWith(
|
|
1048
|
+
const srcIndex = (src.relative.startsWith("/") || src.relative.startsWith("../") ? "" : "./") +
|
|
1049
|
+
src.relative;
|
|
903
1050
|
if (Object.keys(root.mapping).length > 0) {
|
|
904
1051
|
importMapping[srcIndex] = {};
|
|
905
1052
|
}
|
|
@@ -911,19 +1058,27 @@ async function doParse(iter, options = {}) {
|
|
|
911
1058
|
const key = revMapping[val];
|
|
912
1059
|
const values = [];
|
|
913
1060
|
for (const iden of token.l) {
|
|
914
|
-
if (iden.typ != EnumToken.IdenTokenType &&
|
|
1061
|
+
if (iden.typ != EnumToken.IdenTokenType &&
|
|
1062
|
+
iden.typ != EnumToken.DashedIdenTokenType) {
|
|
915
1063
|
continue;
|
|
916
1064
|
}
|
|
917
1065
|
if (!(iden.val in root.mapping)) {
|
|
918
|
-
const result =
|
|
1066
|
+
const result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
1067
|
+
? iden.val
|
|
1068
|
+
: moduleSettings.generateScopedName(iden.val, srcIndex, moduleSettings.pattern, moduleSettings.hashLength);
|
|
919
1069
|
let value = result instanceof Promise ? await result : result;
|
|
920
|
-
root.mapping[iden.val] =
|
|
1070
|
+
root.mapping[iden.val] =
|
|
1071
|
+
moduleSettings.naming & ModuleCaseTransformEnum.DashCaseOnly ||
|
|
1072
|
+
moduleSettings.naming & ModuleCaseTransformEnum.CamelCaseOnly
|
|
1073
|
+
? getKeyName(value, moduleSettings.naming)
|
|
1074
|
+
: value;
|
|
921
1075
|
root.revMapping[root.mapping[iden.val]] = iden.val;
|
|
922
1076
|
}
|
|
923
|
-
importMapping[srcIndex][iden.val] =
|
|
1077
|
+
importMapping[srcIndex][iden.val] =
|
|
1078
|
+
root.mapping[iden.val];
|
|
924
1079
|
values.push(root.mapping[iden.val]);
|
|
925
1080
|
}
|
|
926
|
-
mapping[key] = [...new Set([...mapping[key].split(
|
|
1081
|
+
mapping[key] = [...new Set([...mapping[key].split(" "), ...values])].join(" ");
|
|
927
1082
|
}
|
|
928
1083
|
}
|
|
929
1084
|
}
|
|
@@ -933,27 +1088,32 @@ async function doParse(iter, options = {}) {
|
|
|
933
1088
|
else if (token.r.typ == EnumToken.IdenTokenType) {
|
|
934
1089
|
// global
|
|
935
1090
|
if (parentRule != null) {
|
|
936
|
-
if (
|
|
1091
|
+
if (equalsIgnoreCase("global", token.r.val)) {
|
|
937
1092
|
for (const tk of parentRule.tokens) {
|
|
938
1093
|
if (tk.typ == EnumToken.ClassSelectorTokenType) {
|
|
939
1094
|
const val = tk.val.slice(1);
|
|
940
1095
|
if (val in revMapping) {
|
|
941
1096
|
const key = revMapping[val];
|
|
942
|
-
mapping[key] = [
|
|
1097
|
+
mapping[key] = [
|
|
1098
|
+
...new Set([
|
|
1099
|
+
...mapping[key].split(" "),
|
|
1100
|
+
...token.l.reduce((acc, curr) => {
|
|
943
1101
|
if (curr.typ == EnumToken.IdenTokenType) {
|
|
944
1102
|
acc.push(curr.val);
|
|
945
1103
|
}
|
|
946
1104
|
return acc;
|
|
947
|
-
}, [])
|
|
1105
|
+
}, []),
|
|
1106
|
+
]),
|
|
1107
|
+
].join(" ");
|
|
948
1108
|
}
|
|
949
1109
|
}
|
|
950
1110
|
}
|
|
951
1111
|
}
|
|
952
1112
|
else {
|
|
953
1113
|
errors.push({
|
|
954
|
-
action:
|
|
1114
|
+
action: "drop",
|
|
955
1115
|
message: `composes '${token.r.val}' is not supported`,
|
|
956
|
-
node
|
|
1116
|
+
node,
|
|
957
1117
|
});
|
|
958
1118
|
}
|
|
959
1119
|
}
|
|
@@ -961,29 +1121,42 @@ async function doParse(iter, options = {}) {
|
|
|
961
1121
|
}
|
|
962
1122
|
parentRule.chi.splice(parentRule.chi.indexOf(node), 1);
|
|
963
1123
|
}
|
|
964
|
-
if (node.typ == EnumToken.DeclarationNodeType &&
|
|
1124
|
+
if (node.typ == EnumToken.DeclarationNodeType &&
|
|
1125
|
+
[
|
|
1126
|
+
"grid-column",
|
|
1127
|
+
"grid-column-start",
|
|
1128
|
+
"grid-column-end",
|
|
1129
|
+
"grid-row",
|
|
1130
|
+
"grid-row-start",
|
|
1131
|
+
"grid-row-end",
|
|
1132
|
+
"grid-template",
|
|
1133
|
+
"grid-template-columns",
|
|
1134
|
+
"grid-template-rows",
|
|
1135
|
+
].includes(node.nam)) {
|
|
965
1136
|
for (const { value } of walkValues(node.val, node)) {
|
|
966
1137
|
if (value.typ != EnumToken.IdenTokenType) {
|
|
967
1138
|
continue;
|
|
968
1139
|
}
|
|
969
1140
|
let idenToken = value.val;
|
|
970
|
-
let suffix =
|
|
971
|
-
if (idenToken.endsWith(
|
|
972
|
-
suffix =
|
|
1141
|
+
let suffix = "";
|
|
1142
|
+
if (idenToken.endsWith("-start")) {
|
|
1143
|
+
suffix = "-start";
|
|
973
1144
|
idenToken = idenToken.slice(0, -6);
|
|
974
1145
|
}
|
|
975
|
-
else if (idenToken.endsWith(
|
|
976
|
-
suffix =
|
|
1146
|
+
else if (idenToken.endsWith("-end")) {
|
|
1147
|
+
suffix = "-end";
|
|
977
1148
|
idenToken = idenToken.slice(0, -4);
|
|
978
1149
|
}
|
|
979
1150
|
if (!(idenToken in mapping)) {
|
|
980
|
-
let result =
|
|
1151
|
+
let result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
1152
|
+
? idenToken
|
|
1153
|
+
: moduleSettings.generateScopedName(idenToken, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
|
|
981
1154
|
if (result instanceof Promise) {
|
|
982
1155
|
result = await result;
|
|
983
1156
|
}
|
|
984
1157
|
mapping[idenToken] = result;
|
|
985
1158
|
revMapping[result] = idenToken;
|
|
986
|
-
if (suffix !==
|
|
1159
|
+
if (suffix !== "") {
|
|
987
1160
|
idenToken += suffix;
|
|
988
1161
|
if (!(idenToken in mapping)) {
|
|
989
1162
|
mapping[idenToken] = result + suffix;
|
|
@@ -994,17 +1167,22 @@ async function doParse(iter, options = {}) {
|
|
|
994
1167
|
value.val = mapping[idenToken];
|
|
995
1168
|
}
|
|
996
1169
|
}
|
|
997
|
-
else if (node.nam ==
|
|
1170
|
+
else if (node.nam == "grid-template-areas" || node.nam == "grid-template") {
|
|
998
1171
|
for (let i = 0; i < node.val.length; i++) {
|
|
999
1172
|
if (node.val[i].typ == EnumToken.String) {
|
|
1000
|
-
const tokens = parseString(node.val[i].val.slice(1, -1), {
|
|
1173
|
+
const tokens = parseString(node.val[i].val.slice(1, -1), {
|
|
1174
|
+
location: true,
|
|
1175
|
+
});
|
|
1001
1176
|
for (const { value } of walkValues(tokens)) {
|
|
1002
|
-
if (value.typ == EnumToken.IdenTokenType ||
|
|
1177
|
+
if (value.typ == EnumToken.IdenTokenType ||
|
|
1178
|
+
value.typ == EnumToken.DashedIdenTokenType) {
|
|
1003
1179
|
if (value.val in mapping) {
|
|
1004
1180
|
value.val = mapping[value.val];
|
|
1005
1181
|
}
|
|
1006
1182
|
else {
|
|
1007
|
-
let result =
|
|
1183
|
+
let result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
1184
|
+
? value.val
|
|
1185
|
+
: moduleSettings.generateScopedName(value.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
|
|
1008
1186
|
if (result instanceof Promise) {
|
|
1009
1187
|
result = await result;
|
|
1010
1188
|
}
|
|
@@ -1014,22 +1192,49 @@ async function doParse(iter, options = {}) {
|
|
|
1014
1192
|
}
|
|
1015
1193
|
}
|
|
1016
1194
|
}
|
|
1017
|
-
node.val[i].val =
|
|
1195
|
+
node.val[i].val =
|
|
1196
|
+
node.val[i].val.charAt(0) +
|
|
1197
|
+
renderTokens(tokens) +
|
|
1198
|
+
node.val[i].val.charAt(node.val[i].val.length - 1);
|
|
1018
1199
|
}
|
|
1019
1200
|
}
|
|
1020
1201
|
}
|
|
1021
|
-
else if (node.nam ==
|
|
1202
|
+
else if (node.nam == "animation" || node.nam == "animation-name") {
|
|
1022
1203
|
for (const { value } of walkValues(node.val, node)) {
|
|
1023
|
-
if (value.typ == EnumToken.IdenTokenType &&
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1204
|
+
if (value.typ == EnumToken.IdenTokenType &&
|
|
1205
|
+
![
|
|
1206
|
+
"none",
|
|
1207
|
+
"infinite",
|
|
1208
|
+
"normal",
|
|
1209
|
+
"reverse",
|
|
1210
|
+
"alternate",
|
|
1211
|
+
"alternate-reverse",
|
|
1212
|
+
"forwards",
|
|
1213
|
+
"backwards",
|
|
1214
|
+
"both",
|
|
1215
|
+
"running",
|
|
1216
|
+
"paused",
|
|
1217
|
+
"linear",
|
|
1218
|
+
"ease",
|
|
1219
|
+
"ease-in",
|
|
1220
|
+
"ease-out",
|
|
1221
|
+
"ease-in-out",
|
|
1222
|
+
"step-start",
|
|
1223
|
+
"step-end",
|
|
1224
|
+
"jump-start",
|
|
1225
|
+
"jump-end",
|
|
1226
|
+
"jump-none",
|
|
1227
|
+
"jump-both",
|
|
1228
|
+
"start",
|
|
1229
|
+
"end",
|
|
1230
|
+
"inherit",
|
|
1231
|
+
"initial",
|
|
1232
|
+
"unset",
|
|
1233
|
+
].includes(value.val)) {
|
|
1031
1234
|
if (!(value.val in mapping)) {
|
|
1032
|
-
const result =
|
|
1235
|
+
const result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
1236
|
+
? value.val
|
|
1237
|
+
: moduleSettings.generateScopedName(value.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
|
|
1033
1238
|
mapping[value.val] = result instanceof Promise ? await result : result;
|
|
1034
1239
|
revMapping[mapping[value.val]] = value.val;
|
|
1035
1240
|
}
|
|
@@ -1040,24 +1245,50 @@ async function doParse(iter, options = {}) {
|
|
|
1040
1245
|
for (const { value, parent } of walkValues(node.val, node)) {
|
|
1041
1246
|
if (value.typ == EnumToken.DashedIdenTokenType) {
|
|
1042
1247
|
if (!(value.val in mapping)) {
|
|
1043
|
-
const result =
|
|
1248
|
+
const result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
1249
|
+
? value.val
|
|
1250
|
+
: moduleSettings.generateScopedName(value.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
|
|
1044
1251
|
let val = result instanceof Promise ? await result : result;
|
|
1045
|
-
mapping[value.val] =
|
|
1252
|
+
mapping[value.val] =
|
|
1253
|
+
"--" +
|
|
1254
|
+
(moduleSettings.naming & ModuleCaseTransformEnum.DashCaseOnly ||
|
|
1255
|
+
moduleSettings.naming & ModuleCaseTransformEnum.CamelCaseOnly
|
|
1256
|
+
? getKeyName(val, moduleSettings.naming)
|
|
1257
|
+
: val);
|
|
1046
1258
|
revMapping[mapping[value.val]] = value.val;
|
|
1047
1259
|
}
|
|
1048
1260
|
value.val = mapping[value.val];
|
|
1049
1261
|
}
|
|
1050
|
-
else if ((value.typ == EnumToken.IdenTokenType || isIdentColor(value)) &&
|
|
1262
|
+
else if ((value.typ == EnumToken.IdenTokenType || isIdentColor(value)) &&
|
|
1263
|
+
value.val in importedCssVariables) {
|
|
1051
1264
|
replaceToken(parent, value, importedCssVariables[value.val].val);
|
|
1052
1265
|
}
|
|
1053
1266
|
}
|
|
1054
1267
|
}
|
|
1055
1268
|
else if (node.typ == EnumToken.RuleNodeType) {
|
|
1056
1269
|
if (node.tokens == null) {
|
|
1057
|
-
|
|
1270
|
+
const tokens = parseString(node.sel, { location: true });
|
|
1271
|
+
matchSelectorSyntax(tokens, [], options);
|
|
1272
|
+
Object.defineProperty(node, "tokens", {
|
|
1058
1273
|
...definedPropertySettings,
|
|
1059
|
-
value:
|
|
1274
|
+
value: trimArray(tokens),
|
|
1060
1275
|
});
|
|
1276
|
+
let i;
|
|
1277
|
+
const stack = [];
|
|
1278
|
+
for (i = 0; i < tokens.length; i++) {
|
|
1279
|
+
if (tokensfuncDefMap.has(tokens[i].typ)) {
|
|
1280
|
+
stack.push(tokens[i]);
|
|
1281
|
+
continue;
|
|
1282
|
+
}
|
|
1283
|
+
else if (tokens[i].typ == EnumToken.EndParensTokenType) {
|
|
1284
|
+
const func = stack.at(-1);
|
|
1285
|
+
tokens.splice(i, 1);
|
|
1286
|
+
// @ts-expect-error
|
|
1287
|
+
func.typ = tokensfuncDefMap.get(func.typ);
|
|
1288
|
+
func.chi = tokens.splice(tokens.indexOf(func) + 1, i - 1);
|
|
1289
|
+
stack.pop();
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1061
1292
|
}
|
|
1062
1293
|
let hasIdOrClass = false;
|
|
1063
1294
|
for (const { value } of walkValues(node.tokens, node,
|
|
@@ -1066,19 +1297,25 @@ async function doParse(iter, options = {}) {
|
|
|
1066
1297
|
if (value.typ == EnumToken.PseudoClassTokenType) {
|
|
1067
1298
|
const val = value.val.toLowerCase();
|
|
1068
1299
|
switch (val) {
|
|
1069
|
-
case
|
|
1070
|
-
case
|
|
1300
|
+
case ":local":
|
|
1301
|
+
case ":global":
|
|
1071
1302
|
{
|
|
1072
1303
|
let index = parent.tokens.indexOf(value);
|
|
1073
1304
|
parent.tokens.splice(index, 1);
|
|
1074
|
-
if (parent.tokens[index]?.typ == EnumToken.WhitespaceTokenType ||
|
|
1305
|
+
if (parent.tokens[index]?.typ == EnumToken.WhitespaceTokenType ||
|
|
1306
|
+
parent.tokens[index]?.typ ==
|
|
1307
|
+
EnumToken.DescendantCombinatorTokenType) {
|
|
1075
1308
|
parent.tokens.splice(index, 1);
|
|
1076
1309
|
}
|
|
1077
|
-
if (val ==
|
|
1310
|
+
if (val == ":global") {
|
|
1078
1311
|
for (; index < parent.tokens.length; index++) {
|
|
1079
|
-
if (parent.tokens[index].typ ==
|
|
1080
|
-
|
|
1081
|
-
|
|
1312
|
+
if (parent.tokens[index].typ ==
|
|
1313
|
+
EnumToken.CommaTokenType ||
|
|
1314
|
+
([
|
|
1315
|
+
EnumToken.PseudoClassFuncTokenType,
|
|
1316
|
+
EnumToken.PseudoClassTokenType,
|
|
1317
|
+
].includes(parent.tokens[index].typ) &&
|
|
1318
|
+
[":global", ":local"].includes(parent.tokens[index].val.toLowerCase()))) {
|
|
1082
1319
|
break;
|
|
1083
1320
|
}
|
|
1084
1321
|
global.add(parent.tokens[index]);
|
|
@@ -1090,13 +1327,13 @@ async function doParse(iter, options = {}) {
|
|
|
1090
1327
|
}
|
|
1091
1328
|
else if (value.typ == EnumToken.PseudoClassFuncTokenType) {
|
|
1092
1329
|
switch (value.val.toLowerCase()) {
|
|
1093
|
-
case
|
|
1330
|
+
case ":global":
|
|
1094
1331
|
for (const token of value.chi) {
|
|
1095
1332
|
global.add(token);
|
|
1096
1333
|
}
|
|
1097
1334
|
parent.tokens.splice(parent.tokens.indexOf(value), 1, ...value.chi);
|
|
1098
1335
|
break;
|
|
1099
|
-
case
|
|
1336
|
+
case ":local":
|
|
1100
1337
|
parent.tokens.splice(parent.tokens.indexOf(value), 1, ...value.chi);
|
|
1101
1338
|
break;
|
|
1102
1339
|
}
|
|
@@ -1118,21 +1355,27 @@ async function doParse(iter, options = {}) {
|
|
|
1118
1355
|
if (value.typ == EnumToken.ClassSelectorTokenType) {
|
|
1119
1356
|
const val = value.val.slice(1);
|
|
1120
1357
|
if (!(val in mapping)) {
|
|
1121
|
-
const result =
|
|
1358
|
+
const result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
1359
|
+
? val
|
|
1360
|
+
: moduleSettings.generateScopedName(val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
|
|
1122
1361
|
let value = result instanceof Promise ? await result : result;
|
|
1123
|
-
mapping[val] =
|
|
1362
|
+
mapping[val] =
|
|
1363
|
+
moduleSettings.naming & ModuleCaseTransformEnum.DashCaseOnly ||
|
|
1364
|
+
moduleSettings.naming & ModuleCaseTransformEnum.CamelCaseOnly
|
|
1365
|
+
? getKeyName(value, moduleSettings.naming)
|
|
1366
|
+
: value;
|
|
1124
1367
|
revMapping[mapping[val]] = val;
|
|
1125
1368
|
}
|
|
1126
|
-
value.val =
|
|
1369
|
+
value.val = "." + mapping[val];
|
|
1127
1370
|
}
|
|
1128
1371
|
}
|
|
1129
1372
|
}
|
|
1130
1373
|
if (moduleSettings.scoped & ModuleScopeEnumOptions.Pure) {
|
|
1131
1374
|
if (!hasIdOrClass) {
|
|
1132
|
-
throw new Error(`pure module: No id or class found in selector '${node.sel}' at '${node.loc?.src ??
|
|
1375
|
+
throw new Error(`pure module: No id or class found in selector '${node.sel}' at '${node.loc?.src ?? ""}':${node.loc?.sta?.lin ?? ""}:${node.loc?.sta?.col ?? ""}`);
|
|
1133
1376
|
}
|
|
1134
1377
|
}
|
|
1135
|
-
node.sel =
|
|
1378
|
+
node.sel = "";
|
|
1136
1379
|
for (const token of node.tokens) {
|
|
1137
1380
|
node.sel += renderToken(token);
|
|
1138
1381
|
}
|
|
@@ -1140,39 +1383,50 @@ async function doParse(iter, options = {}) {
|
|
|
1140
1383
|
else if (node.typ == EnumToken.AtRuleNodeType || node.typ == EnumToken.KeyframesAtRuleNodeType) {
|
|
1141
1384
|
const val = node.nam.toLowerCase();
|
|
1142
1385
|
if (node.tokens == null) {
|
|
1143
|
-
Object.defineProperty(node,
|
|
1386
|
+
Object.defineProperty(node, "tokens", {
|
|
1144
1387
|
...definedPropertySettings,
|
|
1145
1388
|
// @ts-ignore
|
|
1146
|
-
value:
|
|
1389
|
+
value: parseString(node.val),
|
|
1147
1390
|
});
|
|
1148
1391
|
}
|
|
1149
|
-
if (val ==
|
|
1150
|
-
const prefix = val ==
|
|
1392
|
+
if (val == "property" || val == "keyframes") {
|
|
1393
|
+
const prefix = val == "property" ? "--" : "";
|
|
1151
1394
|
for (const value of node.tokens) {
|
|
1152
|
-
if ((prefix ==
|
|
1395
|
+
if ((prefix == "--" && value.typ == EnumToken.DashedIdenTokenType) ||
|
|
1396
|
+
(prefix == "" && value.typ == EnumToken.IdenTokenType)) {
|
|
1153
1397
|
if (!(value.val in mapping)) {
|
|
1154
|
-
const result =
|
|
1398
|
+
const result = moduleSettings.scoped & ModuleScopeEnumOptions.Global
|
|
1399
|
+
? value.val
|
|
1400
|
+
: moduleSettings.generateScopedName(value.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
|
|
1155
1401
|
let val = result instanceof Promise ? await result : result;
|
|
1156
|
-
mapping[value.val] =
|
|
1402
|
+
mapping[value.val] =
|
|
1403
|
+
prefix +
|
|
1404
|
+
(moduleSettings.naming & ModuleCaseTransformEnum.DashCaseOnly ||
|
|
1405
|
+
moduleSettings.naming & ModuleCaseTransformEnum.CamelCaseOnly
|
|
1406
|
+
? getKeyName(val, moduleSettings.naming)
|
|
1407
|
+
: val);
|
|
1157
1408
|
revMapping[mapping[value.val]] = value.val;
|
|
1158
1409
|
}
|
|
1159
1410
|
value.val = mapping[value.val];
|
|
1160
1411
|
}
|
|
1161
1412
|
}
|
|
1162
|
-
node.val = node.tokens
|
|
1413
|
+
node.val = renderTokens(node.tokens);
|
|
1163
1414
|
}
|
|
1164
1415
|
else {
|
|
1165
1416
|
let isReplaced = false;
|
|
1166
1417
|
for (const { value, parent } of walkValues(node.tokens, node)) {
|
|
1167
|
-
if (EnumToken.MediaQueryConditionTokenType == parent.typ &&
|
|
1168
|
-
|
|
1418
|
+
if (EnumToken.MediaQueryConditionTokenType == parent.typ &&
|
|
1419
|
+
// @ts-expect-error
|
|
1420
|
+
value != parent.l) {
|
|
1421
|
+
if ((value.typ == EnumToken.IdenTokenType || isIdentColor(value)) &&
|
|
1422
|
+
value.val in importedCssVariables) {
|
|
1169
1423
|
isReplaced = true;
|
|
1170
1424
|
parent.r.splice(parent.r.indexOf(value), 1, ...importedCssVariables[value.val].val);
|
|
1171
1425
|
}
|
|
1172
1426
|
}
|
|
1173
1427
|
}
|
|
1174
1428
|
if (isReplaced) {
|
|
1175
|
-
node.val = node.tokens
|
|
1429
|
+
node.val = renderTokens(node.tokens);
|
|
1176
1430
|
}
|
|
1177
1431
|
}
|
|
1178
1432
|
}
|
|
@@ -1188,7 +1442,7 @@ async function doParse(iter, options = {}) {
|
|
|
1188
1442
|
}
|
|
1189
1443
|
result.mapping = mapping;
|
|
1190
1444
|
result.revMapping = revMapping;
|
|
1191
|
-
if (
|
|
1445
|
+
if (moduleSettings.scoped & ModuleScopeEnumOptions.ICSS && Object.keys(importMapping).length > 0) {
|
|
1192
1446
|
result.importMapping = importMapping;
|
|
1193
1447
|
}
|
|
1194
1448
|
endTime = performance.now();
|
|
@@ -1196,887 +1450,872 @@ async function doParse(iter, options = {}) {
|
|
|
1196
1450
|
result.stats.total = `${(endTime - startTime).toFixed(2)}ms`;
|
|
1197
1451
|
}
|
|
1198
1452
|
if (options.signal != null) {
|
|
1199
|
-
options.signal.removeEventListener(
|
|
1453
|
+
options.signal.removeEventListener("abort", reject);
|
|
1200
1454
|
}
|
|
1201
1455
|
return result;
|
|
1202
1456
|
}
|
|
1203
|
-
function
|
|
1204
|
-
let i =
|
|
1205
|
-
|
|
1206
|
-
|
|
1457
|
+
function parseNode(tokens, context, options, errors, stats) {
|
|
1458
|
+
let i = 0;
|
|
1459
|
+
if (tokens.at(-1)?.typ === EnumToken.EOFTokenType) {
|
|
1460
|
+
tokens.pop();
|
|
1461
|
+
// check parenthesis are balanced
|
|
1462
|
+
let matchCount = 0;
|
|
1463
|
+
let position = tokens.at(-1)?.loc;
|
|
1464
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
1465
|
+
const token = tokens[i];
|
|
1466
|
+
if (token.typ === EnumToken.StartParensTokenType || tokensfuncDefMap.has(token.typ)) {
|
|
1467
|
+
matchCount++;
|
|
1468
|
+
}
|
|
1469
|
+
else if (token.typ === EnumToken.EndParensTokenType) {
|
|
1470
|
+
matchCount--;
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
if (matchCount > 0) {
|
|
1474
|
+
while (matchCount > 0) {
|
|
1475
|
+
position = {
|
|
1476
|
+
...position,
|
|
1477
|
+
sta: { ...position.sta, ind: position.sta.ind + 1, col: position.sta.col + 1 },
|
|
1478
|
+
end: { ...position.end, ind: position.end.ind + 1, col: position.end.col + 1 },
|
|
1479
|
+
};
|
|
1480
|
+
tokens.push(Object.defineProperty({
|
|
1481
|
+
typ: EnumToken.EndParensTokenType,
|
|
1482
|
+
loc: tokens.at(-1)?.loc,
|
|
1483
|
+
}, "loc", {
|
|
1484
|
+
...definedPropertySettings,
|
|
1485
|
+
value: { ...position },
|
|
1486
|
+
}));
|
|
1487
|
+
matchCount--;
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
for (; i < tokens.length; i++) {
|
|
1492
|
+
if (tokens[i].typ === EnumToken.CDOCOMMTokenType && context.typ !== EnumToken.StyleSheetNodeType) {
|
|
1493
|
+
errors.push({
|
|
1494
|
+
action: "drop",
|
|
1495
|
+
message: `CDOCOMM not allowed here ${JSON.stringify(tokens[i], null, 1)}`,
|
|
1496
|
+
node: tokens[i],
|
|
1497
|
+
location: tokens[i].loc,
|
|
1498
|
+
});
|
|
1499
|
+
tokens[i].typ = EnumToken.InvalidCommentTokenType;
|
|
1207
1500
|
continue;
|
|
1208
1501
|
}
|
|
1209
|
-
|
|
1502
|
+
if (tokens[i].typ === EnumToken.CommentTokenType ||
|
|
1503
|
+
tokens[i].typ === EnumToken.CDOCOMMTokenType ||
|
|
1504
|
+
tokens[i].typ === EnumToken.WhitespaceTokenType) {
|
|
1505
|
+
continue;
|
|
1506
|
+
}
|
|
1507
|
+
break;
|
|
1210
1508
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
function parseNode(results, context, options, errors, src, map, rawTokens, stats) {
|
|
1214
|
-
let tokens = [];
|
|
1215
|
-
for (const t of results) {
|
|
1216
|
-
const node = getTokenType(t.token, t.hint);
|
|
1217
|
-
map.set(node, { sta: t.sta, end: t.end, src });
|
|
1218
|
-
tokens.push(node);
|
|
1509
|
+
if (i > 0) {
|
|
1510
|
+
context.chi.push(...tokens.splice(0, i).filter((n) => n.typ !== EnumToken.WhitespaceTokenType));
|
|
1219
1511
|
}
|
|
1220
|
-
|
|
1221
|
-
let loc;
|
|
1222
|
-
for (i = 0; i < tokens.length; i++) {
|
|
1512
|
+
for (; i < tokens.length; i++) {
|
|
1223
1513
|
if (tokens[i].typ == EnumToken.CommentTokenType || tokens[i].typ == EnumToken.CDOCOMMTokenType) {
|
|
1224
|
-
const location =
|
|
1514
|
+
const location = tokens[i]?.loc;
|
|
1225
1515
|
if (tokens[i].typ == EnumToken.CDOCOMMTokenType && context.typ != EnumToken.StyleSheetNodeType) {
|
|
1226
1516
|
errors.push({
|
|
1227
|
-
action:
|
|
1517
|
+
action: "drop",
|
|
1228
1518
|
message: `CDOCOMM not allowed here ${JSON.stringify(tokens[i], null, 1)}`,
|
|
1229
1519
|
node: tokens[i],
|
|
1230
|
-
location
|
|
1520
|
+
location,
|
|
1231
1521
|
});
|
|
1522
|
+
tokens[i].typ = EnumToken.InvalidCommentTokenType;
|
|
1232
1523
|
continue;
|
|
1233
1524
|
}
|
|
1234
|
-
loc = location;
|
|
1235
1525
|
context.chi.push(tokens[i]);
|
|
1236
1526
|
stats.nodesCount++;
|
|
1237
|
-
Object.defineProperty(tokens[i], 'loc', {
|
|
1238
|
-
...definedPropertySettings,
|
|
1239
|
-
value: loc,
|
|
1240
|
-
enumerable: options.sourcemap !== false
|
|
1241
|
-
});
|
|
1242
1527
|
}
|
|
1243
1528
|
else if (tokens[i].typ != EnumToken.WhitespaceTokenType) {
|
|
1244
1529
|
break;
|
|
1245
1530
|
}
|
|
1246
1531
|
}
|
|
1247
|
-
tokens = tokens.slice(i);
|
|
1248
1532
|
if (tokens.length == 0) {
|
|
1249
1533
|
return null;
|
|
1250
1534
|
}
|
|
1251
1535
|
let delim = tokens.at(-1);
|
|
1252
|
-
if (delim.typ == EnumToken.SemiColonTokenType ||
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
while ([EnumToken.WhitespaceTokenType, EnumToken.BadStringTokenType, EnumToken.BadCommentTokenType].includes(tokens.at(-1)?.typ)) {
|
|
1536
|
+
if (delim.typ == EnumToken.SemiColonTokenType ||
|
|
1537
|
+
delim.typ == EnumToken.BlockStartTokenType ||
|
|
1538
|
+
delim.typ == EnumToken.BlockEndTokenType) {
|
|
1256
1539
|
tokens.pop();
|
|
1257
1540
|
}
|
|
1258
1541
|
if (tokens.length == 0) {
|
|
1259
1542
|
return null;
|
|
1260
1543
|
}
|
|
1261
1544
|
if (tokens[0]?.typ == EnumToken.AtRuleTokenType) {
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
while (
|
|
1266
|
-
|
|
1545
|
+
let nestedRule = false;
|
|
1546
|
+
let parent = context;
|
|
1547
|
+
let node;
|
|
1548
|
+
while (parent != null) {
|
|
1549
|
+
if (parent.typ == EnumToken.RuleNodeType) {
|
|
1550
|
+
nestedRule = true;
|
|
1551
|
+
break;
|
|
1552
|
+
}
|
|
1553
|
+
parent = parent.parent;
|
|
1267
1554
|
}
|
|
1268
|
-
|
|
1269
|
-
if (
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
}
|
|
1555
|
+
node = parseAtRule(tokens, context, { ...options, nestedRule }, errors, delim.typ == EnumToken.BlockStartTokenType);
|
|
1556
|
+
if (node == null) {
|
|
1557
|
+
return null;
|
|
1558
|
+
}
|
|
1559
|
+
stats.nodesCount++;
|
|
1560
|
+
context.chi.push(node);
|
|
1561
|
+
// @ts-expect-error
|
|
1562
|
+
return Object.defineProperty(node, "parent", { ...definedPropertySettings, value: context });
|
|
1563
|
+
}
|
|
1564
|
+
else {
|
|
1565
|
+
stats.nodesCount++;
|
|
1566
|
+
// rule
|
|
1567
|
+
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
1568
|
+
const node = parseSelector(tokens, context, options, errors);
|
|
1569
|
+
context.chi.push(node);
|
|
1570
|
+
Object.defineProperty(node, "parent", { ...definedPropertySettings, value: context });
|
|
1571
|
+
return node;
|
|
1572
|
+
}
|
|
1573
|
+
else {
|
|
1574
|
+
const node = parseDeclaration(tokens, context, options, errors);
|
|
1575
|
+
Object.defineProperty(node, "parent", { ...definedPropertySettings, value: context });
|
|
1576
|
+
if (context.typ === EnumToken.StyleSheetNodeType && node.typ === EnumToken.DeclarationNodeType) {
|
|
1577
|
+
// @ts-expect-error
|
|
1578
|
+
node.typ = EnumToken.InvalidDeclarationNodeType;
|
|
1579
|
+
errors.push({
|
|
1580
|
+
message: "<declaration> not allowed in <stylesheet>",
|
|
1581
|
+
action: "drop",
|
|
1582
|
+
node,
|
|
1583
|
+
location: node.loc,
|
|
1584
|
+
});
|
|
1299
1585
|
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1586
|
+
else if (options.lenient || node.typ === EnumToken.DeclarationNodeType) {
|
|
1587
|
+
context.chi.push(node);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
return null;
|
|
1592
|
+
}
|
|
1593
|
+
/**mjgvgyikjkml,kmbm b8790u89y70
|
|
1594
|
+
vbbnkit;;;jmjhyg77 * @param options
|
|
1595
|
+
* @param errors
|
|
1596
|
+
* @param parseAsBlock
|
|
1597
|
+
*/
|
|
1598
|
+
function parseAtRule(stream, context, options, errors, parseAsBlock = null) {
|
|
1599
|
+
// const rules = getSyntaxRule(ValidationSyntaxGroupEnum.AtRules, "@" + (stream[0] as AtRuleToken).nam);
|
|
1600
|
+
let success = true;
|
|
1601
|
+
let atRuleName = stream[0].nam;
|
|
1602
|
+
if (atRuleName.startsWith("-")) {
|
|
1603
|
+
atRuleName = atRuleName.replace(/^-[a-z]+-/, "").toLowerCase();
|
|
1604
|
+
}
|
|
1605
|
+
const atRule = stream.shift();
|
|
1606
|
+
const syntaxRules = getSyntaxRule(ValidationSyntaxGroupEnum.AtRules, "@" + atRule.nam);
|
|
1607
|
+
const syntax = syntaxRules?.getPreludeRules()?.slice?.(1);
|
|
1608
|
+
const blockAllowed = syntaxRules?.getBlockRules() != null;
|
|
1609
|
+
if (syntaxRules == null) {
|
|
1610
|
+
if (!options.lenient) {
|
|
1611
|
+
errors.push({
|
|
1612
|
+
action: "drop",
|
|
1613
|
+
node: atRule,
|
|
1614
|
+
location: atRule.loc,
|
|
1615
|
+
message: "unknown at-rule",
|
|
1616
|
+
});
|
|
1617
|
+
// @ts-expect-error
|
|
1618
|
+
return {
|
|
1619
|
+
...atRule,
|
|
1620
|
+
typ: EnumToken.InvalidRuleNodeType,
|
|
1621
|
+
val: renderTokens(trimArray(stream), options),
|
|
1622
|
+
...(parseAsBlock ? { chi: [] } : {}),
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
else if (context.typ === EnumToken.AtRuleNodeType &&
|
|
1627
|
+
"page" === context.nam &&
|
|
1628
|
+
pageMarginBoxType.has(atRuleName.toLowerCase())) {
|
|
1629
|
+
if (parseAsBlock === false) {
|
|
1630
|
+
errors.push({
|
|
1631
|
+
action: "drop",
|
|
1632
|
+
node: atRule,
|
|
1633
|
+
location: atRule.loc,
|
|
1634
|
+
message: parseAsBlock ? "at-rule block not supported" : "at-rule block is required",
|
|
1635
|
+
});
|
|
1636
|
+
// @ts-expect-error
|
|
1637
|
+
return {
|
|
1638
|
+
...atRule,
|
|
1639
|
+
typ: EnumToken.InvalidRuleNodeType,
|
|
1640
|
+
val: renderTokens(trimArray(stream), options),
|
|
1641
|
+
...(parseAsBlock ? { chi: [] } : {}),
|
|
1642
|
+
};
|
|
1643
|
+
}
|
|
1644
|
+
const token = stream.find((t) => t.typ != EnumToken.WhitespaceTokenType && t.typ === EnumToken.CommentTokenType) ?? null;
|
|
1645
|
+
if (token != null) {
|
|
1646
|
+
errors.push({
|
|
1647
|
+
action: "drop",
|
|
1648
|
+
node: token,
|
|
1649
|
+
location: token.loc,
|
|
1650
|
+
message: `unexpected token ${EnumToken[token.typ]} at ${token.loc.src}:${token.loc.sta.lin}:${token.loc.sta.col}`,
|
|
1651
|
+
});
|
|
1652
|
+
// @ts-expect-error
|
|
1653
|
+
return {
|
|
1654
|
+
...atRule,
|
|
1655
|
+
typ: EnumToken.InvalidRuleNodeType,
|
|
1656
|
+
val: renderTokens(trimArray(stream), options),
|
|
1657
|
+
...(parseAsBlock ? { chi: [] } : {}),
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
if (parseAsBlock === null) {
|
|
1662
|
+
parseAsBlock = blockAllowed;
|
|
1663
|
+
}
|
|
1664
|
+
if (syntax != null && atRule.nam !== "layer" && parseAsBlock !== blockAllowed) {
|
|
1665
|
+
success = false;
|
|
1666
|
+
errors.push({
|
|
1667
|
+
action: "drop",
|
|
1668
|
+
node: atRule,
|
|
1669
|
+
location: atRule.loc,
|
|
1670
|
+
message: parseAsBlock ? "at-rule block not supported" : "at-rule block is required",
|
|
1671
|
+
});
|
|
1672
|
+
// @ts-expect-error
|
|
1673
|
+
return {
|
|
1674
|
+
...atRule,
|
|
1675
|
+
typ: EnumToken.InvalidRuleNodeType,
|
|
1676
|
+
val: renderTokens(trimArray(stream), options),
|
|
1677
|
+
...(parseAsBlock ? { chi: [] } : {}),
|
|
1678
|
+
};
|
|
1679
|
+
}
|
|
1680
|
+
switch (atRuleName) {
|
|
1681
|
+
case "charset": {
|
|
1682
|
+
let success = true;
|
|
1683
|
+
if (stream.length === 0 ||
|
|
1684
|
+
stream[0].typ !== EnumToken.WhitespaceTokenType ||
|
|
1685
|
+
stream[0].val !== " ") {
|
|
1686
|
+
success = false;
|
|
1302
1687
|
errors.push({
|
|
1303
|
-
action:
|
|
1304
|
-
|
|
1305
|
-
location
|
|
1688
|
+
action: "drop",
|
|
1689
|
+
node: stream[0] ?? atRule,
|
|
1690
|
+
location: (stream[0] ?? atRule).loc,
|
|
1691
|
+
message: "expecting <space>",
|
|
1306
1692
|
});
|
|
1307
|
-
return null;
|
|
1308
1693
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1694
|
+
else if (stream[1].typ !== EnumToken.StringTokenType) {
|
|
1695
|
+
success = false;
|
|
1696
|
+
errors.push({
|
|
1697
|
+
action: "drop",
|
|
1698
|
+
node: stream[1] ?? atRule,
|
|
1699
|
+
location: (stream[1] ?? atRule).loc,
|
|
1700
|
+
message: "expecting <string>",
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
if (success && stream[1].val.charCodeAt(0) !== 0x22) {
|
|
1704
|
+
success = false;
|
|
1311
1705
|
errors.push({
|
|
1312
|
-
action:
|
|
1313
|
-
|
|
1314
|
-
location
|
|
1706
|
+
action: "drop",
|
|
1707
|
+
node: stream[1] ?? atRule,
|
|
1708
|
+
location: (stream[1] ?? atRule).loc,
|
|
1709
|
+
message: "expecting double-quoted string",
|
|
1315
1710
|
});
|
|
1711
|
+
}
|
|
1712
|
+
if (success && options.removeCharset) {
|
|
1316
1713
|
return null;
|
|
1317
1714
|
}
|
|
1715
|
+
// @ts-expect-error
|
|
1716
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1717
|
+
typ: success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
1718
|
+
val: renderTokens(trimArray(stream), options),
|
|
1719
|
+
}), {
|
|
1720
|
+
loc: {
|
|
1721
|
+
...definedPropertySettings,
|
|
1722
|
+
value: { ...atRule.loc, end: (stream.at(-1) ?? atRule).loc.end },
|
|
1723
|
+
},
|
|
1724
|
+
tokens: { ...definedPropertySettings, value: stream },
|
|
1725
|
+
});
|
|
1318
1726
|
}
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
if (
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1727
|
+
case "font-feature-values": {
|
|
1728
|
+
const result = parseAtRuleFontFeatureValues(stream, atRule, options);
|
|
1729
|
+
if (result.errors.length > 0) {
|
|
1730
|
+
errors.push(...result.errors);
|
|
1731
|
+
}
|
|
1732
|
+
// @ts-expect-error
|
|
1733
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1734
|
+
typ: result.success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
1735
|
+
val: renderTokens(trimWhiteSpaceTokens(stream), options),
|
|
1736
|
+
chi: [],
|
|
1737
|
+
}), {
|
|
1738
|
+
loc: {
|
|
1739
|
+
...definedPropertySettings,
|
|
1740
|
+
value: { ...atRule.loc, end: (stream.at(-1) ?? atRule).loc.end },
|
|
1741
|
+
},
|
|
1742
|
+
tokens: { ...definedPropertySettings, value: stream },
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
case "stylistic":
|
|
1746
|
+
case "historical-forms":
|
|
1747
|
+
case "character-variant":
|
|
1748
|
+
case "swash":
|
|
1749
|
+
case "ornaments":
|
|
1750
|
+
case "annotation": {
|
|
1751
|
+
let success = context.typ === EnumToken.AtRuleNodeType && "font-feature-values" === context.nam;
|
|
1752
|
+
if (!success) {
|
|
1753
|
+
errors.push({
|
|
1754
|
+
action: "drop",
|
|
1755
|
+
node: atRule,
|
|
1756
|
+
location: atRule.loc,
|
|
1757
|
+
message: `unexpected at-rule ${atRule.nam}`,
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
if (success) {
|
|
1761
|
+
for (const token of stream) {
|
|
1762
|
+
if (token.typ !== EnumToken.CommentTokenType && token.typ !== EnumToken.WhitespaceTokenType) {
|
|
1763
|
+
success = false;
|
|
1764
|
+
errors.push({
|
|
1765
|
+
action: "drop",
|
|
1766
|
+
node: token,
|
|
1767
|
+
location: token.loc,
|
|
1768
|
+
message: `unexpected token ${EnumToken[token.typ]} at ${token.loc.src}:${token.loc.sta.lin}:${token.loc.sta.col}`,
|
|
1769
|
+
});
|
|
1333
1770
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
// @ts-expect-error
|
|
1774
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1775
|
+
typ: success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
1776
|
+
val: renderTokens(trimWhiteSpaceTokens(stream), options),
|
|
1777
|
+
chi: [],
|
|
1778
|
+
}), {
|
|
1779
|
+
loc: {
|
|
1780
|
+
...definedPropertySettings,
|
|
1781
|
+
value: { ...atRule.loc, end: (stream.at(-1) ?? atRule).loc.end },
|
|
1782
|
+
},
|
|
1783
|
+
tokens: { ...definedPropertySettings, value: stream },
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
case "container": {
|
|
1787
|
+
const result = parseAtRuleContainerQueryList(stream, atRule, options);
|
|
1788
|
+
if (result.errors.length > 0) {
|
|
1789
|
+
errors.push(...result.errors);
|
|
1790
|
+
}
|
|
1791
|
+
// @ts-expect-error
|
|
1792
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1793
|
+
typ: result.success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
1794
|
+
val: renderTokens(trimWhiteSpaceTokens(stream), options),
|
|
1795
|
+
chi: [],
|
|
1796
|
+
}), {
|
|
1797
|
+
loc: {
|
|
1798
|
+
...definedPropertySettings,
|
|
1799
|
+
value: { ...atRule.loc, end: (stream.at(-1) ?? atRule).loc.end },
|
|
1800
|
+
},
|
|
1801
|
+
tokens: { ...definedPropertySettings, value: stream },
|
|
1802
|
+
});
|
|
1803
|
+
}
|
|
1804
|
+
case "custom-media": {
|
|
1805
|
+
const tokens = trimArray(stream.slice(1));
|
|
1806
|
+
const result = matchAllSyntax(syntax, createValidationContext(tokens), options);
|
|
1807
|
+
if (result.errors.length > 0) {
|
|
1808
|
+
errors.push(...result.errors);
|
|
1809
|
+
}
|
|
1810
|
+
// @ts-expect-error
|
|
1811
|
+
options = { ...options, convertColor: false };
|
|
1812
|
+
// @ts-expect-error
|
|
1813
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1814
|
+
typ: result.success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
1815
|
+
val: renderTokens(trimWhiteSpaceTokens(tokens), options),
|
|
1816
|
+
}), {
|
|
1817
|
+
loc: {
|
|
1818
|
+
...definedPropertySettings,
|
|
1819
|
+
value: { ...atRule.loc, end: (tokens.at(-1) ?? atRule).loc.end },
|
|
1820
|
+
},
|
|
1821
|
+
tokens: { ...definedPropertySettings, value: tokens },
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
case "keyframes": {
|
|
1825
|
+
const tokens = trimArray(stream.slice(1));
|
|
1826
|
+
const filtered = stream.filter((t) => t.typ !== EnumToken.WhitespaceTokenType && t.typ !== EnumToken.CommentTokenType);
|
|
1827
|
+
if (filtered.length != 1 ||
|
|
1828
|
+
(filtered[0].typ !== EnumToken.IdenTokenType &&
|
|
1829
|
+
filtered[0].typ !== EnumToken.StringTokenType &&
|
|
1830
|
+
filtered[0].typ !== EnumToken.DashedIdenTokenType)) {
|
|
1831
|
+
errors.push({
|
|
1832
|
+
action: "drop",
|
|
1833
|
+
node: atRule,
|
|
1834
|
+
location: atRule.loc,
|
|
1835
|
+
message: `expected <keyframe-name> at ${atRule.loc.src}:${atRule.loc.sta.lin}:${atRule.loc.sta.col}`,
|
|
1836
|
+
});
|
|
1837
|
+
success = false;
|
|
1838
|
+
}
|
|
1839
|
+
// @ts-expect-error
|
|
1840
|
+
options = { ...options, convertColor: false };
|
|
1841
|
+
// @ts-expect-error
|
|
1842
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1843
|
+
typ: success ? EnumToken.KeyframesAtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
1844
|
+
val: renderTokens(tokens, options),
|
|
1845
|
+
chi: [],
|
|
1846
|
+
}), {
|
|
1847
|
+
loc: {
|
|
1848
|
+
...definedPropertySettings,
|
|
1849
|
+
value: { ...atRule.loc, end: (tokens.at(-1) ?? atRule).loc.end },
|
|
1850
|
+
},
|
|
1851
|
+
tokens: { ...definedPropertySettings, value: tokens },
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
case "namespace": {
|
|
1855
|
+
const result = matchAllSyntax(syntax, createValidationContext(stream), options);
|
|
1856
|
+
if (!result.success) {
|
|
1857
|
+
errors.push(...result.errors);
|
|
1858
|
+
}
|
|
1859
|
+
const valid = blockAllowed === parseAsBlock && result.success;
|
|
1860
|
+
if (valid) {
|
|
1861
|
+
let start = 0;
|
|
1862
|
+
let end = -1;
|
|
1863
|
+
let hasString = false;
|
|
1864
|
+
for (start = 0; start < stream.length; start++) {
|
|
1865
|
+
if (stream[start].typ == EnumToken.UrlFunctionTokenDefType) {
|
|
1866
|
+
start++;
|
|
1867
|
+
for (end = start; end < stream.length; end++) {
|
|
1868
|
+
if (stream[end].typ == EnumToken.EndParensTokenType) {
|
|
1869
|
+
break;
|
|
1870
|
+
}
|
|
1871
|
+
if (stream[end].typ === EnumToken.StringTokenType) {
|
|
1872
|
+
hasString = true;
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
break;
|
|
1337
1876
|
}
|
|
1338
1877
|
}
|
|
1878
|
+
// replace url(string) -> string
|
|
1879
|
+
if (hasString) {
|
|
1880
|
+
stream.splice(start - 1, end - start + 2, ...stream.slice(start, end));
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
// @ts-expect-error
|
|
1884
|
+
options = { ...options, convertColor: false };
|
|
1885
|
+
// @ts-expect-error
|
|
1886
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1887
|
+
typ: valid ? EnumToken.AtRuleNodeType : EnumToken.InvalidAtRuleNodeType,
|
|
1888
|
+
val: trimArray(stream).reduce((acc, t, index) => acc +
|
|
1889
|
+
(t.typ === EnumToken.CommentTokenType ||
|
|
1890
|
+
(t.typ === EnumToken.WhitespaceTokenType &&
|
|
1891
|
+
stream[index + 1]?.typ === EnumToken.CommentTokenType &&
|
|
1892
|
+
(stream.length < index + 3 || stream[index + 2]?.typ === EnumToken.WhitespaceTokenType))
|
|
1893
|
+
? ""
|
|
1894
|
+
: renderToken(t, options)), ""),
|
|
1895
|
+
...(parseAsBlock ? { chi: [] } : {}),
|
|
1896
|
+
}), {
|
|
1897
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
1898
|
+
loc: {
|
|
1899
|
+
...definedPropertySettings,
|
|
1900
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
1901
|
+
},
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
case "import": {
|
|
1905
|
+
const result = matchAtRuleImportSyntax(atRule, stream, context, options);
|
|
1906
|
+
if (result.errors.length > 0) {
|
|
1907
|
+
errors.push(...result.errors);
|
|
1339
1908
|
}
|
|
1909
|
+
else {
|
|
1910
|
+
if (stream[0]?.typ == EnumToken.UrlFunctionTokenType &&
|
|
1911
|
+
stream[0].chi.some((t) => t.typ == EnumToken.StringTokenType)) {
|
|
1912
|
+
stream.splice(0, 1, ...stream[0].chi);
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
// @ts-expect-error
|
|
1916
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1917
|
+
typ: result.success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
1918
|
+
val: stream.reduce((acc, t, index) => acc +
|
|
1919
|
+
(t.typ === EnumToken.CommentTokenType ||
|
|
1920
|
+
(t.typ === EnumToken.WhitespaceTokenType &&
|
|
1921
|
+
stream[index + 1]?.typ === EnumToken.CommentTokenType &&
|
|
1922
|
+
(stream.length < index + 3 || stream[index + 2]?.typ === EnumToken.WhitespaceTokenType))
|
|
1923
|
+
? ""
|
|
1924
|
+
: renderToken(t, options)), ""),
|
|
1925
|
+
}), {
|
|
1926
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
1927
|
+
loc: {
|
|
1928
|
+
...definedPropertySettings,
|
|
1929
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
1930
|
+
},
|
|
1931
|
+
});
|
|
1340
1932
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1933
|
+
case "supports":
|
|
1934
|
+
case "when":
|
|
1935
|
+
case "else": {
|
|
1936
|
+
trimWhiteSpaceTokens(stream);
|
|
1937
|
+
const result = atRuleName === "supports"
|
|
1938
|
+
? parseAtRuleSupportSyntax(stream, atRule, options)
|
|
1939
|
+
: matchAtRuleWhenElseSyntax(stream, atRule, options);
|
|
1940
|
+
if (result.errors.length > 0) {
|
|
1941
|
+
errors.push(...result.errors);
|
|
1942
|
+
}
|
|
1943
|
+
let success = true;
|
|
1944
|
+
if (atRule.nam === "else") {
|
|
1945
|
+
const siblings = context.chi;
|
|
1946
|
+
let sibling = null;
|
|
1947
|
+
let l = siblings.length;
|
|
1948
|
+
while (l--) {
|
|
1949
|
+
if (siblings[l].typ === EnumToken.WhitespaceTokenType ||
|
|
1950
|
+
siblings[l].typ === EnumToken.CommentTokenType ||
|
|
1951
|
+
siblings[l].typ === EnumToken.CDOCOMMTokenType) {
|
|
1952
|
+
continue;
|
|
1953
|
+
}
|
|
1954
|
+
sibling = siblings[l];
|
|
1955
|
+
break;
|
|
1351
1956
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1957
|
+
let missingWhen = false;
|
|
1958
|
+
let definedAfterLastElse = false;
|
|
1959
|
+
if (sibling == null || sibling.typ !== EnumToken.AtRuleNodeType) {
|
|
1960
|
+
missingWhen = true;
|
|
1354
1961
|
}
|
|
1355
|
-
if (
|
|
1356
|
-
|
|
1962
|
+
else if (sibling.nam !== "when") {
|
|
1963
|
+
if (sibling.nam !== "else") {
|
|
1964
|
+
missingWhen = true;
|
|
1965
|
+
}
|
|
1966
|
+
else if (sibling.val === "") {
|
|
1967
|
+
definedAfterLastElse = true;
|
|
1968
|
+
}
|
|
1357
1969
|
}
|
|
1358
|
-
if (
|
|
1970
|
+
if (missingWhen) {
|
|
1971
|
+
success = false;
|
|
1359
1972
|
errors.push({
|
|
1360
|
-
action:
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1973
|
+
action: "drop",
|
|
1974
|
+
node: atRule,
|
|
1975
|
+
location: atRule.loc,
|
|
1976
|
+
message: "at-rule @when is required before @else block",
|
|
1364
1977
|
});
|
|
1365
|
-
return null;
|
|
1366
1978
|
}
|
|
1367
|
-
if (
|
|
1979
|
+
else if (definedAfterLastElse) {
|
|
1980
|
+
success = false;
|
|
1368
1981
|
errors.push({
|
|
1369
|
-
action:
|
|
1370
|
-
|
|
1371
|
-
location
|
|
1982
|
+
action: "drop",
|
|
1983
|
+
node: atRule,
|
|
1984
|
+
location: atRule.loc,
|
|
1985
|
+
message: "at-rule @else block is defined after last @else block",
|
|
1372
1986
|
});
|
|
1373
|
-
return null;
|
|
1374
1987
|
}
|
|
1375
|
-
break;
|
|
1376
|
-
}
|
|
1377
|
-
if (options.removeCharset) {
|
|
1378
|
-
return null;
|
|
1379
1988
|
}
|
|
1989
|
+
// @ts-expect-error
|
|
1990
|
+
options = { ...options, minify: false, convertColor: false };
|
|
1991
|
+
// @ts-expect-error
|
|
1992
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
1993
|
+
typ: success && result.success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
1994
|
+
val: renderTokens(stream, options),
|
|
1995
|
+
chi: [],
|
|
1996
|
+
}), {
|
|
1997
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
1998
|
+
loc: {
|
|
1999
|
+
...definedPropertySettings,
|
|
2000
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
2001
|
+
},
|
|
2002
|
+
});
|
|
1380
2003
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
2004
|
+
case "media": {
|
|
2005
|
+
options = { ...options, parseColor: false };
|
|
2006
|
+
const result = parseMediaqueryList(stream, options);
|
|
2007
|
+
if (result.errors.length > 0) {
|
|
2008
|
+
errors.push(...result.errors);
|
|
2009
|
+
}
|
|
2010
|
+
// @ts-expect-error
|
|
2011
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
2012
|
+
typ: result.success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
2013
|
+
val: renderTokens(stream, options),
|
|
2014
|
+
chi: [],
|
|
2015
|
+
}), {
|
|
2016
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
2017
|
+
loc: {
|
|
2018
|
+
...definedPropertySettings,
|
|
2019
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
2020
|
+
},
|
|
2021
|
+
});
|
|
1399
2022
|
}
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
}
|
|
2023
|
+
case "scope": {
|
|
2024
|
+
let context = createValidationContext(trimArray(stream));
|
|
2025
|
+
let success = true;
|
|
2026
|
+
// @ts-ignore
|
|
2027
|
+
let range = context.peekRange((t) => t.typ === EnumToken.EndParensTokenType);
|
|
2028
|
+
if (range[0]?.typ !== EnumToken.StartParensTokenType) {
|
|
2029
|
+
errors.push({
|
|
2030
|
+
action: "drop",
|
|
2031
|
+
node: range[0] ?? atRule,
|
|
2032
|
+
location: (range[0] ?? atRule).loc,
|
|
2033
|
+
message: "expected '(' at start of @scope block",
|
|
2034
|
+
});
|
|
2035
|
+
success = false;
|
|
1414
2036
|
}
|
|
1415
|
-
else {
|
|
1416
|
-
|
|
2037
|
+
else if (range.at(-1)?.typ !== EnumToken.EndParensTokenType) {
|
|
2038
|
+
errors.push({
|
|
2039
|
+
action: "drop",
|
|
2040
|
+
node: range.at(-1) ?? atRule,
|
|
2041
|
+
location: (range.at(-1) ?? atRule).loc,
|
|
2042
|
+
message: "expected ')' at end of @scope block",
|
|
2043
|
+
});
|
|
2044
|
+
success = false;
|
|
1417
2045
|
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
2046
|
+
else {
|
|
2047
|
+
const srange = range.slice(1, -1);
|
|
2048
|
+
const result = matchSelectorSyntax(srange, errors, options, true);
|
|
2049
|
+
if (!result.success) {
|
|
2050
|
+
success = false;
|
|
2051
|
+
}
|
|
2052
|
+
else {
|
|
2053
|
+
stream.splice(stream.indexOf(range[0]) + 1, range.length - 2, ...trimWhiteSpaceTokens(srange));
|
|
1425
2054
|
}
|
|
1426
|
-
break;
|
|
1427
2055
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
2056
|
+
let index = stream.indexOf(range.at(-1));
|
|
2057
|
+
if (stream.length > index + 1) {
|
|
2058
|
+
while (stream[++index]?.typ === EnumToken.WhitespaceTokenType ||
|
|
2059
|
+
stream[index]?.typ === EnumToken.CommentTokenType)
|
|
2060
|
+
;
|
|
2061
|
+
if (index < stream.length) {
|
|
2062
|
+
if (stream[index].typ !== EnumToken.IdenTokenType ||
|
|
2063
|
+
"to" !== stream[index].val.toLowerCase()) {
|
|
2064
|
+
errors.push({
|
|
2065
|
+
action: "drop",
|
|
2066
|
+
node: stream[index],
|
|
2067
|
+
location: stream[index]?.loc,
|
|
2068
|
+
message: "expected 'to' at end of @scope block",
|
|
2069
|
+
});
|
|
2070
|
+
success = false;
|
|
2071
|
+
}
|
|
2072
|
+
else {
|
|
2073
|
+
while (stream[++index]?.typ === EnumToken.WhitespaceTokenType ||
|
|
2074
|
+
stream[index]?.typ === EnumToken.CommentTokenType)
|
|
2075
|
+
;
|
|
2076
|
+
if (stream[index].typ !== EnumToken.StartParensTokenType) {
|
|
2077
|
+
errors.push({
|
|
2078
|
+
action: "drop",
|
|
2079
|
+
node: stream[index],
|
|
2080
|
+
location: stream[index]?.loc,
|
|
2081
|
+
message: "expected 'to' at end of @scope block",
|
|
2082
|
+
});
|
|
2083
|
+
success = false;
|
|
1435
2084
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
offset++;
|
|
1447
|
-
}
|
|
1448
|
-
if (tokens[j].typ == EnumToken.StringTokenType) {
|
|
1449
|
-
Object.assign(node, {
|
|
1450
|
-
typ: EnumToken.CssVariableImportTokenType,
|
|
1451
|
-
nam: tokens[i].val,
|
|
1452
|
-
val: tokens.slice(offset)
|
|
2085
|
+
else {
|
|
2086
|
+
context = createValidationContext(stream.slice(index));
|
|
2087
|
+
// @ts-ignore
|
|
2088
|
+
range = context.peekRange((t) => t.typ === EnumToken.EndParensTokenType);
|
|
2089
|
+
if (range.at(-1)?.typ !== EnumToken.EndParensTokenType) {
|
|
2090
|
+
errors.push({
|
|
2091
|
+
action: "drop",
|
|
2092
|
+
node: range.at(-1) ?? atRule,
|
|
2093
|
+
location: (range.at(-1) ?? atRule).loc,
|
|
2094
|
+
message: "expected ')' at end of @scope block",
|
|
1453
2095
|
});
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
2096
|
+
success = false;
|
|
2097
|
+
}
|
|
2098
|
+
else {
|
|
2099
|
+
const srange = range.slice(1, -1);
|
|
2100
|
+
const result = matchSelectorSyntax(srange, errors, options, true);
|
|
2101
|
+
if (!result.success) {
|
|
2102
|
+
success = false;
|
|
2103
|
+
}
|
|
2104
|
+
else {
|
|
2105
|
+
stream.splice(stream.indexOf(range[0]) + 1, range.length - 2, ...trimWhiteSpaceTokens(srange));
|
|
2106
|
+
}
|
|
1457
2107
|
}
|
|
1458
|
-
Object.assign(node, {
|
|
1459
|
-
typ: EnumToken.CssVariableTokenType,
|
|
1460
|
-
nam: tokens[i].val,
|
|
1461
|
-
val: tokens.slice(offset)
|
|
1462
|
-
});
|
|
1463
|
-
context.chi.push(node);
|
|
1464
|
-
return null;
|
|
1465
|
-
}
|
|
1466
|
-
if (tokens[k].typ == EnumToken.PseudoClassTokenType) {
|
|
1467
|
-
Object.assign(tokens[k], {
|
|
1468
|
-
typ: EnumToken.IdenTokenType,
|
|
1469
|
-
val: tokens[k].val.slice(1)
|
|
1470
|
-
});
|
|
1471
|
-
Object.assign(node, {
|
|
1472
|
-
typ: EnumToken.CssVariableTokenType,
|
|
1473
|
-
nam: tokens[i].val,
|
|
1474
|
-
val: tokens.slice(k)
|
|
1475
|
-
});
|
|
1476
|
-
context.chi.push(node);
|
|
1477
|
-
return null;
|
|
1478
2108
|
}
|
|
1479
|
-
if (tokens[k].typ == EnumToken.CommaTokenType) {
|
|
1480
|
-
let j = i;
|
|
1481
|
-
while (++j < tokens.length) {
|
|
1482
|
-
if (tokens[j].typ == EnumToken.IdenTokenType && tokens[j].val.toLowerCase() == 'from') {
|
|
1483
|
-
const vars = tokens.slice(i, j);
|
|
1484
|
-
const from = tokens.slice(j + 1);
|
|
1485
|
-
let l = 0;
|
|
1486
|
-
let expect = EnumToken.IdenTokenType;
|
|
1487
|
-
for (; l < vars.length; l++) {
|
|
1488
|
-
if (vars[l].typ == EnumToken.WhitespaceTokenType || vars[l].typ == EnumToken.CommentTokenType) {
|
|
1489
|
-
continue;
|
|
1490
|
-
}
|
|
1491
|
-
if (expect == vars[l].typ || (expect == EnumToken.IdenTokenType && isIdentColor(vars[l]))) {
|
|
1492
|
-
expect = expect == EnumToken.CommaTokenType ? EnumToken.IdenTokenType : EnumToken.CommaTokenType;
|
|
1493
|
-
continue;
|
|
1494
|
-
}
|
|
1495
|
-
errors.push({
|
|
1496
|
-
action: 'drop',
|
|
1497
|
-
node: node,
|
|
1498
|
-
location: map.get(vars[l]) ?? location,
|
|
1499
|
-
message: `expecting '${EnumToken[expect]}' but found ${renderToken(vars[l])}`
|
|
1500
|
-
});
|
|
1501
|
-
return null;
|
|
1502
|
-
}
|
|
1503
|
-
l = 0;
|
|
1504
|
-
expect = EnumToken.IdenTokenType;
|
|
1505
|
-
for (; l < from.length; l++) {
|
|
1506
|
-
if (from[l].typ == EnumToken.WhitespaceTokenType || from[l].typ == EnumToken.CommentTokenType) {
|
|
1507
|
-
continue;
|
|
1508
|
-
}
|
|
1509
|
-
if (expect == from[l].typ || isIdentColor(from[l])) {
|
|
1510
|
-
while (++l < from.length) {
|
|
1511
|
-
if (from[l].typ == EnumToken.WhitespaceTokenType || from[l].typ == EnumToken.CommentTokenType) {
|
|
1512
|
-
continue;
|
|
1513
|
-
}
|
|
1514
|
-
errors.push({
|
|
1515
|
-
action: 'drop',
|
|
1516
|
-
node: node,
|
|
1517
|
-
location: map.get(from[l]) ?? location,
|
|
1518
|
-
message: `unexpected '${renderToken(from[l])}'`
|
|
1519
|
-
});
|
|
1520
|
-
return null;
|
|
1521
|
-
}
|
|
1522
|
-
break;
|
|
1523
|
-
}
|
|
1524
|
-
errors.push({
|
|
1525
|
-
action: 'drop',
|
|
1526
|
-
node: node,
|
|
1527
|
-
location: map.get(from[l]) ?? location,
|
|
1528
|
-
message: `expecting <string> but found ${renderToken(from[l])}`
|
|
1529
|
-
});
|
|
1530
|
-
return null;
|
|
1531
|
-
}
|
|
1532
|
-
// @ts-ignore
|
|
1533
|
-
delete node.nam;
|
|
1534
|
-
// @ts-ignore
|
|
1535
|
-
delete node.val;
|
|
1536
|
-
Object.assign(node, {
|
|
1537
|
-
typ: EnumToken.CssVariableDeclarationMapTokenType,
|
|
1538
|
-
vars,
|
|
1539
|
-
from
|
|
1540
|
-
});
|
|
1541
|
-
context.chi.push(node);
|
|
1542
|
-
return null;
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
k++;
|
|
1547
2109
|
}
|
|
1548
|
-
Object.assign(node, {
|
|
1549
|
-
typ: EnumToken.CssVariableTokenType,
|
|
1550
|
-
nam: tokens[i].val,
|
|
1551
|
-
val: tokens.slice(k)
|
|
1552
|
-
});
|
|
1553
|
-
context.chi.push(node);
|
|
1554
|
-
return null;
|
|
1555
2110
|
}
|
|
1556
2111
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
valid: SyntaxValidationResult.Drop,
|
|
1569
|
-
node,
|
|
1570
|
-
syntax: '@' + node.nam,
|
|
1571
|
-
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)) : {
|
|
1572
|
-
valid: SyntaxValidationResult.Drop,
|
|
1573
|
-
node,
|
|
1574
|
-
syntax: '@' + node.nam,
|
|
1575
|
-
error: '@' + node.nam + ' not allowed here'};
|
|
1576
|
-
if (valid.valid == SyntaxValidationResult.Drop) {
|
|
1577
|
-
let message = '';
|
|
1578
|
-
for (const token of tokens) {
|
|
1579
|
-
message += renderToken(token, { minify: false });
|
|
1580
|
-
}
|
|
1581
|
-
errors.push({
|
|
1582
|
-
action: 'drop',
|
|
1583
|
-
message: valid.error + ' - "' + message + '"',
|
|
1584
|
-
node,
|
|
1585
|
-
// @ts-ignore
|
|
1586
|
-
location: { src, ...(map.get(valid.node) ?? location) }
|
|
2112
|
+
// @ts-expect-error
|
|
2113
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
2114
|
+
typ: success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
2115
|
+
val: renderTokens(stream, options),
|
|
2116
|
+
chi: [],
|
|
2117
|
+
}), {
|
|
2118
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
2119
|
+
loc: {
|
|
2120
|
+
...definedPropertySettings,
|
|
2121
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
2122
|
+
},
|
|
1587
2123
|
});
|
|
1588
|
-
// @ts-ignore
|
|
1589
|
-
node.typ = EnumToken.InvalidAtRuleTokenType;
|
|
1590
|
-
}
|
|
1591
|
-
else {
|
|
1592
|
-
node.val = '';
|
|
1593
|
-
for (const token of node.tokens) {
|
|
1594
|
-
node.val += renderToken(token, {
|
|
1595
|
-
minify: false,
|
|
1596
|
-
convertColor: false,
|
|
1597
|
-
removeComments: true
|
|
1598
|
-
});
|
|
1599
|
-
}
|
|
1600
2124
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
const ruleType = context.typ == EnumToken.KeyframesAtRuleNodeType ? EnumToken.KeyFramesRuleNodeType : EnumToken.RuleNodeType;
|
|
1616
|
-
if (ruleType == EnumToken.RuleNodeType) {
|
|
1617
|
-
parseSelector(tokens);
|
|
1618
|
-
}
|
|
1619
|
-
const node = {
|
|
1620
|
-
typ: ruleType,
|
|
1621
|
-
sel: [...tokens.reduce((acc, curr, index, array) => {
|
|
1622
|
-
if (curr.typ == EnumToken.CommentTokenType) {
|
|
1623
|
-
return acc;
|
|
1624
|
-
}
|
|
1625
|
-
if (options.minify) {
|
|
1626
|
-
if (curr.typ == EnumToken.PseudoClassFuncTokenType && curr.val == ':nth-child') {
|
|
1627
|
-
let i = 0;
|
|
1628
|
-
for (; i < curr.chi.length; i++) {
|
|
1629
|
-
if (curr.chi[i].typ == EnumToken.IdenTokenType && curr.chi[i].val == 'even') {
|
|
1630
|
-
Object.assign(curr.chi[i], {
|
|
1631
|
-
typ: EnumToken.Dimension,
|
|
1632
|
-
val: 2,
|
|
1633
|
-
unit: 'n'
|
|
1634
|
-
});
|
|
1635
|
-
}
|
|
1636
|
-
else if (curr.chi[i].typ == EnumToken.Dimension &&
|
|
1637
|
-
curr.chi[i].val == 2 &&
|
|
1638
|
-
curr.chi[i].unit == 'n' &&
|
|
1639
|
-
curr.chi[i + 1]?.typ == EnumToken.WhitespaceTokenType &&
|
|
1640
|
-
curr.chi[i + 2]?.typ == EnumToken.LiteralTokenType &&
|
|
1641
|
-
curr.chi[i + 2].val == '+' &&
|
|
1642
|
-
curr.chi[i + 3]?.typ == EnumToken.WhitespaceTokenType &&
|
|
1643
|
-
curr.chi[i + 4]?.typ == EnumToken.NumberTokenType &&
|
|
1644
|
-
curr.chi[i + 4].val == 1) {
|
|
1645
|
-
curr.chi.splice(i, 5, Object.assign(curr.chi[i], {
|
|
1646
|
-
typ: EnumToken.IdenTokenType,
|
|
1647
|
-
val: 'odd'
|
|
1648
|
-
}));
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
if (curr.typ == EnumToken.WhitespaceTokenType) {
|
|
1654
|
-
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
1655
|
-
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
1656
|
-
combinators.includes(array[index - 1]?.val) ||
|
|
1657
|
-
combinators.includes(array[index + 1]?.val)) {
|
|
1658
|
-
return acc;
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
if (ruleType == EnumToken.KeyFramesRuleNodeType && options.minify) {
|
|
1662
|
-
if (curr.typ == EnumToken.IdenTokenType && curr.val == 'from') {
|
|
1663
|
-
Object.assign(curr, { typ: EnumToken.PercentageTokenType, val: '0' });
|
|
1664
|
-
}
|
|
1665
|
-
else if (curr.typ == EnumToken.PercentageTokenType && curr.val == 100) {
|
|
1666
|
-
Object.assign(curr, { typ: EnumToken.IdenTokenType, val: 'to' });
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
|
-
let t = renderToken(curr, { minify: false });
|
|
1670
|
-
if (t == ',') {
|
|
1671
|
-
acc.push([]);
|
|
1672
|
-
}
|
|
1673
|
-
else {
|
|
1674
|
-
acc[acc.length - 1].push(t);
|
|
1675
|
-
}
|
|
1676
|
-
return acc;
|
|
1677
|
-
}, [[]]).reduce((acc, curr) => {
|
|
1678
|
-
let i = 0;
|
|
1679
|
-
for (; i < curr.length; i++) {
|
|
1680
|
-
if (i + 1 < curr.length && curr[i] == '*') {
|
|
1681
|
-
if (curr[i] == '*') {
|
|
1682
|
-
let index = curr[i + 1] == ' ' ? 2 : 1;
|
|
1683
|
-
if (!['>', '~', '+'].includes(curr[index])) {
|
|
1684
|
-
curr.splice(i, index);
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
acc.set(curr.join(''), curr);
|
|
1690
|
-
return acc;
|
|
1691
|
-
}, uniq).keys()].join(','),
|
|
1692
|
-
chi: []
|
|
1693
|
-
};
|
|
1694
|
-
Object.defineProperty(node, 'tokens', {
|
|
1695
|
-
...definedPropertySettings,
|
|
1696
|
-
enumerable: false,
|
|
1697
|
-
value: tokens.slice()
|
|
1698
|
-
});
|
|
1699
|
-
loc = location;
|
|
1700
|
-
Object.defineProperty(node, 'loc', {
|
|
1701
|
-
...definedPropertySettings,
|
|
1702
|
-
value: loc,
|
|
1703
|
-
enumerable: options.sourcemap !== false
|
|
2125
|
+
case "page": {
|
|
2126
|
+
trimArray(stream);
|
|
2127
|
+
parseAtRulePage(atRule, stream, options, errors);
|
|
2128
|
+
// @ts-expect-error
|
|
2129
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
2130
|
+
typ: success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
2131
|
+
val: renderTokens(stream, options),
|
|
2132
|
+
chi: [],
|
|
2133
|
+
}), {
|
|
2134
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
2135
|
+
loc: {
|
|
2136
|
+
...definedPropertySettings,
|
|
2137
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
2138
|
+
},
|
|
1704
2139
|
});
|
|
1705
|
-
context.chi.push(node);
|
|
1706
|
-
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
|
|
1707
|
-
// @ts-ignore
|
|
1708
|
-
const skipValidate = (options.validation & ValidationLevel.Selector) == 0;
|
|
1709
|
-
const isAllowed = skipValidate || isNodeAllowedInContext(node, context);
|
|
1710
|
-
// @ts-ignore
|
|
1711
|
-
const valid = skipValidate ? {
|
|
1712
|
-
valid: SyntaxValidationResult.Valid,
|
|
1713
|
-
error: null
|
|
1714
|
-
} : !isAllowed ? {
|
|
1715
|
-
valid: SyntaxValidationResult.Drop,
|
|
1716
|
-
error: `${EnumToken[context.typ]}: child ${EnumToken[node.typ]} not allowed in context${context.typ == EnumToken.AtRuleNodeType ? ` '@${context.nam}'` : context.typ == EnumToken.StyleSheetNodeType ? ` 'stylesheet'` : ''}`
|
|
1717
|
-
} : ruleType == EnumToken.KeyFramesRuleNodeType ? validateKeyframeSelector(tokens) : validateSelector(tokens, options, context);
|
|
1718
|
-
if (valid.valid != SyntaxValidationResult.Valid) {
|
|
1719
|
-
// @ts-ignore
|
|
1720
|
-
node.typ = EnumToken.InvalidRuleTokenType;
|
|
1721
|
-
node.sel = tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '');
|
|
1722
|
-
errors.push({
|
|
1723
|
-
action: 'drop',
|
|
1724
|
-
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
1725
|
-
node,
|
|
1726
|
-
// @ts-ignore
|
|
1727
|
-
location
|
|
1728
|
-
});
|
|
1729
|
-
}
|
|
1730
|
-
Object.defineProperty(node, 'validSyntax', {
|
|
1731
|
-
...definedPropertySettings,
|
|
1732
|
-
value: valid.valid == SyntaxValidationResult.Valid
|
|
1733
|
-
});
|
|
1734
|
-
return node;
|
|
1735
2140
|
}
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
else if (start == '/' && isFunction(val)) {
|
|
1754
|
-
tokens.splice(i, 1, { typ: EnumToken.LiteralTokenType, val: '/' }, getTokenType(val));
|
|
1755
|
-
}
|
|
1756
|
-
}
|
|
1757
|
-
}
|
|
1758
|
-
parseTokens(tokens, { ...options, parseColor: true });
|
|
1759
|
-
for (i = 0; i < tokens.length; i++) {
|
|
1760
|
-
if (tokens[i].typ == EnumToken.CommentTokenType) {
|
|
1761
|
-
continue;
|
|
1762
|
-
}
|
|
1763
|
-
if (name == null && [EnumToken.IdenTokenType, EnumToken.DashedIdenTokenType].includes(tokens[i].typ)) {
|
|
1764
|
-
name = tokens.slice(0, i + 1);
|
|
1765
|
-
}
|
|
1766
|
-
else if (name == null && tokens[i].typ == EnumToken.ColorTokenType && [ColorType.SYS, ColorType.DPSYS].includes(tokens[i].kin)) {
|
|
1767
|
-
name = tokens.slice(0, i + 1);
|
|
1768
|
-
tokens[i].typ = EnumToken.IdenTokenType;
|
|
1769
|
-
}
|
|
1770
|
-
else if (name != null && funcLike.concat([
|
|
1771
|
-
EnumToken.LiteralTokenType,
|
|
1772
|
-
EnumToken.IdenTokenType, EnumToken.DashedIdenTokenType,
|
|
1773
|
-
EnumToken.PseudoClassTokenType, EnumToken.PseudoClassFuncTokenType
|
|
1774
|
-
]).includes(tokens[i].typ)) {
|
|
1775
|
-
if (tokens[i].val?.charAt?.(0) == ':') {
|
|
1776
|
-
Object.assign(tokens[i], getTokenType(tokens[i].val.slice(1)));
|
|
1777
|
-
if ('chi' in tokens[i]) {
|
|
1778
|
-
tokens[i].typ = EnumToken.FunctionTokenType;
|
|
1779
|
-
if (colorsFunc.includes(tokens[i].val) && isColor(tokens[i])) {
|
|
1780
|
-
parseColor(tokens[i]);
|
|
1781
|
-
}
|
|
1782
|
-
}
|
|
1783
|
-
tokens.splice(i--, 0, { typ: EnumToken.ColonTokenType });
|
|
1784
|
-
continue;
|
|
1785
|
-
}
|
|
1786
|
-
if ('chi' in tokens[i]) {
|
|
1787
|
-
tokens[i].typ = EnumToken.FunctionTokenType;
|
|
1788
|
-
}
|
|
1789
|
-
value = tokens.slice(i);
|
|
1790
|
-
}
|
|
1791
|
-
if (tokens[i].typ == EnumToken.ColonTokenType) {
|
|
1792
|
-
name = tokens.slice(0, i);
|
|
1793
|
-
value = tokens.slice(i + 1);
|
|
1794
|
-
break;
|
|
1795
|
-
}
|
|
1796
|
-
}
|
|
1797
|
-
if (name == null) {
|
|
1798
|
-
name = tokens;
|
|
1799
|
-
}
|
|
1800
|
-
const location = map.get(name[0]);
|
|
1801
|
-
if (name.length > 0) {
|
|
1802
|
-
for (let i = 1; i < name.length; i++) {
|
|
1803
|
-
if (name[i].typ != EnumToken.WhitespaceTokenType && name[i].typ != EnumToken.CommentTokenType) {
|
|
1804
|
-
errors.push({
|
|
1805
|
-
action: 'drop',
|
|
1806
|
-
message: 'doParse: invalid declaration',
|
|
1807
|
-
location
|
|
1808
|
-
});
|
|
1809
|
-
return null;
|
|
1810
|
-
}
|
|
1811
|
-
}
|
|
1812
|
-
}
|
|
1813
|
-
const nam = renderToken(name.shift(), { removeComments: true });
|
|
1814
|
-
if (value == null || (!nam.startsWith('--') && value.length == 0)) {
|
|
2141
|
+
case "top-left-corner":
|
|
2142
|
+
case "top-left":
|
|
2143
|
+
case "top-center":
|
|
2144
|
+
case "top-right":
|
|
2145
|
+
case "top-right-corner":
|
|
2146
|
+
case "bottom-left-corner":
|
|
2147
|
+
case "bottom-left":
|
|
2148
|
+
case "bottom-right":
|
|
2149
|
+
case "bottom-right-corner":
|
|
2150
|
+
case "left-top":
|
|
2151
|
+
case "left-middle":
|
|
2152
|
+
case "left-bottom":
|
|
2153
|
+
case "right-top":
|
|
2154
|
+
case "right-middle":
|
|
2155
|
+
case "right-bottom": {
|
|
2156
|
+
if (context.typ !== EnumToken.AtRuleNodeType || context.nam !== "page") {
|
|
2157
|
+
success = false;
|
|
1815
2158
|
errors.push({
|
|
1816
|
-
action:
|
|
1817
|
-
|
|
1818
|
-
location
|
|
2159
|
+
action: "drop",
|
|
2160
|
+
node: atRule,
|
|
2161
|
+
location: atRule.loc,
|
|
2162
|
+
message: "node is allowd only in @page rule",
|
|
1819
2163
|
});
|
|
1820
|
-
if (options.lenient) {
|
|
1821
|
-
const node = {
|
|
1822
|
-
typ: EnumToken.InvalidDeclarationNodeType,
|
|
1823
|
-
nam,
|
|
1824
|
-
val: []
|
|
1825
|
-
};
|
|
1826
|
-
Object.defineProperty(node, 'loc', {
|
|
1827
|
-
...definedPropertySettings,
|
|
1828
|
-
value: location,
|
|
1829
|
-
enumerable: options.sourcemap !== false
|
|
1830
|
-
});
|
|
1831
|
-
context.chi.push(node);
|
|
1832
|
-
stats.nodesCount++;
|
|
1833
|
-
}
|
|
1834
|
-
return null;
|
|
1835
2164
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
// fix expressions starting with '/' or '*' such as '/4' in (1 + 1)/4
|
|
1843
|
-
if (node.typ == EnumToken.LiteralTokenType && node.val.length > 0) {
|
|
1844
|
-
if (node.val[0] == '/' || node.val[0] == '*') {
|
|
1845
|
-
parent.chi.splice(parent.chi.indexOf(node), 1, { typ: node.val[0] == '/' ? EnumToken.Div : EnumToken.Mul }, ...parseString(node.val.slice(1)));
|
|
1846
|
-
}
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
const node = {
|
|
1852
|
-
typ: EnumToken.DeclarationNodeType,
|
|
1853
|
-
nam,
|
|
1854
|
-
val: value
|
|
1855
|
-
};
|
|
1856
|
-
Object.defineProperty(node, 'loc', {
|
|
1857
|
-
...definedPropertySettings,
|
|
1858
|
-
value: location,
|
|
1859
|
-
enumerable: options.sourcemap !== false
|
|
1860
|
-
});
|
|
1861
|
-
node.loc.end = { ...map.get(delim).end };
|
|
1862
|
-
// do not allow declarations in style sheets
|
|
1863
|
-
if (context.typ == EnumToken.StyleSheetNodeType && options.lenient) {
|
|
1864
|
-
Object.assign(node, { typ: EnumToken.InvalidDeclarationNodeType });
|
|
1865
|
-
context.chi.push(node);
|
|
1866
|
-
stats.nodesCount++;
|
|
1867
|
-
return null;
|
|
1868
|
-
}
|
|
1869
|
-
const result = parseDeclarationNode(node, errors, location);
|
|
1870
|
-
Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
|
|
1871
|
-
if (result != null) {
|
|
1872
|
-
if (options.validation & ValidationLevel.Declaration) {
|
|
1873
|
-
const isAllowed = isNodeAllowedInContext(node, context);
|
|
1874
|
-
// @ts-ignore
|
|
1875
|
-
const valid = !isAllowed ? {
|
|
1876
|
-
valid: SyntaxValidationResult.Drop,
|
|
1877
|
-
error: `${EnumToken[node.typ]} not allowed in context${context.typ == EnumToken.AtRuleNodeType ? ` '@${context.nam}'` : context.typ == EnumToken.StyleSheetNodeType ? ` 'stylesheet'` : ''}`,
|
|
1878
|
-
node,
|
|
1879
|
-
syntax: null
|
|
1880
|
-
} : evaluateSyntax(result, context, options);
|
|
1881
|
-
Object.defineProperty(result, 'validSyntax', {
|
|
1882
|
-
...definedPropertySettings,
|
|
1883
|
-
value: valid.valid == SyntaxValidationResult.Valid
|
|
1884
|
-
});
|
|
1885
|
-
if (valid.valid == SyntaxValidationResult.Drop) {
|
|
2165
|
+
else {
|
|
2166
|
+
trimArray(stream);
|
|
2167
|
+
for (let i = 0; i < stream.length; i++) {
|
|
2168
|
+
if (stream[i].typ !== EnumToken.WhitespaceTokenType &&
|
|
2169
|
+
stream[i].typ !== EnumToken.CommentTokenType) {
|
|
2170
|
+
success = false;
|
|
1886
2171
|
errors.push({
|
|
1887
|
-
action:
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
location: map.get(valid.node) ?? valid.node?.loc ?? result.loc ?? location
|
|
2172
|
+
action: "drop",
|
|
2173
|
+
node: stream[i],
|
|
2174
|
+
location: stream[i].loc,
|
|
2175
|
+
message: "expected whitespace or comment",
|
|
1892
2176
|
});
|
|
1893
|
-
if (!options.lenient) {
|
|
1894
|
-
return null;
|
|
1895
|
-
}
|
|
1896
|
-
Object.assign(node, { typ: EnumToken.InvalidDeclarationNodeType });
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
context.chi.push(result);
|
|
1900
|
-
stats.nodesCount++;
|
|
1901
|
-
}
|
|
1902
|
-
return null;
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
}
|
|
1906
|
-
/**
|
|
1907
|
-
* parse at-rule prelude
|
|
1908
|
-
* @param tokens
|
|
1909
|
-
* @param atRule
|
|
1910
|
-
*/
|
|
1911
|
-
function parseAtRulePrelude(tokens, atRule) {
|
|
1912
|
-
for (const { value, parent } of walkValues(tokens, null, null, true)) {
|
|
1913
|
-
if (value.typ == EnumToken.CommentTokenType ||
|
|
1914
|
-
value.typ == EnumToken.WhitespaceTokenType ||
|
|
1915
|
-
value.typ == EnumToken.CommaTokenType) {
|
|
1916
|
-
continue;
|
|
1917
|
-
}
|
|
1918
|
-
if (value.typ == EnumToken.PseudoClassFuncTokenType || value.typ == EnumToken.PseudoClassTokenType) {
|
|
1919
|
-
if (parent?.typ == EnumToken.ParensTokenType) {
|
|
1920
|
-
const index = parent.chi.indexOf(value);
|
|
1921
|
-
let i = index;
|
|
1922
|
-
while (i--) {
|
|
1923
|
-
if (parent.chi[i].typ == EnumToken.IdenTokenType || parent.chi[i].typ == EnumToken.DashedIdenTokenType) {
|
|
1924
2177
|
break;
|
|
1925
2178
|
}
|
|
1926
2179
|
}
|
|
1927
|
-
if (i >= 0) {
|
|
1928
|
-
const token = getTokenType(parent.chi[index].val.slice(1) + (funcLike.includes(parent.chi[index].typ) ? '(' : ''));
|
|
1929
|
-
parent.chi[index].val = token.val;
|
|
1930
|
-
parent.chi[index].typ = token.typ;
|
|
1931
|
-
if (parent.chi[index].typ == EnumToken.FunctionTokenType && isColor(parent.chi[index])) {
|
|
1932
|
-
parseColor(parent.chi[index]);
|
|
1933
|
-
}
|
|
1934
|
-
parent.chi.splice(i, index - i + 1, {
|
|
1935
|
-
typ: EnumToken.MediaQueryConditionTokenType,
|
|
1936
|
-
l: parent.chi[i],
|
|
1937
|
-
r: parent.chi.slice(index),
|
|
1938
|
-
op: {
|
|
1939
|
-
typ: EnumToken.ColonTokenType
|
|
1940
|
-
}
|
|
1941
|
-
});
|
|
1942
|
-
}
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
if (atRule.val == 'page' && value.typ == EnumToken.PseudoClassTokenType) {
|
|
1946
|
-
if ([':left', ':right', ':first', ':blank'].includes(value.val)) {
|
|
1947
|
-
Object.assign(value, { typ: EnumToken.PseudoPageTokenType });
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
if (atRule.val == 'layer') {
|
|
1951
|
-
if (parent == null && value.typ == EnumToken.LiteralTokenType) {
|
|
1952
|
-
if (value.val.charAt(0) == '.') {
|
|
1953
|
-
if (isIdent(value.val.slice(1))) {
|
|
1954
|
-
Object.assign(value, { typ: EnumToken.ClassSelectorTokenType });
|
|
1955
|
-
}
|
|
1956
|
-
}
|
|
1957
2180
|
}
|
|
2181
|
+
// @ts-expect-error
|
|
2182
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
2183
|
+
typ: success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
2184
|
+
val: renderTokens(stream, options),
|
|
2185
|
+
chi: [],
|
|
2186
|
+
}), {
|
|
2187
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
2188
|
+
loc: {
|
|
2189
|
+
...definedPropertySettings,
|
|
2190
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
2191
|
+
},
|
|
2192
|
+
});
|
|
1958
2193
|
}
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
continue;
|
|
1977
|
-
}
|
|
1978
|
-
if (value.typ == EnumToken.IdenTokenType &&
|
|
1979
|
-
['not', 'only'].some((t) => val === t)) {
|
|
1980
|
-
const array = parent?.chi ?? tokens;
|
|
1981
|
-
const startIndex = array.indexOf(value);
|
|
1982
|
-
let index = startIndex + 1;
|
|
1983
|
-
if (index == 0) {
|
|
1984
|
-
continue;
|
|
1985
|
-
}
|
|
1986
|
-
while (index < array.length && [EnumToken.CommentTokenType, EnumToken.WhitespaceTokenType].includes(array[index].typ)) {
|
|
1987
|
-
index++;
|
|
1988
|
-
}
|
|
1989
|
-
if (array[index] == null || array[index].typ == EnumToken.CommaTokenType) {
|
|
1990
|
-
continue;
|
|
2194
|
+
case "value": {
|
|
2195
|
+
let index = 0;
|
|
2196
|
+
let isVarDeclaration = false;
|
|
2197
|
+
for (; index < stream.length; index++) {
|
|
2198
|
+
if (stream[index].typ == EnumToken.PseudoClassTokenType) {
|
|
2199
|
+
Object.assign(stream[index], {
|
|
2200
|
+
typ: EnumToken.IdenTokenType,
|
|
2201
|
+
val: stream[index].val.slice(1),
|
|
2202
|
+
});
|
|
2203
|
+
stream.splice(index, 0, Object.defineProperty({
|
|
2204
|
+
typ: EnumToken.ColonTokenType,
|
|
2205
|
+
}, "loc", {
|
|
2206
|
+
...definedPropertySettings,
|
|
2207
|
+
value: { ...stream[index].loc, end: { ...stream[index]?.loc?.sta } },
|
|
2208
|
+
}));
|
|
2209
|
+
isVarDeclaration = true;
|
|
2210
|
+
break;
|
|
1991
2211
|
}
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
});
|
|
1996
|
-
array.splice(startIndex + 1, index - startIndex);
|
|
1997
|
-
continue;
|
|
1998
|
-
}
|
|
1999
|
-
}
|
|
2000
|
-
if (value.typ == EnumToken.FunctionTokenType && value.val == 'selector') {
|
|
2001
|
-
parseSelector(value.chi);
|
|
2002
|
-
}
|
|
2003
|
-
if (value.typ == EnumToken.ParensTokenType || (value.typ == EnumToken.FunctionTokenType && ['media', 'supports', 'style', 'scroll-state'].includes(value.val))) {
|
|
2004
|
-
let i;
|
|
2005
|
-
let nameIndex = -1;
|
|
2006
|
-
let valueIndex = -1;
|
|
2007
|
-
const dashedIdent = value.typ == EnumToken.FunctionTokenType && value.val == 'style';
|
|
2008
|
-
for (let i = 0; i < value.chi.length; i++) {
|
|
2009
|
-
if (value.chi[i].typ == EnumToken.CommentTokenType || value.chi[i].typ == EnumToken.WhitespaceTokenType) {
|
|
2010
|
-
continue;
|
|
2212
|
+
else if (stream[index].typ == EnumToken.ColonTokenType) {
|
|
2213
|
+
isVarDeclaration = true;
|
|
2214
|
+
break;
|
|
2011
2215
|
}
|
|
2012
|
-
if (
|
|
2013
|
-
|
|
2216
|
+
else if (stream[index].typ == EnumToken.IdenTokenType &&
|
|
2217
|
+
equalsIgnoreCase("from", stream[index].val)) {
|
|
2218
|
+
break;
|
|
2014
2219
|
}
|
|
2015
|
-
break;
|
|
2016
2220
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2221
|
+
// supported syntaxes:
|
|
2222
|
+
// @value <ident>: <string>; // import from file as alias
|
|
2223
|
+
// @value id : <declaration-value>; // variable declaration
|
|
2224
|
+
// @value <ident># from <ident>; // import variables from alias
|
|
2225
|
+
let result = matchAllSyntax(syntaxRules?.getPreludeRules()?.slice?.(1), createValidationContext(stream), options);
|
|
2226
|
+
if (!result.success) {
|
|
2227
|
+
errors.push(...result.errors);
|
|
2228
|
+
return Object.defineProperty({
|
|
2229
|
+
typ: EnumToken.InvalidAtRuleNodeType,
|
|
2230
|
+
val: renderTokens(stream, options),
|
|
2231
|
+
}, "loc", {
|
|
2232
|
+
...definedPropertySettings,
|
|
2233
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
2234
|
+
});
|
|
2019
2235
|
}
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
i--;
|
|
2031
|
-
continue;
|
|
2032
|
-
}
|
|
2236
|
+
if (isVarDeclaration) {
|
|
2237
|
+
const nam = stream.find((t) => t.typ == EnumToken.IdenTokenType);
|
|
2238
|
+
const value = trimArray(stream.slice(index + 1).filter((t) => t.typ != EnumToken.CommentTokenType));
|
|
2239
|
+
if (value.length == 1 && value[0].typ == EnumToken.StringTokenType) {
|
|
2240
|
+
// import from file as alias
|
|
2241
|
+
return {
|
|
2242
|
+
typ: EnumToken.CssVariableImportTokenType,
|
|
2243
|
+
nam: nam.val,
|
|
2244
|
+
val: value,
|
|
2245
|
+
};
|
|
2033
2246
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2247
|
+
// import variables from alias
|
|
2248
|
+
return {
|
|
2249
|
+
typ: EnumToken.CssVariableTokenType,
|
|
2250
|
+
nam: nam.val,
|
|
2251
|
+
val: value,
|
|
2252
|
+
};
|
|
2253
|
+
}
|
|
2254
|
+
// @ts-expect-error
|
|
2255
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
2256
|
+
typ: EnumToken.CssVariableDeclarationMapTokenType,
|
|
2257
|
+
vars: trimArray(stream.slice(0, index)),
|
|
2258
|
+
from: stream.slice(index + 1),
|
|
2259
|
+
}), {
|
|
2260
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
2261
|
+
loc: {
|
|
2262
|
+
...definedPropertySettings,
|
|
2263
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
2264
|
+
},
|
|
2265
|
+
});
|
|
2266
|
+
}
|
|
2267
|
+
default: {
|
|
2268
|
+
options = { ...options, parseColor: false };
|
|
2269
|
+
let result = null;
|
|
2270
|
+
if (syntax == null) {
|
|
2271
|
+
// check matching '(' and ')'
|
|
2272
|
+
// check commas , or ,,
|
|
2273
|
+
// check colon :
|
|
2274
|
+
// check or and and
|
|
2275
|
+
result = matchGenericSyntax(atRule, stream);
|
|
2276
|
+
if (result.errors.length > 0) {
|
|
2277
|
+
errors.push(...result.errors);
|
|
2043
2278
|
}
|
|
2044
|
-
valueIndex = i;
|
|
2045
|
-
break;
|
|
2046
|
-
}
|
|
2047
|
-
if (valueIndex == -1) {
|
|
2048
|
-
continue;
|
|
2049
2279
|
}
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2280
|
+
else {
|
|
2281
|
+
result = matchAtRuleSyntax(atRule, stream, options);
|
|
2282
|
+
if (result.success) {
|
|
2283
|
+
let i = 0;
|
|
2284
|
+
const stack = [];
|
|
2285
|
+
for (; i < stream.length; i++) {
|
|
2286
|
+
if (stream[i].typ === EnumToken.StartParensTokenType || tokensfuncDefMap.has(stream[i].typ)) {
|
|
2287
|
+
stack.push(stream[i]);
|
|
2288
|
+
continue;
|
|
2289
|
+
}
|
|
2290
|
+
if (stream[i].typ === EnumToken.EndParensTokenType && stack.length > 0) {
|
|
2291
|
+
const index = stream.indexOf(stack[stack.length - 1]);
|
|
2292
|
+
stream[index].loc.end = stream[i].loc.end;
|
|
2293
|
+
Object.assign(stream[index], {
|
|
2294
|
+
typ: tokensfuncDefMap.get(stream[index].typ),
|
|
2295
|
+
chi: stream.splice(index + 1, i - index - 1),
|
|
2296
|
+
});
|
|
2297
|
+
i = index;
|
|
2298
|
+
stream.splice(index + 1, 1);
|
|
2299
|
+
stack.pop();
|
|
2300
|
+
// continue;
|
|
2301
|
+
}
|
|
2066
2302
|
}
|
|
2067
|
-
const t = [{
|
|
2068
|
-
typ: EnumToken.MediaQueryConditionTokenType,
|
|
2069
|
-
l: node,
|
|
2070
|
-
op: { typ: val.typ },
|
|
2071
|
-
r: value.chi.slice()
|
|
2072
|
-
}];
|
|
2073
|
-
value.chi.length = 0;
|
|
2074
|
-
value.chi.push(...t);
|
|
2075
2303
|
}
|
|
2076
2304
|
}
|
|
2305
|
+
// @ts-expect-error
|
|
2306
|
+
return Object.defineProperties(Object.assign(atRule, {
|
|
2307
|
+
typ: result.success ? EnumToken.AtRuleNodeType : EnumToken.InvalidRuleNodeType,
|
|
2308
|
+
val: renderTokens(trimWhiteSpaceTokens(stream), options),
|
|
2309
|
+
...(parseAsBlock ? { chi: [] } : {}),
|
|
2310
|
+
}), {
|
|
2311
|
+
tokens: { ...definedPropertySettings, value: stream.slice() },
|
|
2312
|
+
loc: {
|
|
2313
|
+
...definedPropertySettings,
|
|
2314
|
+
value: { ...atRule.loc, end: { ...(stream.at(-1)?.loc?.end ?? atRule.loc.end) } },
|
|
2315
|
+
},
|
|
2316
|
+
});
|
|
2077
2317
|
}
|
|
2078
2318
|
}
|
|
2079
|
-
return tokens;
|
|
2080
2319
|
}
|
|
2081
2320
|
/**
|
|
2082
2321
|
* parse a string as an array of declaration nodes
|
|
@@ -2092,104 +2331,16 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
2092
2331
|
async function parseDeclarations(declaration) {
|
|
2093
2332
|
return doParse(tokenize({
|
|
2094
2333
|
stream: `.x{${declaration}}`,
|
|
2095
|
-
buffer:
|
|
2334
|
+
buffer: "",
|
|
2096
2335
|
offset: 0,
|
|
2097
2336
|
position: { ind: 0, lin: 1, col: 1 },
|
|
2098
|
-
currentPosition: { ind: -1, lin: 1, col: 0 }
|
|
2099
|
-
}), { setParent: false, minify: false, validation: false }).then(result => {
|
|
2100
|
-
return result.ast.chi[0].chi.filter(t => t.typ == EnumToken.DeclarationNodeType ||
|
|
2337
|
+
currentPosition: { ind: -1, lin: 1, col: 0 },
|
|
2338
|
+
}), { setParent: false, minify: false, validation: false }).then((result) => {
|
|
2339
|
+
return result.ast.chi[0].chi.filter((t) => t.typ == EnumToken.DeclarationNodeType ||
|
|
2340
|
+
t.typ == EnumToken.CommentNodeType ||
|
|
2341
|
+
t.typ == EnumToken.InvalidDeclarationNodeType);
|
|
2101
2342
|
});
|
|
2102
2343
|
}
|
|
2103
|
-
/**
|
|
2104
|
-
* parse selector
|
|
2105
|
-
* @param tokens
|
|
2106
|
-
*/
|
|
2107
|
-
function parseSelector(tokens) {
|
|
2108
|
-
for (const { value, parent } of walkValues(tokens)) {
|
|
2109
|
-
if (value.typ == EnumToken.CommentTokenType ||
|
|
2110
|
-
value.typ == EnumToken.WhitespaceTokenType ||
|
|
2111
|
-
value.typ == EnumToken.CommaTokenType ||
|
|
2112
|
-
value.typ == EnumToken.IdenTokenType ||
|
|
2113
|
-
value.typ == EnumToken.HashTokenType) {
|
|
2114
|
-
continue;
|
|
2115
|
-
}
|
|
2116
|
-
if (parent == null) {
|
|
2117
|
-
if (value.typ == EnumToken.GtTokenType) {
|
|
2118
|
-
Object.assign(value, { typ: EnumToken.ChildCombinatorTokenType });
|
|
2119
|
-
}
|
|
2120
|
-
else if (value.typ == EnumToken.LiteralTokenType) {
|
|
2121
|
-
if (value.val.charAt(0) == '&') {
|
|
2122
|
-
Object.assign(value, { typ: EnumToken.NestingSelectorTokenType });
|
|
2123
|
-
// @ts-ignore
|
|
2124
|
-
delete value.val;
|
|
2125
|
-
}
|
|
2126
|
-
else if (value.val.charAt(0) == '.') {
|
|
2127
|
-
if (!isIdent(value.val.slice(1))) {
|
|
2128
|
-
Object.assign(value, { typ: EnumToken.InvalidClassSelectorTokenType });
|
|
2129
|
-
}
|
|
2130
|
-
else {
|
|
2131
|
-
Object.assign(value, { typ: EnumToken.ClassSelectorTokenType });
|
|
2132
|
-
}
|
|
2133
|
-
}
|
|
2134
|
-
if (['*', '>', '+', '~'].includes(value.val)) {
|
|
2135
|
-
switch (value.val) {
|
|
2136
|
-
case '*':
|
|
2137
|
-
Object.assign(value, { typ: EnumToken.UniversalSelectorTokenType });
|
|
2138
|
-
break;
|
|
2139
|
-
case '>':
|
|
2140
|
-
Object.assign(value, { typ: EnumToken.ChildCombinatorTokenType });
|
|
2141
|
-
break;
|
|
2142
|
-
case '+':
|
|
2143
|
-
Object.assign(value, { typ: EnumToken.NextSiblingCombinatorTokenType });
|
|
2144
|
-
break;
|
|
2145
|
-
case '~':
|
|
2146
|
-
Object.assign(value, { typ: EnumToken.SubsequentSiblingCombinatorTokenType });
|
|
2147
|
-
break;
|
|
2148
|
-
}
|
|
2149
|
-
// @ts-ignore
|
|
2150
|
-
delete value.val;
|
|
2151
|
-
}
|
|
2152
|
-
}
|
|
2153
|
-
else if (value.typ == EnumToken.ColorTokenType) {
|
|
2154
|
-
if (value.kin == ColorType.LIT || value.kin == ColorType.HEX || value.kin == ColorType.SYS || value.kin == ColorType.DPSYS) {
|
|
2155
|
-
if (value.kin == ColorType.HEX) {
|
|
2156
|
-
if (!isIdent(value.val.slice(1))) {
|
|
2157
|
-
continue;
|
|
2158
|
-
}
|
|
2159
|
-
Object.assign(value, { typ: EnumToken.HashTokenType });
|
|
2160
|
-
}
|
|
2161
|
-
else {
|
|
2162
|
-
Object.assign(value, { typ: EnumToken.IdenTokenType });
|
|
2163
|
-
}
|
|
2164
|
-
// @ts-ignore
|
|
2165
|
-
delete value.kin;
|
|
2166
|
-
}
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
let i = 0;
|
|
2171
|
-
const combinators = [
|
|
2172
|
-
EnumToken.ChildCombinatorTokenType,
|
|
2173
|
-
EnumToken.NextSiblingCombinatorTokenType,
|
|
2174
|
-
EnumToken.SubsequentSiblingCombinatorTokenType
|
|
2175
|
-
];
|
|
2176
|
-
for (; i < tokens.length; i++) {
|
|
2177
|
-
if (combinators.includes(tokens[i].typ)) {
|
|
2178
|
-
if (i + 1 < tokens.length && [EnumToken.WhitespaceTokenType, EnumToken.DescendantCombinatorTokenType].includes(tokens[i + 1].typ)) {
|
|
2179
|
-
tokens.splice(i + 1, 1);
|
|
2180
|
-
}
|
|
2181
|
-
if (i > 0 && [EnumToken.WhitespaceTokenType, EnumToken.DescendantCombinatorTokenType].includes(tokens[i - 1].typ)) {
|
|
2182
|
-
tokens.splice(i - 1, 1);
|
|
2183
|
-
i--;
|
|
2184
|
-
continue;
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
if (tokens[i].typ == EnumToken.WhitespaceTokenType) {
|
|
2188
|
-
tokens[i].typ = EnumToken.DescendantCombinatorTokenType;
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
|
-
return tokens;
|
|
2192
|
-
}
|
|
2193
2344
|
/**
|
|
2194
2345
|
* parse css string and return an array of tokens
|
|
2195
2346
|
* @param src
|
|
@@ -2213,194 +2364,14 @@ function parseSelector(tokens) {
|
|
|
2213
2364
|
function parseString(src, options = { location: false }) {
|
|
2214
2365
|
const parseInfo = {
|
|
2215
2366
|
stream: src,
|
|
2216
|
-
|
|
2367
|
+
src: options.src ?? "",
|
|
2368
|
+
buffer: "",
|
|
2217
2369
|
offset: 0,
|
|
2370
|
+
time: 0,
|
|
2218
2371
|
position: { ind: 0, lin: 1, col: 1 },
|
|
2219
|
-
currentPosition: { ind: -1, lin: 1, col: 0 }
|
|
2220
|
-
};
|
|
2221
|
-
return parseTokens([...tokenize(parseInfo)].reduce((acc, t) => {
|
|
2222
|
-
if (t.hint == EnumToken.EOFTokenType) {
|
|
2223
|
-
return acc;
|
|
2224
|
-
}
|
|
2225
|
-
const token = getTokenType(t.token, t.hint);
|
|
2226
|
-
Object.defineProperty(token, 'loc', {
|
|
2227
|
-
...definedPropertySettings,
|
|
2228
|
-
value: { sta: t.sta },
|
|
2229
|
-
enumerable: options.location !== false
|
|
2230
|
-
});
|
|
2231
|
-
acc.push(token);
|
|
2232
|
-
return acc;
|
|
2233
|
-
}, []));
|
|
2234
|
-
}
|
|
2235
|
-
/**
|
|
2236
|
-
* get the token type from a string
|
|
2237
|
-
* @param val
|
|
2238
|
-
* @param hint
|
|
2239
|
-
*/
|
|
2240
|
-
function getTokenType(val, hint) {
|
|
2241
|
-
if (hint != null) {
|
|
2242
|
-
return enumTokenHints.has(hint) ? { typ: hint } : { typ: hint, val };
|
|
2243
|
-
}
|
|
2244
|
-
switch (val) {
|
|
2245
|
-
case ' ':
|
|
2246
|
-
return { typ: EnumToken.WhitespaceTokenType };
|
|
2247
|
-
case ';':
|
|
2248
|
-
return { typ: EnumToken.SemiColonTokenType };
|
|
2249
|
-
case '{':
|
|
2250
|
-
return { typ: EnumToken.BlockStartTokenType };
|
|
2251
|
-
case '}':
|
|
2252
|
-
return { typ: EnumToken.BlockEndTokenType };
|
|
2253
|
-
case '[':
|
|
2254
|
-
return { typ: EnumToken.AttrStartTokenType };
|
|
2255
|
-
case ']':
|
|
2256
|
-
return { typ: EnumToken.AttrEndTokenType };
|
|
2257
|
-
case ':':
|
|
2258
|
-
return { typ: EnumToken.ColonTokenType };
|
|
2259
|
-
case ')':
|
|
2260
|
-
return { typ: EnumToken.EndParensTokenType };
|
|
2261
|
-
case '(':
|
|
2262
|
-
return { typ: EnumToken.StartParensTokenType };
|
|
2263
|
-
case '=':
|
|
2264
|
-
return { typ: EnumToken.DelimTokenType };
|
|
2265
|
-
case ',':
|
|
2266
|
-
return { typ: EnumToken.CommaTokenType };
|
|
2267
|
-
case '<':
|
|
2268
|
-
return { typ: EnumToken.LtTokenType };
|
|
2269
|
-
case '>':
|
|
2270
|
-
return { typ: EnumToken.GtTokenType };
|
|
2271
|
-
}
|
|
2272
|
-
if (val.charAt(0) == ':' && isPseudo(val)) {
|
|
2273
|
-
return val.endsWith('(') ? {
|
|
2274
|
-
typ: EnumToken.PseudoClassFuncTokenType,
|
|
2275
|
-
val: val.slice(0, -1),
|
|
2276
|
-
chi: []
|
|
2277
|
-
}
|
|
2278
|
-
: (
|
|
2279
|
-
// https://www.w3.org/TR/selectors-4/#single-colon-pseudos
|
|
2280
|
-
val.startsWith('::') || pseudoElements.includes(val) ? {
|
|
2281
|
-
typ: EnumToken.PseudoElementTokenType,
|
|
2282
|
-
val
|
|
2283
|
-
} :
|
|
2284
|
-
{
|
|
2285
|
-
typ: EnumToken.PseudoClassTokenType,
|
|
2286
|
-
val
|
|
2287
|
-
});
|
|
2288
|
-
}
|
|
2289
|
-
if (val.charAt(0) == '@' && isAtKeyword(val)) {
|
|
2290
|
-
return {
|
|
2291
|
-
typ: EnumToken.AtRuleTokenType,
|
|
2292
|
-
val: val.slice(1)
|
|
2293
|
-
};
|
|
2294
|
-
}
|
|
2295
|
-
if (val.endsWith('(') && isFunction(val)) {
|
|
2296
|
-
val = val.slice(0, -1);
|
|
2297
|
-
if (val == 'url') {
|
|
2298
|
-
return {
|
|
2299
|
-
typ: EnumToken.UrlFunctionTokenType,
|
|
2300
|
-
val,
|
|
2301
|
-
chi: []
|
|
2302
|
-
};
|
|
2303
|
-
}
|
|
2304
|
-
if (['linear-gradient', 'radial-gradient', 'repeating-linear-gradient', 'repeating-radial-gradient', 'conic-gradient', 'image', 'image-set', 'element', 'cross-fade', 'paint'].includes(val)) {
|
|
2305
|
-
return {
|
|
2306
|
-
typ: EnumToken.ImageFunctionTokenType,
|
|
2307
|
-
val,
|
|
2308
|
-
chi: []
|
|
2309
|
-
};
|
|
2310
|
-
}
|
|
2311
|
-
if (timingFunc.includes(val.toLowerCase())) {
|
|
2312
|
-
return {
|
|
2313
|
-
typ: EnumToken.TimingFunctionTokenType,
|
|
2314
|
-
val,
|
|
2315
|
-
chi: []
|
|
2316
|
-
};
|
|
2317
|
-
}
|
|
2318
|
-
if (timelineFunc.includes(val)) {
|
|
2319
|
-
return {
|
|
2320
|
-
typ: EnumToken.TimelineFunctionTokenType,
|
|
2321
|
-
val,
|
|
2322
|
-
chi: []
|
|
2323
|
-
};
|
|
2324
|
-
}
|
|
2325
|
-
return {
|
|
2326
|
-
typ: EnumToken.FunctionTokenType,
|
|
2327
|
-
val,
|
|
2328
|
-
chi: []
|
|
2329
|
-
};
|
|
2330
|
-
}
|
|
2331
|
-
if (isNumber(val)) {
|
|
2332
|
-
return {
|
|
2333
|
-
typ: EnumToken.NumberTokenType,
|
|
2334
|
-
val: +val
|
|
2335
|
-
};
|
|
2336
|
-
}
|
|
2337
|
-
if (isPercentage(val)) {
|
|
2338
|
-
return {
|
|
2339
|
-
typ: EnumToken.PercentageTokenType,
|
|
2340
|
-
val: +val.slice(0, -1)
|
|
2341
|
-
};
|
|
2342
|
-
}
|
|
2343
|
-
const dimension = parseDimension(val);
|
|
2344
|
-
if (dimension != null) {
|
|
2345
|
-
return dimension;
|
|
2346
|
-
}
|
|
2347
|
-
const v = val.toLowerCase();
|
|
2348
|
-
if (v == 'currentcolor' || v == 'transparent' || v in COLORS_NAMES) {
|
|
2349
|
-
return {
|
|
2350
|
-
typ: EnumToken.ColorTokenType,
|
|
2351
|
-
val: v,
|
|
2352
|
-
kin: ColorType.LIT
|
|
2353
|
-
};
|
|
2354
|
-
}
|
|
2355
|
-
if (isIdent(val)) {
|
|
2356
|
-
if (systemColors.has(v)) {
|
|
2357
|
-
return {
|
|
2358
|
-
typ: EnumToken.ColorTokenType,
|
|
2359
|
-
val,
|
|
2360
|
-
kin: ColorType.SYS
|
|
2361
|
-
};
|
|
2362
|
-
}
|
|
2363
|
-
if (deprecatedSystemColors.has(v)) {
|
|
2364
|
-
return {
|
|
2365
|
-
typ: EnumToken.ColorTokenType,
|
|
2366
|
-
val,
|
|
2367
|
-
kin: ColorType.DPSYS
|
|
2368
|
-
};
|
|
2369
|
-
}
|
|
2370
|
-
return {
|
|
2371
|
-
typ: val.startsWith('--') ? EnumToken.DashedIdenTokenType : EnumToken.IdenTokenType,
|
|
2372
|
-
val
|
|
2373
|
-
};
|
|
2374
|
-
}
|
|
2375
|
-
if (val.charAt(0) == '.' && isIdent(val.slice(1))) {
|
|
2376
|
-
return {
|
|
2377
|
-
typ: EnumToken.ClassSelectorTokenType,
|
|
2378
|
-
val
|
|
2379
|
-
};
|
|
2380
|
-
}
|
|
2381
|
-
if (val.charAt(0) == '#' && isHexColor(val)) {
|
|
2382
|
-
return {
|
|
2383
|
-
typ: EnumToken.ColorTokenType,
|
|
2384
|
-
val,
|
|
2385
|
-
kin: ColorType.HEX
|
|
2386
|
-
};
|
|
2387
|
-
}
|
|
2388
|
-
if (val.charAt(0) == '#' && isHash(val)) {
|
|
2389
|
-
return {
|
|
2390
|
-
typ: EnumToken.HashTokenType,
|
|
2391
|
-
val
|
|
2392
|
-
};
|
|
2393
|
-
}
|
|
2394
|
-
if ('"\''.includes(val.charAt(0))) {
|
|
2395
|
-
return {
|
|
2396
|
-
typ: EnumToken.UnclosedStringTokenType,
|
|
2397
|
-
val
|
|
2398
|
-
};
|
|
2399
|
-
}
|
|
2400
|
-
return {
|
|
2401
|
-
typ: EnumToken.LiteralTokenType,
|
|
2402
|
-
val
|
|
2372
|
+
currentPosition: { ind: -1, lin: 1, col: 0 },
|
|
2403
2373
|
};
|
|
2374
|
+
return parseTokens([...tokenize(parseInfo)].map((t) => t.token), { sourcemap: options.location }).slice(0, -1);
|
|
2404
2375
|
}
|
|
2405
2376
|
/**
|
|
2406
2377
|
* parse function tokens in a token array
|
|
@@ -2425,7 +2396,7 @@ function getTokenType(val, hint) {
|
|
|
2425
2396
|
function parseTokens(tokens, options = {}) {
|
|
2426
2397
|
for (let i = 0; i < tokens.length; i++) {
|
|
2427
2398
|
const t = tokens[i];
|
|
2428
|
-
if (t.typ == EnumToken.IdenTokenType && t.val ==
|
|
2399
|
+
if (t.typ == EnumToken.IdenTokenType && t.val == "from" && i > 0) {
|
|
2429
2400
|
const left = [];
|
|
2430
2401
|
const right = [];
|
|
2431
2402
|
let foundLeft = 0;
|
|
@@ -2433,11 +2404,13 @@ function parseTokens(tokens, options = {}) {
|
|
|
2433
2404
|
let k = i;
|
|
2434
2405
|
let l = i;
|
|
2435
2406
|
while (k > 0) {
|
|
2436
|
-
if (tokens[k - 1].typ == EnumToken.CommentTokenType ||
|
|
2407
|
+
if (tokens[k - 1].typ == EnumToken.CommentTokenType ||
|
|
2408
|
+
tokens[k - 1].typ == EnumToken.WhitespaceTokenType) {
|
|
2437
2409
|
left.push(tokens[--k]);
|
|
2438
2410
|
continue;
|
|
2439
2411
|
}
|
|
2440
|
-
if (tokens[k - 1].typ == EnumToken.IdenTokenType ||
|
|
2412
|
+
if (tokens[k - 1].typ == EnumToken.IdenTokenType ||
|
|
2413
|
+
tokens[k - 1].typ == EnumToken.DashedIdenTokenType) {
|
|
2441
2414
|
foundLeft++;
|
|
2442
2415
|
left.push(tokens[--k]);
|
|
2443
2416
|
continue;
|
|
@@ -2467,17 +2440,27 @@ function parseTokens(tokens, options = {}) {
|
|
|
2467
2440
|
typ: EnumToken.ComposesSelectorNodeType,
|
|
2468
2441
|
l: left,
|
|
2469
2442
|
r: right.reduce((a, b) => {
|
|
2470
|
-
return a == null
|
|
2471
|
-
|
|
2443
|
+
return a == null
|
|
2444
|
+
? b
|
|
2445
|
+
: b.typ == EnumToken.IdenTokenType || b.typ == EnumToken.StringTokenType
|
|
2446
|
+
? b
|
|
2447
|
+
: a;
|
|
2448
|
+
}, null),
|
|
2472
2449
|
});
|
|
2473
2450
|
i = k;
|
|
2474
2451
|
continue;
|
|
2475
2452
|
}
|
|
2476
2453
|
}
|
|
2477
|
-
if (t.typ == EnumToken.WhitespaceTokenType &&
|
|
2478
|
-
i
|
|
2479
|
-
|
|
2480
|
-
|
|
2454
|
+
if (t.typ == EnumToken.WhitespaceTokenType &&
|
|
2455
|
+
(i == 0 ||
|
|
2456
|
+
i + 1 == tokens.length ||
|
|
2457
|
+
[
|
|
2458
|
+
EnumToken.CommaTokenType,
|
|
2459
|
+
EnumToken.GteTokenType,
|
|
2460
|
+
EnumToken.LteTokenType,
|
|
2461
|
+
EnumToken.ColumnCombinatorTokenType,
|
|
2462
|
+
].includes(tokens[i + 1].typ) ||
|
|
2463
|
+
(i > 0 && trimWhiteSpace.includes(tokens[i - 1].typ)))) {
|
|
2481
2464
|
tokens.splice(i--, 1);
|
|
2482
2465
|
continue;
|
|
2483
2466
|
}
|
|
@@ -2488,7 +2471,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
2488
2471
|
tokens[i + 1].typ = EnumToken.PseudoClassFuncTokenType;
|
|
2489
2472
|
}
|
|
2490
2473
|
else if (typ == EnumToken.IdenTokenType) {
|
|
2491
|
-
tokens[i + 1].val =
|
|
2474
|
+
tokens[i + 1].val = ":" + tokens[i + 1].val;
|
|
2492
2475
|
tokens[i + 1].typ = EnumToken.PseudoClassTokenType;
|
|
2493
2476
|
}
|
|
2494
2477
|
if (typ == EnumToken.FunctionTokenType || typ == EnumToken.IdenTokenType) {
|
|
@@ -2514,7 +2497,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
2514
2497
|
}
|
|
2515
2498
|
const attr = Object.assign(t, {
|
|
2516
2499
|
typ: inAttr == 0 ? EnumToken.AttrTokenType : EnumToken.InvalidAttrTokenType,
|
|
2517
|
-
chi: tokens.splice(i + 1, k - i)
|
|
2500
|
+
chi: tokens.splice(i + 1, k - i),
|
|
2518
2501
|
});
|
|
2519
2502
|
// @ts-ignore
|
|
2520
2503
|
if (attr.chi.at(-1).typ == EnumToken.AttrEndTokenType) {
|
|
@@ -2532,11 +2515,12 @@ function parseTokens(tokens, options = {}) {
|
|
|
2532
2515
|
val = attr.chi[m];
|
|
2533
2516
|
if (val.typ == EnumToken.StringTokenType) {
|
|
2534
2517
|
const slice = val.val.slice(1, -1);
|
|
2535
|
-
if ((slice.charAt(0) !=
|
|
2518
|
+
if ((slice.charAt(0) != "-" || (slice.charAt(0) == "-" && isIdentStart(slice.charCodeAt(1)))) &&
|
|
2519
|
+
isIdent(slice)) {
|
|
2536
2520
|
Object.assign(val, { typ: EnumToken.IdenTokenType, val: slice });
|
|
2537
2521
|
}
|
|
2538
2522
|
}
|
|
2539
|
-
else if (val.typ == EnumToken.LiteralTokenType && val.val ==
|
|
2523
|
+
else if (val.typ == EnumToken.LiteralTokenType && val.val == "|") {
|
|
2540
2524
|
let upper = m;
|
|
2541
2525
|
let lower = m;
|
|
2542
2526
|
while (++upper < attr.chi.length) {
|
|
@@ -2555,7 +2539,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
2555
2539
|
attr.chi[m] = {
|
|
2556
2540
|
typ: EnumToken.NameSpaceAttributeTokenType,
|
|
2557
2541
|
l: attr.chi[lower],
|
|
2558
|
-
r: attr.chi[upper]
|
|
2542
|
+
r: attr.chi[upper],
|
|
2559
2543
|
};
|
|
2560
2544
|
attr.chi.splice(upper, 1);
|
|
2561
2545
|
if (lower >= 0) {
|
|
@@ -2564,7 +2548,12 @@ function parseTokens(tokens, options = {}) {
|
|
|
2564
2548
|
}
|
|
2565
2549
|
}
|
|
2566
2550
|
else if ([
|
|
2567
|
-
EnumToken.DashMatchTokenType,
|
|
2551
|
+
EnumToken.DashMatchTokenType,
|
|
2552
|
+
EnumToken.StartMatchTokenType,
|
|
2553
|
+
EnumToken.ContainMatchTokenType,
|
|
2554
|
+
EnumToken.EndMatchTokenType,
|
|
2555
|
+
EnumToken.IncludeMatchTokenType,
|
|
2556
|
+
EnumToken.DelimTokenType,
|
|
2568
2557
|
].includes(attr.chi[m].typ)) {
|
|
2569
2558
|
let upper = m;
|
|
2570
2559
|
let lower = m;
|
|
@@ -2583,14 +2572,16 @@ function parseTokens(tokens, options = {}) {
|
|
|
2583
2572
|
val = attr.chi[lower];
|
|
2584
2573
|
if (val.typ == EnumToken.StringTokenType) {
|
|
2585
2574
|
const slice = val.val.slice(1, -1);
|
|
2586
|
-
if ((slice.charAt(0) !=
|
|
2575
|
+
if ((slice.charAt(0) != "-" || (slice.charAt(0) == "-" && isIdentStart(slice.charCodeAt(1)))) &&
|
|
2576
|
+
isIdent(slice)) {
|
|
2587
2577
|
Object.assign(val, { typ: EnumToken.IdenTokenType, val: slice });
|
|
2588
2578
|
}
|
|
2589
2579
|
}
|
|
2590
2580
|
val = attr.chi[upper];
|
|
2591
2581
|
if (val.typ == EnumToken.StringTokenType) {
|
|
2592
2582
|
const slice = val.val.slice(1, -1);
|
|
2593
|
-
if ((slice.charAt(0) !=
|
|
2583
|
+
if ((slice.charAt(0) != "-" || (slice.charAt(0) == "-" && isIdentStart(slice.charCodeAt(1)))) &&
|
|
2584
|
+
isIdent(slice)) {
|
|
2594
2585
|
Object.assign(val, { typ: EnumToken.IdenTokenType, val: slice });
|
|
2595
2586
|
}
|
|
2596
2587
|
}
|
|
@@ -2601,28 +2592,31 @@ function parseTokens(tokens, options = {}) {
|
|
|
2601
2592
|
typ: EnumToken.MatchExpressionTokenType,
|
|
2602
2593
|
op: {
|
|
2603
2594
|
// @ts-ignore
|
|
2604
|
-
typ: typ == EnumToken.DelimTokenType ? EnumToken.EqualMatchTokenType : typ
|
|
2595
|
+
typ: typ == EnumToken.DelimTokenType ? EnumToken.EqualMatchTokenType : typ,
|
|
2605
2596
|
},
|
|
2606
2597
|
l: t.chi[lower],
|
|
2607
|
-
r: t.chi[upper]
|
|
2598
|
+
r: t.chi[upper],
|
|
2608
2599
|
};
|
|
2609
2600
|
if (isIdentColor(t.chi[m].l)) {
|
|
2610
|
-
t.chi[m].l.typ =
|
|
2601
|
+
t.chi[m].l.typ =
|
|
2602
|
+
EnumToken.IdenTokenType;
|
|
2611
2603
|
}
|
|
2612
2604
|
if (isIdentColor(t.chi[m].r)) {
|
|
2613
|
-
t.chi[m].r.typ =
|
|
2605
|
+
t.chi[m].r.typ =
|
|
2606
|
+
EnumToken.IdenTokenType;
|
|
2614
2607
|
}
|
|
2615
2608
|
t.chi.splice(upper, 1);
|
|
2616
2609
|
t.chi.splice(lower, 1);
|
|
2617
2610
|
upper = m;
|
|
2618
2611
|
m--;
|
|
2619
|
-
while (upper < t.chi.length &&
|
|
2612
|
+
while (upper < t.chi.length &&
|
|
2613
|
+
t.chi[upper].typ == EnumToken.WhitespaceTokenType) {
|
|
2620
2614
|
upper++;
|
|
2621
2615
|
}
|
|
2622
2616
|
if (upper < t.chi.length &&
|
|
2623
2617
|
t.chi[upper].typ == EnumToken.IdenTokenType &&
|
|
2624
|
-
[
|
|
2625
|
-
t.chi[m].attr = t.chi[upper].val;
|
|
2618
|
+
["i", "s"].includes(t.chi[upper].val.toLowerCase())) {
|
|
2619
|
+
t.chi[m].attr = (t.chi[upper].val);
|
|
2626
2620
|
t.chi.splice(upper, 1);
|
|
2627
2621
|
}
|
|
2628
2622
|
}
|
|
@@ -2642,11 +2636,12 @@ function parseTokens(tokens, options = {}) {
|
|
|
2642
2636
|
if (typ != null) {
|
|
2643
2637
|
if (typ == EnumToken.IdenTokenType) {
|
|
2644
2638
|
tokens[k + 1].typ = EnumToken.PseudoClassTokenType;
|
|
2645
|
-
tokens[k + 1].val =
|
|
2639
|
+
tokens[k + 1].val = ":" + tokens[k + 1].val;
|
|
2646
2640
|
}
|
|
2647
2641
|
else if (typ == EnumToken.FunctionTokenType) {
|
|
2648
2642
|
tokens[k + 1].typ = EnumToken.PseudoClassFuncTokenType;
|
|
2649
|
-
tokens[k + 1].val =
|
|
2643
|
+
tokens[k + 1].val =
|
|
2644
|
+
":" + tokens[k + 1].val;
|
|
2650
2645
|
}
|
|
2651
2646
|
if (typ == EnumToken.FunctionTokenType || typ == EnumToken.IdenTokenType) {
|
|
2652
2647
|
tokens.splice(k, 1);
|
|
@@ -2681,19 +2676,27 @@ function parseTokens(tokens, options = {}) {
|
|
|
2681
2676
|
for (const { value, parent } of walkValues(t.chi)) {
|
|
2682
2677
|
if (value.typ == EnumToken.WhitespaceTokenType) {
|
|
2683
2678
|
const p = (parent ?? t);
|
|
2684
|
-
for (let i = 0; i <
|
|
2679
|
+
for (let i = 0; i < p.chi.length; i++) {
|
|
2685
2680
|
// @ts-ignore
|
|
2686
2681
|
if (p.chi[i] == value) {
|
|
2687
2682
|
// @ts-ignore
|
|
2688
|
-
|
|
2683
|
+
p.chi.splice(i, 1);
|
|
2689
2684
|
i--;
|
|
2690
2685
|
break;
|
|
2691
2686
|
}
|
|
2692
2687
|
}
|
|
2693
2688
|
}
|
|
2694
|
-
else if (value.typ == EnumToken.LiteralTokenType &&
|
|
2689
|
+
else if (value.typ == EnumToken.LiteralTokenType &&
|
|
2690
|
+
["+", "-", "/", "*"].includes(value.val)) {
|
|
2695
2691
|
// @ts-ignore
|
|
2696
|
-
value.typ =
|
|
2692
|
+
value.typ =
|
|
2693
|
+
value.val === "+"
|
|
2694
|
+
? EnumToken.Add
|
|
2695
|
+
: value.val === "-"
|
|
2696
|
+
? EnumToken.Sub
|
|
2697
|
+
: value.val === "*"
|
|
2698
|
+
? EnumToken.Mul
|
|
2699
|
+
: EnumToken.Div;
|
|
2697
2700
|
// @ts-ignore
|
|
2698
2701
|
delete value.val;
|
|
2699
2702
|
}
|
|
@@ -2706,7 +2709,8 @@ function parseTokens(tokens, options = {}) {
|
|
|
2706
2709
|
return acc;
|
|
2707
2710
|
}, []);
|
|
2708
2711
|
}
|
|
2709
|
-
else if (t.typ == EnumToken.FunctionTokenType &&
|
|
2712
|
+
else if (t.typ == EnumToken.FunctionTokenType &&
|
|
2713
|
+
["minmax", "fit-content", "repeat"].includes(t.val)) {
|
|
2710
2714
|
// @ts-ignore
|
|
2711
2715
|
t.typ = EnumToken.GridTemplateFuncTokenType;
|
|
2712
2716
|
}
|
|
@@ -2725,15 +2729,18 @@ function parseTokens(tokens, options = {}) {
|
|
|
2725
2729
|
// @ts-ignore
|
|
2726
2730
|
const value = t.chi[0].val.slice(1, -1);
|
|
2727
2731
|
// @ts-ignore
|
|
2728
|
-
if (t.chi[0].val.slice(1, 5) !=
|
|
2732
|
+
if (t.chi[0].val.slice(1, 5) != "data:" && urlTokenMatcher.test(value)) {
|
|
2729
2733
|
// @ts-ignore
|
|
2730
2734
|
t.chi[0].typ = EnumToken.UrlTokenTokenType;
|
|
2731
2735
|
// @ts-ignore
|
|
2732
|
-
t.chi[0].val =
|
|
2736
|
+
t.chi[0].val =
|
|
2737
|
+
options.src !== "" && options.resolveUrls
|
|
2738
|
+
? options.resolve(value, options.src)?.absolute
|
|
2739
|
+
: value;
|
|
2733
2740
|
}
|
|
2734
2741
|
}
|
|
2735
2742
|
if (t.chi[0]?.typ == EnumToken.UrlTokenTokenType) {
|
|
2736
|
-
if (options.src !==
|
|
2743
|
+
if (options.src !== "" && options.resolveUrls) {
|
|
2737
2744
|
// @ts-ignore
|
|
2738
2745
|
t.chi[0].val = options.resolve(t.chi[0].val, options.src, options.cwd).relative;
|
|
2739
2746
|
}
|
|
@@ -2741,12 +2748,14 @@ function parseTokens(tokens, options = {}) {
|
|
|
2741
2748
|
}
|
|
2742
2749
|
// @ts-ignore
|
|
2743
2750
|
if (t.chi.length > 0) {
|
|
2744
|
-
if (t.typ == EnumToken.PseudoClassFuncTokenType &&
|
|
2751
|
+
if (t.typ == EnumToken.PseudoClassFuncTokenType &&
|
|
2752
|
+
t.val === ":is" &&
|
|
2753
|
+
options.minify) {
|
|
2745
2754
|
const count = t.chi.filter((t) => t.typ != EnumToken.CommentTokenType).length;
|
|
2746
2755
|
if (count == 1 ||
|
|
2747
|
-
(i == 0 &&
|
|
2748
|
-
|
|
2749
|
-
|
|
2756
|
+
(i == 0 && (tokens[i + 1]?.typ == EnumToken.CommaTokenType || tokens.length == i + 1)) ||
|
|
2757
|
+
(tokens[i - 1]?.typ == EnumToken.CommaTokenType &&
|
|
2758
|
+
(tokens[i + 1]?.typ == EnumToken.CommaTokenType || tokens.length == i + 1))) {
|
|
2750
2759
|
tokens.splice(i, 1, ...t.chi);
|
|
2751
2760
|
i = Math.max(0, i - t.chi.length);
|
|
2752
2761
|
}
|
|
@@ -2757,4 +2766,4 @@ function parseTokens(tokens, options = {}) {
|
|
|
2757
2766
|
return tokens;
|
|
2758
2767
|
}
|
|
2759
2768
|
|
|
2760
|
-
export { doParse, generateScopedName, getKeyName,
|
|
2769
|
+
export { doParse, generateScopedName, getKeyName, getShortNameGenerator, parseAtRule, parseDeclarations, parseString, parseTokens, trimWhiteSpace };
|