@tbela99/css-parser 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +53 -6
- package/dist/index-umd-web.js +5503 -5037
- package/dist/index.cjs +5510 -5044
- package/dist/index.d.ts +148 -41
- package/dist/lib/ast/expand.js +81 -65
- package/dist/lib/ast/features/calc.js +14 -36
- package/dist/lib/ast/features/inlinecssvariables.js +6 -17
- package/dist/lib/ast/features/prefix.js +22 -19
- package/dist/lib/ast/features/shorthand.js +1 -1
- package/dist/lib/ast/features/transform.js +17 -2
- package/dist/lib/ast/math/expression.js +74 -172
- package/dist/lib/ast/math/math.js +24 -22
- package/dist/lib/ast/minify.js +249 -199
- package/dist/lib/ast/transform/compute.js +18 -41
- package/dist/lib/ast/transform/matrix.js +36 -36
- package/dist/lib/ast/transform/minify.js +37 -59
- package/dist/lib/ast/transform/perspective.js +1 -1
- package/dist/lib/ast/transform/rotate.js +13 -13
- package/dist/lib/ast/transform/scale.js +8 -8
- package/dist/lib/ast/transform/skew.js +4 -4
- package/dist/lib/ast/transform/translate.js +8 -8
- package/dist/lib/ast/transform/utils.js +80 -28
- package/dist/lib/ast/types.js +122 -2
- package/dist/lib/fs/resolve.js +1 -14
- package/dist/lib/parser/declaration/list.js +1 -1
- package/dist/lib/parser/declaration/map.js +1 -1
- package/dist/lib/parser/declaration/set.js +3 -3
- package/dist/lib/parser/parse.js +53 -107
- package/dist/lib/parser/tokenize.js +29 -53
- package/dist/lib/parser/utils/declaration.js +1 -1
- package/dist/lib/parser/utils/type.js +2 -2
- package/dist/lib/renderer/render.js +79 -194
- package/dist/lib/{renderer → syntax}/color/a98rgb.js +2 -2
- package/dist/lib/syntax/color/cmyk.js +104 -0
- package/dist/lib/{renderer → syntax}/color/color-mix.js +31 -33
- package/dist/lib/syntax/color/color.js +581 -0
- package/dist/lib/syntax/color/hex.js +179 -0
- package/dist/lib/syntax/color/hsl.js +201 -0
- package/dist/lib/syntax/color/hwb.js +204 -0
- package/dist/lib/syntax/color/lab.js +262 -0
- package/dist/lib/syntax/color/lch.js +194 -0
- package/dist/lib/syntax/color/oklab.js +237 -0
- package/dist/lib/syntax/color/oklch.js +166 -0
- package/dist/lib/{renderer → syntax}/color/p3.js +3 -3
- package/dist/lib/{renderer → syntax}/color/rec2020.js +11 -11
- package/dist/lib/{renderer → syntax}/color/relativecolor.js +54 -41
- package/dist/lib/syntax/color/rgb.js +140 -0
- package/dist/lib/{renderer → syntax}/color/srgb.js +58 -46
- package/dist/lib/syntax/color/utils/components.js +46 -0
- package/dist/lib/{renderer → syntax}/color/utils/constants.js +6 -33
- package/dist/lib/syntax/color/utils/distance.js +40 -0
- package/dist/lib/{renderer → syntax}/color/xyz.js +27 -14
- package/dist/lib/{renderer → syntax}/color/xyzd50.js +8 -8
- package/dist/lib/syntax/syntax.js +78 -77
- package/dist/lib/syntax/utils.js +70 -0
- package/dist/lib/validation/at-rules/container.js +1 -1
- package/dist/lib/validation/at-rules/counter-style.js +1 -1
- package/dist/lib/validation/at-rules/custom-media.js +1 -1
- package/dist/lib/validation/at-rules/document.js +2 -2
- package/dist/lib/validation/at-rules/font-feature-values.js +2 -2
- package/dist/lib/validation/at-rules/import.js +5 -5
- package/dist/lib/validation/at-rules/keyframes.js +3 -13
- package/dist/lib/validation/at-rules/layer.js +1 -1
- package/dist/lib/validation/at-rules/media.js +1 -1
- package/dist/lib/validation/at-rules/namespace.js +1 -1
- package/dist/lib/validation/at-rules/page-margin-box.js +1 -1
- package/dist/lib/validation/at-rules/page.js +1 -1
- package/dist/lib/validation/at-rules/supports.js +7 -7
- package/dist/lib/validation/at-rules/when.js +1 -1
- package/dist/lib/validation/atrule.js +2 -2
- package/dist/lib/validation/config.js +0 -3
- package/dist/lib/validation/config.json.js +1 -1
- package/dist/lib/validation/parser/parse.js +8 -11
- package/dist/lib/validation/selector.js +1 -9
- package/dist/lib/validation/syntax.js +67 -137
- package/dist/lib/validation/syntaxes/complex-selector-list.js +2 -19
- package/dist/lib/validation/syntaxes/complex-selector.js +1 -1
- package/dist/lib/validation/syntaxes/compound-selector.js +5 -24
- package/dist/lib/validation/syntaxes/family-name.js +5 -40
- package/dist/lib/validation/syntaxes/keyframe-selector.js +3 -22
- package/dist/lib/validation/syntaxes/layer-name.js +1 -1
- package/dist/lib/validation/syntaxes/relative-selector-list.js +1 -25
- package/dist/lib/validation/syntaxes/relative-selector.js +1 -1
- package/dist/lib/validation/syntaxes/url.js +3 -34
- package/dist/lib/validation/utils/list.js +2 -9
- package/dist/lib/validation/utils/whitespace.js +1 -1
- package/dist/node/index.js +4 -2
- package/dist/web/index.js +4 -2
- package/package.json +4 -4
- package/.editorconfig +0 -484
- package/dist/lib/ast/transform/convert.js +0 -33
- package/dist/lib/ast/utils/utils.js +0 -104
- package/dist/lib/renderer/color/color.js +0 -654
- package/dist/lib/renderer/color/hex.js +0 -105
- package/dist/lib/renderer/color/hsl.js +0 -125
- package/dist/lib/renderer/color/hwb.js +0 -103
- package/dist/lib/renderer/color/lab.js +0 -148
- package/dist/lib/renderer/color/lch.js +0 -90
- package/dist/lib/renderer/color/oklab.js +0 -131
- package/dist/lib/renderer/color/oklch.js +0 -75
- package/dist/lib/renderer/color/rgb.js +0 -50
- package/dist/lib/renderer/color/utils/components.js +0 -34
- package/dist/lib/validation/syntaxes/keyframe-block-list.js +0 -28
- package/dist/lib/{renderer → syntax}/color/hsv.js +0 -0
- package/dist/lib/{renderer → syntax}/color/prophotorgb.js +1 -1
- /package/dist/lib/{renderer → syntax}/color/utils/matrix.js +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ValidationTokenEnum } from './types.js';
|
|
2
2
|
import { isIdent, isPseudo } from '../../syntax/syntax.js';
|
|
3
|
-
import { getTokenType as getTokenType$1 } from '../../parser/parse.js';
|
|
4
|
-
import '../../parser/tokenize.js';
|
|
5
|
-
import '../../parser/utils/config.js';
|
|
6
3
|
import { EnumToken } from '../../ast/types.js';
|
|
7
4
|
import '../../ast/minify.js';
|
|
8
5
|
import '../../ast/walk.js';
|
|
9
|
-
import '../../
|
|
6
|
+
import { getTokenType as getTokenType$1 } from '../../parser/parse.js';
|
|
7
|
+
import '../../parser/tokenize.js';
|
|
8
|
+
import '../../parser/utils/config.js';
|
|
9
|
+
import '../../syntax/color/utils/constants.js';
|
|
10
10
|
import '../../renderer/sourcemap/lib/encode.js';
|
|
11
11
|
|
|
12
12
|
const skipped = [
|
|
@@ -175,7 +175,6 @@ function parseSyntax(syntax) {
|
|
|
175
175
|
typ: ValidationTokenEnum.Root,
|
|
176
176
|
chi: []
|
|
177
177
|
}, 'pos', { ...objectProperties, value: { ind: 0, lin: 1, col: 0 } });
|
|
178
|
-
// return minify(doParseSyntax(syntaxes, tokenize(syntaxes), root)) as ValidationRootToken;
|
|
179
178
|
return minify(doParseSyntax(syntax, tokenize(syntax), root));
|
|
180
179
|
}
|
|
181
180
|
function matchParens(syntax, iterator) {
|
|
@@ -351,9 +350,6 @@ function matchAtRule(syntax, iterator) {
|
|
|
351
350
|
token.typ = ValidationTokenEnum.AtRule;
|
|
352
351
|
break;
|
|
353
352
|
}
|
|
354
|
-
if (item.value.typ != ValidationTokenEnum.Whitespace) {
|
|
355
|
-
console.error('unexpected token', item.value);
|
|
356
|
-
}
|
|
357
353
|
item = iterator.next();
|
|
358
354
|
if (item.done) {
|
|
359
355
|
break;
|
|
@@ -665,6 +661,10 @@ function parseSyntaxTokens(syntax, iterator) {
|
|
|
665
661
|
}
|
|
666
662
|
}
|
|
667
663
|
}
|
|
664
|
+
if ('occurence' in item.value) {
|
|
665
|
+
// @ts-ignore
|
|
666
|
+
items[i].occurence = { ...item.value.occurence };
|
|
667
|
+
}
|
|
668
668
|
break;
|
|
669
669
|
case ValidationTokenEnum.Pipe:
|
|
670
670
|
item.value.chi = item.value.chi.map((t) => parseSyntaxTokens(syntax, t[Symbol.iterator]()));
|
|
@@ -966,9 +966,6 @@ function renderSyntax(token, parent) {
|
|
|
966
966
|
return '{' + token.chi.reduce((acc, t) => acc + renderSyntax(t), '') + '}';
|
|
967
967
|
case ValidationTokenEnum.DeclarationDefinitionToken:
|
|
968
968
|
return token.nam + ': ' + renderSyntax(token.val);
|
|
969
|
-
// case ValidationTokenEnum.ColumnArrayToken:
|
|
970
|
-
//
|
|
971
|
-
// return (token as ValidationColumnArrayToken).chi.reduce((acc: string, curr: ValidationToken) => acc + (acc.trim().length > 0 ? '||' : '') + renderSyntax(curr), '');
|
|
972
969
|
default:
|
|
973
970
|
throw new Error('Unhandled token: ' + JSON.stringify({ token }, null, 1));
|
|
974
971
|
}
|
|
@@ -4,23 +4,15 @@ import '../ast/walk.js';
|
|
|
4
4
|
import '../parser/parse.js';
|
|
5
5
|
import '../parser/tokenize.js';
|
|
6
6
|
import '../parser/utils/config.js';
|
|
7
|
-
import '../
|
|
7
|
+
import '../syntax/color/utils/constants.js';
|
|
8
8
|
import '../renderer/sourcemap/lib/encode.js';
|
|
9
9
|
import { validateRelativeSelectorList } from './syntaxes/relative-selector-list.js';
|
|
10
10
|
import './syntaxes/complex-selector.js';
|
|
11
|
-
import { validateKeyframeBlockList } from './syntaxes/keyframe-block-list.js';
|
|
12
11
|
import './syntax.js';
|
|
13
12
|
import './config.js';
|
|
14
13
|
import { validateSelectorList } from './syntaxes/selector-list.js';
|
|
15
14
|
|
|
16
15
|
function validateSelector(selector, options, root) {
|
|
17
|
-
if (root == null) {
|
|
18
|
-
return validateSelectorList(selector, root, options);
|
|
19
|
-
}
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
if (root.typ == EnumToken.AtRuleNodeType && root.nam.match(/^(-[a-z]+-)?keyframes$/)) {
|
|
22
|
-
return validateKeyframeBlockList(selector);
|
|
23
|
-
}
|
|
24
16
|
let isNested = root.typ == EnumToken.RuleNodeType ? 1 : 0;
|
|
25
17
|
let currentRoot = root.parent;
|
|
26
18
|
while (currentRoot != null && isNested == 0) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ValidationTokenEnum } from './parser/types.js';
|
|
2
2
|
import { renderSyntax } from './parser/parse.js';
|
|
3
|
-
import { EnumToken, SyntaxValidationResult } from '../ast/types.js';
|
|
3
|
+
import { EnumToken, SyntaxValidationResult, ColorType } from '../ast/types.js';
|
|
4
4
|
import '../ast/minify.js';
|
|
5
5
|
import '../ast/walk.js';
|
|
6
6
|
import '../parser/parse.js';
|
|
@@ -8,7 +8,7 @@ import '../parser/tokenize.js';
|
|
|
8
8
|
import '../parser/utils/config.js';
|
|
9
9
|
import { wildCardFuncs, isIdentColor, mathFuncs } from '../syntax/syntax.js';
|
|
10
10
|
import { renderToken } from '../renderer/render.js';
|
|
11
|
-
import { funcLike,
|
|
11
|
+
import { funcLike, colorsFunc } from '../syntax/color/utils/constants.js';
|
|
12
12
|
import { getSyntaxConfig, getParsedSyntax, getSyntax } from './config.js';
|
|
13
13
|
import './syntaxes/complex-selector.js';
|
|
14
14
|
|
|
@@ -17,12 +17,12 @@ const config = getSyntaxConfig();
|
|
|
17
17
|
const allValues = getSyntaxConfig()["declarations" /* ValidationSyntaxGroupEnum.Declarations */].all.syntax.trim().split(/[\s|]+/g);
|
|
18
18
|
function createContext(input) {
|
|
19
19
|
const values = input.slice();
|
|
20
|
-
const result = values.slice();
|
|
21
|
-
if (result.at(-1)?.typ == EnumToken.WhitespaceTokenType) {
|
|
22
|
-
result.pop();
|
|
23
|
-
}
|
|
20
|
+
const result = values.filter(token => token.typ != EnumToken.CommentTokenType).slice();
|
|
24
21
|
return {
|
|
25
22
|
index: -1,
|
|
23
|
+
get length() {
|
|
24
|
+
return this.index < 0 ? result.length : this.index > result.length ? 0 : result.length - this.index;
|
|
25
|
+
},
|
|
26
26
|
peek() {
|
|
27
27
|
let index = this.index + 1;
|
|
28
28
|
if (index >= result.length) {
|
|
@@ -42,15 +42,8 @@ function createContext(input) {
|
|
|
42
42
|
},
|
|
43
43
|
consume(token, howMany) {
|
|
44
44
|
let newIndex = result.indexOf(token, this.index + 1);
|
|
45
|
-
if (newIndex == -1 || newIndex < this.index) {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
45
|
howMany ??= 0;
|
|
49
46
|
let splice = 1;
|
|
50
|
-
if (result[newIndex - 1]?.typ == EnumToken.WhitespaceTokenType) {
|
|
51
|
-
splice++;
|
|
52
|
-
newIndex--;
|
|
53
|
-
}
|
|
54
47
|
result.splice(this.index + 1, 0, ...result.splice(newIndex, splice + howMany));
|
|
55
48
|
this.index += howMany + splice;
|
|
56
49
|
return true;
|
|
@@ -72,9 +65,6 @@ function createContext(input) {
|
|
|
72
65
|
this.index = index;
|
|
73
66
|
return result[this.index] ?? null;
|
|
74
67
|
},
|
|
75
|
-
tokens() {
|
|
76
|
-
return result;
|
|
77
|
-
},
|
|
78
68
|
slice() {
|
|
79
69
|
return result.slice(this.index + 1);
|
|
80
70
|
},
|
|
@@ -82,14 +72,6 @@ function createContext(input) {
|
|
|
82
72
|
const context = createContext(result.slice());
|
|
83
73
|
context.index = this.index;
|
|
84
74
|
return context;
|
|
85
|
-
},
|
|
86
|
-
// @ts-ignore
|
|
87
|
-
toJSON() {
|
|
88
|
-
return {
|
|
89
|
-
index: this.index,
|
|
90
|
-
slice: this.slice(),
|
|
91
|
-
tokens: this.tokens()
|
|
92
|
-
};
|
|
93
75
|
}
|
|
94
76
|
};
|
|
95
77
|
}
|
|
@@ -123,10 +105,7 @@ function evaluateSyntax(node, options) {
|
|
|
123
105
|
result = doEvaluateSyntax(ast, createContext(values), { ...options, visited: new WeakMap() });
|
|
124
106
|
if (result.valid == SyntaxValidationResult.Valid && !result.context.done()) {
|
|
125
107
|
let token = null;
|
|
126
|
-
|
|
127
|
-
if (token.typ == EnumToken.WhitespaceTokenType || token.typ == EnumToken.CommentTokenType) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
108
|
+
if ((token = result.context.next()) != null) {
|
|
130
109
|
return {
|
|
131
110
|
...result,
|
|
132
111
|
valid: SyntaxValidationResult.Drop,
|
|
@@ -142,13 +121,6 @@ function evaluateSyntax(node, options) {
|
|
|
142
121
|
};
|
|
143
122
|
}
|
|
144
123
|
break;
|
|
145
|
-
case EnumToken.RuleNodeType:
|
|
146
|
-
case EnumToken.AtRuleNodeType:
|
|
147
|
-
case EnumToken.KeyframeAtRuleNodeType:
|
|
148
|
-
case EnumToken.KeyFrameRuleNodeType:
|
|
149
|
-
// default:
|
|
150
|
-
//
|
|
151
|
-
// throw new Error(`Not implemented: ${node.typ}`);
|
|
152
124
|
}
|
|
153
125
|
return {
|
|
154
126
|
valid: SyntaxValidationResult.Valid,
|
|
@@ -178,7 +150,18 @@ function doEvaluateSyntax(syntaxes, context, options) {
|
|
|
178
150
|
let syntax;
|
|
179
151
|
let i = 0;
|
|
180
152
|
let result;
|
|
153
|
+
let tmpResult;
|
|
181
154
|
let token = null;
|
|
155
|
+
if (context.done()) {
|
|
156
|
+
const success = syntaxes.some(s => s.isOptional || s.isRepeatable || s.isRepeatableGroup);
|
|
157
|
+
return {
|
|
158
|
+
valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
|
|
159
|
+
node: null,
|
|
160
|
+
syntax: null,
|
|
161
|
+
error: '',
|
|
162
|
+
context
|
|
163
|
+
};
|
|
164
|
+
}
|
|
182
165
|
for (; i < syntaxes.length; i++) {
|
|
183
166
|
syntax = syntaxes[i];
|
|
184
167
|
if (context.done()) {
|
|
@@ -188,6 +171,10 @@ function doEvaluateSyntax(syntaxes, context, options) {
|
|
|
188
171
|
break;
|
|
189
172
|
}
|
|
190
173
|
token = context.peek();
|
|
174
|
+
// if var() is the last token, then match the remaining syntax and return
|
|
175
|
+
if (context.length == 1 && token.typ == EnumToken.FunctionTokenType && 'var' === token.val?.toLowerCase?.()) {
|
|
176
|
+
return doEvaluateSyntax(getParsedSyntax("functions" /* ValidationSyntaxGroupEnum.Functions */, 'var')?.[0]?.chi ?? [], createContext(token.chi), options);
|
|
177
|
+
}
|
|
191
178
|
if (syntax.typ == ValidationTokenEnum.Whitespace) {
|
|
192
179
|
if (context.peek()?.typ == EnumToken.WhitespaceTokenType) {
|
|
193
180
|
context.next();
|
|
@@ -198,7 +185,13 @@ function doEvaluateSyntax(syntaxes, context, options) {
|
|
|
198
185
|
result = matchList(syntax, context, options);
|
|
199
186
|
}
|
|
200
187
|
else if (options.isRepeatable !== false && syntax.isRepeatable) {
|
|
201
|
-
|
|
188
|
+
tmpResult = matchRepeatable(syntax, context, options);
|
|
189
|
+
if (tmpResult.valid == SyntaxValidationResult.Valid) {
|
|
190
|
+
result = tmpResult;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
202
195
|
}
|
|
203
196
|
else if (options.occurence !== false && syntax.occurence != null) {
|
|
204
197
|
result = matchOccurence(syntax, context, options);
|
|
@@ -252,9 +245,9 @@ function matchAtLeastOnce(syntax, context, options) {
|
|
|
252
245
|
}
|
|
253
246
|
return {
|
|
254
247
|
valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
|
|
255
|
-
node: context.
|
|
248
|
+
node: context.peek(),
|
|
256
249
|
syntax,
|
|
257
|
-
error: success ? '' : `could not match
|
|
250
|
+
error: success ? '' : `could not match syntax: ${renderSyntax(syntax)}`,
|
|
258
251
|
context
|
|
259
252
|
};
|
|
260
253
|
}
|
|
@@ -277,7 +270,7 @@ function matchRepeatable(syntax, context, options) {
|
|
|
277
270
|
};
|
|
278
271
|
}
|
|
279
272
|
function matchList(syntax, context, options) {
|
|
280
|
-
let success
|
|
273
|
+
let success;
|
|
281
274
|
let result;
|
|
282
275
|
let count = 0;
|
|
283
276
|
let con = context.clone();
|
|
@@ -286,15 +279,6 @@ function matchList(syntax, context, options) {
|
|
|
286
279
|
while (!con.done() && con.peek()?.typ != EnumToken.CommaTokenType) {
|
|
287
280
|
tokens.push(con.next());
|
|
288
281
|
}
|
|
289
|
-
if (tokens.length == 0) {
|
|
290
|
-
return {
|
|
291
|
-
valid: SyntaxValidationResult.Drop,
|
|
292
|
-
node: context.peek(),
|
|
293
|
-
syntax,
|
|
294
|
-
error: `could not match list: ${renderSyntax(syntax)}`,
|
|
295
|
-
context
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
282
|
result = doEvaluateSyntax([syntax], createContext(tokens), {
|
|
299
283
|
...options,
|
|
300
284
|
isList: false,
|
|
@@ -315,7 +299,7 @@ function matchList(syntax, context, options) {
|
|
|
315
299
|
}
|
|
316
300
|
}
|
|
317
301
|
success = count > 0;
|
|
318
|
-
if (
|
|
302
|
+
if (success && syntax.occurence != null) {
|
|
319
303
|
success = count >= syntax.occurence.min;
|
|
320
304
|
if (success && syntax.occurence.max != null) {
|
|
321
305
|
success = count <= syntax.occurence.max;
|
|
@@ -323,7 +307,7 @@ function matchList(syntax, context, options) {
|
|
|
323
307
|
}
|
|
324
308
|
return {
|
|
325
309
|
valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
|
|
326
|
-
node: context.
|
|
310
|
+
node: context.peek(),
|
|
327
311
|
syntax,
|
|
328
312
|
error: '',
|
|
329
313
|
context
|
|
@@ -348,7 +332,7 @@ function matchOccurence(syntax, context, options) {
|
|
|
348
332
|
}
|
|
349
333
|
return {
|
|
350
334
|
valid: sucesss ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
|
|
351
|
-
node: context.
|
|
335
|
+
node: context.peek(),
|
|
352
336
|
syntax,
|
|
353
337
|
error: sucesss ? '' : `expected ${renderSyntax(syntax)} ${syntax.occurence.min} to ${syntax.occurence.max} occurences, got ${counter}`,
|
|
354
338
|
context
|
|
@@ -372,26 +356,13 @@ function match(syntax, context, options) {
|
|
|
372
356
|
}
|
|
373
357
|
return {
|
|
374
358
|
valid: SyntaxValidationResult.Drop,
|
|
375
|
-
node: context.
|
|
359
|
+
node: context.peek(),
|
|
376
360
|
syntax,
|
|
377
361
|
error: `expected '${ValidationTokenEnum[syntax.typ].toLowerCase()}', got '${context.done() ? null : renderToken(context.peek())}'`,
|
|
378
362
|
context
|
|
379
363
|
};
|
|
380
364
|
}
|
|
381
365
|
}
|
|
382
|
-
if (token.typ == EnumToken.WhitespaceTokenType) {
|
|
383
|
-
context.next();
|
|
384
|
-
// @ts-ignore
|
|
385
|
-
if (syntax?.typ == ValidationTokenEnum.Whitespace) {
|
|
386
|
-
return {
|
|
387
|
-
valid: SyntaxValidationResult.Valid,
|
|
388
|
-
node: null,
|
|
389
|
-
syntax,
|
|
390
|
-
error: '',
|
|
391
|
-
context
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
366
|
if (syntax.typ != ValidationTokenEnum.PropertyType && (token?.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val))) {
|
|
396
367
|
const result = doEvaluateSyntax(getParsedSyntax("functions" /* ValidationSyntaxGroupEnum.Functions */, token.val)?.[0]?.chi ?? [], createContext(token.chi), {
|
|
397
368
|
...options,
|
|
@@ -409,7 +380,7 @@ function match(syntax, context, options) {
|
|
|
409
380
|
case ValidationTokenEnum.Keyword:
|
|
410
381
|
success = (token.typ == EnumToken.IdenTokenType || token.typ == EnumToken.DashedIdenTokenType || isIdentColor(token)) &&
|
|
411
382
|
(token.val == syntax.val ||
|
|
412
|
-
syntax.val
|
|
383
|
+
syntax.val === token.val?.toLowerCase?.() ||
|
|
413
384
|
// config.declarations.all
|
|
414
385
|
allValues.includes(token.val.toLowerCase()));
|
|
415
386
|
if (success) {
|
|
@@ -427,7 +398,7 @@ function match(syntax, context, options) {
|
|
|
427
398
|
return matchPropertyType(syntax, context, options);
|
|
428
399
|
case ValidationTokenEnum.ValidationFunctionDefinition:
|
|
429
400
|
token = context.peek();
|
|
430
|
-
if (token.typ == EnumToken.ParensTokenType || !funcLike.concat(EnumToken.ColorTokenType) || (!('chi' in token))) {
|
|
401
|
+
if (token.typ == EnumToken.ParensTokenType || !funcLike.concat(EnumToken.ColorTokenType).includes(token.typ) || (!('chi' in token))) {
|
|
431
402
|
return {
|
|
432
403
|
valid: SyntaxValidationResult.Drop,
|
|
433
404
|
node: context.next(),
|
|
@@ -451,37 +422,12 @@ function match(syntax, context, options) {
|
|
|
451
422
|
occurence: null,
|
|
452
423
|
atLeastOnce: null
|
|
453
424
|
});
|
|
454
|
-
case ValidationTokenEnum.Parens:
|
|
455
|
-
token = context.peek();
|
|
456
|
-
if (token.typ != EnumToken.ParensTokenType) {
|
|
457
|
-
break;
|
|
458
|
-
}
|
|
459
|
-
success = doEvaluateSyntax(syntax.chi, createContext(token.chi), {
|
|
460
|
-
...options,
|
|
461
|
-
isRepeatable: null,
|
|
462
|
-
isList: null,
|
|
463
|
-
occurence: null,
|
|
464
|
-
atLeastOnce: null
|
|
465
|
-
}).valid == SyntaxValidationResult.Valid;
|
|
466
|
-
break;
|
|
467
425
|
case ValidationTokenEnum.Comma:
|
|
468
426
|
success = context.peek()?.typ == EnumToken.CommaTokenType;
|
|
469
427
|
if (success) {
|
|
470
428
|
context.next();
|
|
471
429
|
}
|
|
472
430
|
break;
|
|
473
|
-
case ValidationTokenEnum.Number:
|
|
474
|
-
success = context.peek()?.typ == EnumToken.NumberTokenType;
|
|
475
|
-
if (success) {
|
|
476
|
-
context.next();
|
|
477
|
-
}
|
|
478
|
-
break;
|
|
479
|
-
case ValidationTokenEnum.Whitespace:
|
|
480
|
-
success = context.peek()?.typ == EnumToken.WhitespaceTokenType;
|
|
481
|
-
if (success) {
|
|
482
|
-
context.next();
|
|
483
|
-
}
|
|
484
|
-
break;
|
|
485
431
|
case ValidationTokenEnum.Separator:
|
|
486
432
|
{
|
|
487
433
|
const token = context.peek();
|
|
@@ -496,21 +442,15 @@ function match(syntax, context, options) {
|
|
|
496
442
|
if (!wildCardFuncs.includes(syntax.val) && syntax.val != token.val) {
|
|
497
443
|
break;
|
|
498
444
|
}
|
|
499
|
-
if (
|
|
500
|
-
success = doEvaluateSyntax(syntax.chi, createContext(token.chi),
|
|
501
|
-
...options,
|
|
502
|
-
isRepeatable: null,
|
|
503
|
-
isList: null,
|
|
504
|
-
occurence: null,
|
|
505
|
-
atLeastOnce: null
|
|
506
|
-
}).valid == SyntaxValidationResult.Valid;
|
|
445
|
+
if (syntax.typ == ValidationTokenEnum.Function) {
|
|
446
|
+
success = funcLike.includes(token.typ) && syntax.val.toLowerCase() === token.val?.toLowerCase?.() && doEvaluateSyntax(syntax.chi, createContext(token.chi), options).valid == SyntaxValidationResult.Valid;
|
|
507
447
|
if (success) {
|
|
508
448
|
context.next();
|
|
509
449
|
}
|
|
510
450
|
break;
|
|
511
451
|
}
|
|
512
|
-
if (
|
|
513
|
-
success =
|
|
452
|
+
if (token.typ != EnumToken.ParensTokenType && funcLike.includes(token.typ)) {
|
|
453
|
+
success = doEvaluateSyntax(syntax.chi, createContext(token.chi), {
|
|
514
454
|
...options,
|
|
515
455
|
isRepeatable: null,
|
|
516
456
|
isList: null,
|
|
@@ -522,7 +462,6 @@ function match(syntax, context, options) {
|
|
|
522
462
|
}
|
|
523
463
|
break;
|
|
524
464
|
}
|
|
525
|
-
// throw new Error(`Not implemented: ${ValidationTokenEnum[syntax.typ] ?? syntax.typ} : ${renderSyntax(syntax)} : ${renderToken(context.peek() as Token)} : ${JSON.stringify(syntax, null, 1)} | ${JSON.stringify(context.peek(), null, 1)}`);
|
|
526
465
|
}
|
|
527
466
|
if (!success && token.typ == EnumToken.IdenTokenType && allValues.includes(token.val.toLowerCase())) {
|
|
528
467
|
success = true;
|
|
@@ -539,7 +478,9 @@ function match(syntax, context, options) {
|
|
|
539
478
|
function matchPropertyType(syntax, context, options) {
|
|
540
479
|
if (![
|
|
541
480
|
'bg-position',
|
|
542
|
-
'
|
|
481
|
+
'integer',
|
|
482
|
+
'length-percentage', 'flex', 'calc-sum', 'color',
|
|
483
|
+
'color-base', 'system-color', 'deprecated-system-color',
|
|
543
484
|
'pseudo-class-selector', 'pseudo-element-selector'
|
|
544
485
|
].includes(syntax.val)) {
|
|
545
486
|
if (syntax.val in config["syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */]) {
|
|
@@ -633,7 +574,7 @@ function matchPropertyType(syntax, context, options) {
|
|
|
633
574
|
token = context.peek();
|
|
634
575
|
continue;
|
|
635
576
|
}
|
|
636
|
-
success = token.typ == EnumToken.LengthTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val ==
|
|
577
|
+
success = token.typ == EnumToken.LengthTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0);
|
|
637
578
|
if (!success) {
|
|
638
579
|
break;
|
|
639
580
|
}
|
|
@@ -683,14 +624,14 @@ function matchPropertyType(syntax, context, options) {
|
|
|
683
624
|
success = token.typ == EnumToken.DashedIdenTokenType;
|
|
684
625
|
break;
|
|
685
626
|
case 'system-color':
|
|
686
|
-
success = (token.typ == EnumToken.ColorTokenType && token.kin ==
|
|
627
|
+
success = (token.typ == EnumToken.ColorTokenType && token.kin == ColorType.SYS) || (token.typ == EnumToken.IdenTokenType && 'currentcolor' === token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
|
|
687
628
|
break;
|
|
688
629
|
case 'deprecated-system-color':
|
|
689
|
-
success = (token.typ == EnumToken.ColorTokenType && token.kin ==
|
|
630
|
+
success = (token.typ == EnumToken.ColorTokenType && token.kin == ColorType.DPSYS) || (token.typ == EnumToken.IdenTokenType && 'currentcolor' === token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
|
|
690
631
|
break;
|
|
691
632
|
case 'color':
|
|
692
633
|
case 'color-base':
|
|
693
|
-
success = token.typ == EnumToken.ColorTokenType || (token.typ == EnumToken.IdenTokenType && token.val.
|
|
634
|
+
success = token.typ == EnumToken.ColorTokenType || (token.typ == EnumToken.IdenTokenType && 'currentcolor' === token.val.toLowerCase()) || (token.typ == EnumToken.IdenTokenType && 'transparent' === token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
|
|
694
635
|
if (!success && token.typ == EnumToken.FunctionTokenType && colorsFunc.includes(token.val)) {
|
|
695
636
|
success = doEvaluateSyntax(getParsedSyntax("functions" /* ValidationSyntaxGroupEnum.Functions */, token.val)?.[0]?.chi, createContext(token.chi), {
|
|
696
637
|
...options,
|
|
@@ -702,10 +643,10 @@ function matchPropertyType(syntax, context, options) {
|
|
|
702
643
|
}
|
|
703
644
|
break;
|
|
704
645
|
case 'hex-color':
|
|
705
|
-
success = (token.typ == EnumToken.ColorTokenType && token.kin ==
|
|
646
|
+
success = (token.typ == EnumToken.ColorTokenType && token.kin == ColorType.HEX) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
|
|
706
647
|
break;
|
|
707
648
|
case 'integer':
|
|
708
|
-
success = (token.typ == EnumToken.NumberTokenType && Number.isInteger(+(token.val))) || (token.typ == EnumToken.FunctionTokenType && token.val ==
|
|
649
|
+
success = (token.typ == EnumToken.NumberTokenType && Number.isInteger(+(token.val))) || (token.typ == EnumToken.FunctionTokenType && mathFuncs.includes(token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val)));
|
|
709
650
|
if ('range' in syntax) {
|
|
710
651
|
success = success && +token.val >= +syntax.range[0] && +token.val <= +syntax.range[1];
|
|
711
652
|
}
|
|
@@ -731,31 +672,31 @@ function matchPropertyType(syntax, context, options) {
|
|
|
731
672
|
}
|
|
732
673
|
break;
|
|
733
674
|
case 'angle':
|
|
734
|
-
success = token.typ == EnumToken.AngleTokenType || (token.typ == EnumToken.NumberTokenType && token.val ==
|
|
675
|
+
success = token.typ == EnumToken.AngleTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
|
|
735
676
|
break;
|
|
736
677
|
case 'length':
|
|
737
|
-
success = token.typ == EnumToken.LengthTokenType || (token.typ == EnumToken.NumberTokenType && token.val ==
|
|
678
|
+
success = token.typ == EnumToken.LengthTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
|
|
738
679
|
break;
|
|
739
680
|
case 'percentage':
|
|
740
|
-
success = token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val ==
|
|
681
|
+
success = token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
|
|
741
682
|
break;
|
|
742
683
|
case 'length-percentage':
|
|
743
|
-
success = token.typ == EnumToken.LengthTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val ==
|
|
684
|
+
success = token.typ == EnumToken.LengthTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
|
|
744
685
|
break;
|
|
745
686
|
case 'resolution':
|
|
746
|
-
success = token.typ == EnumToken.ResolutionTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val ==
|
|
687
|
+
success = token.typ == EnumToken.ResolutionTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
|
|
747
688
|
break;
|
|
748
689
|
case 'hash-token':
|
|
749
690
|
success = token.typ == EnumToken.HashTokenType;
|
|
750
691
|
break;
|
|
751
692
|
case 'string':
|
|
752
|
-
success = token.typ == EnumToken.StringTokenType || token.typ == EnumToken.IdenTokenType || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
|
|
693
|
+
success = token.typ == EnumToken.StringTokenType || token.typ == EnumToken.UrlTokenTokenType || token.typ == EnumToken.HashTokenType || token.typ == EnumToken.IdenTokenType || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
|
|
753
694
|
break;
|
|
754
695
|
case 'time':
|
|
755
696
|
success = token.typ == EnumToken.TimeTokenType || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
|
|
756
697
|
break;
|
|
757
698
|
case 'zero':
|
|
758
|
-
success = token.val ==
|
|
699
|
+
success = token.val == 0 || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
|
|
759
700
|
break;
|
|
760
701
|
case 'pseudo-element-selector':
|
|
761
702
|
success = token.typ == EnumToken.PseudoElementTokenType;
|
|
@@ -775,9 +716,6 @@ function matchPropertyType(syntax, context, options) {
|
|
|
775
716
|
}
|
|
776
717
|
}
|
|
777
718
|
break;
|
|
778
|
-
// default:
|
|
779
|
-
//
|
|
780
|
-
// throw new Error(`Not implemented: ${ValidationTokenEnum[syntax.typ] ?? syntax.typ} : ${renderSyntax(syntax)}\n${JSON.stringify(syntax, null, 1)}`);
|
|
781
719
|
}
|
|
782
720
|
if (!success &&
|
|
783
721
|
token.typ == EnumToken.FunctionTokenType &&
|
|
@@ -813,9 +751,6 @@ function someOf(syntaxes, context, options) {
|
|
|
813
751
|
let success = false;
|
|
814
752
|
const matched = [];
|
|
815
753
|
for (i = 0; i < syntaxes.length; i++) {
|
|
816
|
-
if (context.peek()?.typ == EnumToken.WhitespaceTokenType) {
|
|
817
|
-
context.next();
|
|
818
|
-
}
|
|
819
754
|
result = doEvaluateSyntax(syntaxes[i], context.clone(), options);
|
|
820
755
|
if (result.valid == SyntaxValidationResult.Valid) {
|
|
821
756
|
success = true;
|
|
@@ -831,9 +766,9 @@ function someOf(syntaxes, context, options) {
|
|
|
831
766
|
}
|
|
832
767
|
return matched[0] ?? {
|
|
833
768
|
valid: SyntaxValidationResult.Drop,
|
|
834
|
-
node: context.
|
|
769
|
+
node: context.peek(),
|
|
835
770
|
syntax: null,
|
|
836
|
-
error: success ? '' : `could not match
|
|
771
|
+
error: success ? '' : `could not match syntax: ${syntaxes.reduce((acc, curr) => acc + (acc.length > 0 ? ' | ' : '') + curr.reduce((acc, curr) => acc + renderSyntax(curr), ''), '')}`,
|
|
837
772
|
context
|
|
838
773
|
};
|
|
839
774
|
}
|
|
@@ -855,9 +790,9 @@ function anyOf(syntaxes, context, options) {
|
|
|
855
790
|
}
|
|
856
791
|
return {
|
|
857
792
|
valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
|
|
858
|
-
node: context.
|
|
793
|
+
node: context.peek(),
|
|
859
794
|
syntax: null,
|
|
860
|
-
error: success ? '' : `could not match
|
|
795
|
+
error: success ? '' : `could not match syntax: ${syntaxes.reduce((acc, curr) => acc + '[' + curr.reduce((acc, curr) => acc + renderSyntax(curr), '') + ']', '')}`,
|
|
861
796
|
context
|
|
862
797
|
};
|
|
863
798
|
}
|
|
@@ -884,9 +819,6 @@ function allOf(syntax, context, options) {
|
|
|
884
819
|
for (i = 0; i < slice.length; i++) {
|
|
885
820
|
if (slice[i].typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(slice[i].val.toLowerCase())) {
|
|
886
821
|
vars.push(slice[i]);
|
|
887
|
-
if (slice[i + 1]?.typ == EnumToken.WhitespaceTokenType) {
|
|
888
|
-
vars.push(slice[++i]);
|
|
889
|
-
}
|
|
890
822
|
continue;
|
|
891
823
|
}
|
|
892
824
|
if (slice[i].typ == EnumToken.CommaTokenType || (slice[i].typ == EnumToken.LiteralTokenType && slice[i].val == '/')) {
|
|
@@ -903,18 +835,16 @@ function allOf(syntax, context, options) {
|
|
|
903
835
|
let j;
|
|
904
836
|
for (i = 0; i < syntax.length; i++) {
|
|
905
837
|
if (syntax[i].length == 1 && syntax[i][0].isOptional) {
|
|
906
|
-
syntax[i][0].isOptional = false;
|
|
907
838
|
j = 0;
|
|
908
839
|
cp = con.clone();
|
|
909
840
|
slice = cp.slice();
|
|
910
841
|
if (cp.done()) {
|
|
911
|
-
syntax[i][0].isOptional = true;
|
|
912
842
|
syntax.splice(i, 1);
|
|
913
843
|
i = -1;
|
|
914
844
|
continue;
|
|
915
845
|
}
|
|
916
846
|
while (!cp.done()) {
|
|
917
|
-
result = doEvaluateSyntax(syntax[i], cp.clone(), options);
|
|
847
|
+
result = doEvaluateSyntax(syntax[i], cp.clone(), { ...options, isOptional: false });
|
|
918
848
|
if (result.valid == SyntaxValidationResult.Valid) {
|
|
919
849
|
let end = slice.indexOf(cp.current());
|
|
920
850
|
if (end == -1) {
|
|
@@ -929,9 +859,8 @@ function allOf(syntax, context, options) {
|
|
|
929
859
|
cp.next();
|
|
930
860
|
j++;
|
|
931
861
|
}
|
|
932
|
-
syntax[i][0].isOptional = true;
|
|
933
862
|
// @ts-ignore
|
|
934
|
-
if (result?.valid == SyntaxValidationResult.Valid) {
|
|
863
|
+
if (result?.valid == SyntaxValidationResult.Valid || (syntax[i].length == 1 && syntax[i][0].isOptional)) {
|
|
935
864
|
syntax.splice(i, 1);
|
|
936
865
|
i = -1;
|
|
937
866
|
}
|
|
@@ -944,12 +873,13 @@ function allOf(syntax, context, options) {
|
|
|
944
873
|
i = -1;
|
|
945
874
|
}
|
|
946
875
|
}
|
|
876
|
+
// console.error()
|
|
947
877
|
const success = syntax.length == 0;
|
|
948
878
|
return {
|
|
949
879
|
valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
|
|
950
|
-
node: context.
|
|
880
|
+
node: context.peek(),
|
|
951
881
|
syntax: syntax?.[0]?.[0] ?? null,
|
|
952
|
-
error: `could not match
|
|
882
|
+
error: `could not match syntax: ${syntax.reduce((acc, curr) => acc + '[' + curr.reduce((acc, curr) => acc + renderSyntax(curr), '') + ']', '')}`,
|
|
953
883
|
context: success ? con : context
|
|
954
884
|
};
|
|
955
885
|
}
|
|
@@ -4,7 +4,7 @@ import '../../ast/walk.js';
|
|
|
4
4
|
import '../../parser/parse.js';
|
|
5
5
|
import '../../parser/tokenize.js';
|
|
6
6
|
import '../../parser/utils/config.js';
|
|
7
|
-
import '../../
|
|
7
|
+
import '../../syntax/color/utils/constants.js';
|
|
8
8
|
import '../../renderer/sourcemap/lib/encode.js';
|
|
9
9
|
import { validateSelector } from './selector.js';
|
|
10
10
|
import { consumeWhitespace } from '../utils/whitespace.js';
|
|
@@ -13,16 +13,6 @@ import { splitTokenList } from '../utils/list.js';
|
|
|
13
13
|
function validateComplexSelectorList(tokens, root, options) {
|
|
14
14
|
tokens = tokens.slice();
|
|
15
15
|
consumeWhitespace(tokens);
|
|
16
|
-
if (tokens.length == 0) {
|
|
17
|
-
return {
|
|
18
|
-
valid: SyntaxValidationResult.Drop,
|
|
19
|
-
context: [],
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
node: root,
|
|
22
|
-
syntax: null,
|
|
23
|
-
error: 'expecting complex selector list'
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
16
|
let result = null;
|
|
27
17
|
for (const t of splitTokenList(tokens)) {
|
|
28
18
|
result = validateSelector(t, root, options);
|
|
@@ -31,14 +21,7 @@ function validateComplexSelectorList(tokens, root, options) {
|
|
|
31
21
|
}
|
|
32
22
|
}
|
|
33
23
|
// @ts-ignore
|
|
34
|
-
return result
|
|
35
|
-
valid: SyntaxValidationResult.Drop,
|
|
36
|
-
context: [],
|
|
37
|
-
// @ts-ignore
|
|
38
|
-
node: root,
|
|
39
|
-
syntax: null,
|
|
40
|
-
error: 'expecting complex selector list'
|
|
41
|
-
};
|
|
24
|
+
return result;
|
|
42
25
|
}
|
|
43
26
|
|
|
44
27
|
export { validateComplexSelectorList };
|
|
@@ -6,7 +6,7 @@ import '../../ast/walk.js';
|
|
|
6
6
|
import '../../parser/parse.js';
|
|
7
7
|
import '../../parser/tokenize.js';
|
|
8
8
|
import '../../parser/utils/config.js';
|
|
9
|
-
import '../../
|
|
9
|
+
import '../../syntax/color/utils/constants.js';
|
|
10
10
|
import '../../renderer/sourcemap/lib/encode.js';
|
|
11
11
|
import { validateCompoundSelector } from './compound-selector.js';
|
|
12
12
|
|