@tbela99/css-parser 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +484 -0
- package/README.md +13 -8
- package/dist/index-umd-web.js +2451 -2554
- package/dist/index.cjs +2605 -2708
- package/dist/index.d.ts +73 -23
- package/dist/lib/ast/expand.js +29 -4
- package/dist/lib/ast/math/expression.js +1 -1
- package/dist/lib/ast/minify.js +31 -17
- package/dist/lib/ast/types.js +2 -0
- package/dist/lib/ast/walk.js +12 -0
- package/dist/lib/parser/declaration/map.js +59 -52
- package/dist/lib/parser/declaration/set.js +0 -12
- package/dist/lib/parser/parse.js +204 -139
- package/dist/lib/parser/tokenize.js +15 -3
- package/dist/lib/renderer/color/color.js +2 -2
- package/dist/lib/renderer/color/hex.js +1 -1
- package/dist/lib/renderer/color/hsl.js +1 -1
- package/dist/lib/renderer/color/hwb.js +2 -2
- package/dist/lib/renderer/color/lab.js +3 -2
- package/dist/lib/renderer/color/lch.js +1 -1
- package/dist/lib/renderer/color/oklab.js +2 -2
- package/dist/lib/renderer/color/oklch.js +1 -1
- package/dist/lib/renderer/color/p3.js +1 -1
- package/dist/lib/renderer/color/prophotoRgb.js +2 -2
- package/dist/lib/renderer/color/prophotorgb.js +2 -2
- package/dist/lib/renderer/color/rgb.js +1 -1
- package/dist/lib/renderer/color/srgb.js +2 -2
- package/dist/lib/renderer/color/utils/constants.js +1 -1
- package/dist/lib/renderer/color/xyz.js +2 -18
- package/dist/lib/renderer/color/xyzd50.js +20 -2
- package/dist/lib/renderer/render.js +37 -8
- package/dist/lib/renderer/sourcemap/sourcemap.js +1 -1
- package/dist/lib/syntax/syntax.js +337 -1
- package/dist/lib/validation/at-rules/container.js +353 -0
- package/dist/lib/validation/at-rules/counter-style.js +2 -2
- package/dist/lib/validation/at-rules/custom-media.js +52 -0
- package/dist/lib/validation/at-rules/document.js +40 -60
- package/dist/lib/validation/at-rules/else.js +5 -0
- package/dist/lib/validation/at-rules/font-feature-values.js +3 -0
- package/dist/lib/validation/at-rules/import.js +64 -59
- package/dist/lib/validation/at-rules/layer.js +3 -0
- package/dist/lib/validation/at-rules/media.js +118 -29
- package/dist/lib/validation/at-rules/supports.js +51 -20
- package/dist/lib/validation/at-rules/when.js +178 -0
- package/dist/lib/validation/atrule.js +25 -10
- package/dist/lib/validation/config.js +20 -15
- package/dist/lib/validation/config.json.js +242 -74
- package/dist/lib/validation/declaration.js +32 -10
- package/dist/lib/validation/parser/parse.js +87 -103
- package/dist/lib/validation/parser/types.js +2 -2
- package/dist/lib/validation/selector.js +6 -3
- package/dist/lib/validation/syntax.js +86 -6
- package/dist/lib/validation/syntaxes/complex-selector-list.js +16 -12
- package/dist/lib/validation/syntaxes/complex-selector.js +17 -247
- package/dist/lib/validation/syntaxes/compound-selector.js +226 -0
- package/dist/lib/validation/syntaxes/image.js +29 -0
- package/dist/lib/validation/syntaxes/keyframe-block-list.js +1 -1
- package/dist/lib/validation/syntaxes/keyframe-selector.js +1 -1
- package/dist/lib/validation/syntaxes/layer-name.js +5 -16
- package/dist/lib/validation/syntaxes/relative-selector-list.js +43 -13
- package/dist/lib/validation/utils/list.js +2 -2
- package/dist/node/index.js +1 -1
- package/dist/web/index.js +1 -1
- package/package.json +10 -9
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { ValidationLevel, EnumToken } from '../../ast/types.js';
|
|
2
2
|
import '../../ast/minify.js';
|
|
3
3
|
import '../../ast/walk.js';
|
|
4
|
-
import '../../parser/parse.js';
|
|
4
|
+
import { parseSelector } from '../../parser/parse.js';
|
|
5
5
|
import { colorFontTech, fontFeaturesTech, fontFormat } from '../../syntax/syntax.js';
|
|
6
6
|
import '../../parser/utils/config.js';
|
|
7
7
|
import '../../renderer/color/utils/constants.js';
|
|
8
8
|
import '../../renderer/sourcemap/lib/encode.js';
|
|
9
9
|
import { consumeWhitespace } from '../utils/whitespace.js';
|
|
10
10
|
import { splitTokenList } from '../utils/list.js';
|
|
11
|
-
import {
|
|
12
|
-
import { getParsedSyntax } from '../config.js';
|
|
11
|
+
import { validateComplexSelector } from '../syntaxes/complex-selector.js';
|
|
13
12
|
|
|
14
13
|
function validateAtRuleSupports(atRule, options, root) {
|
|
15
14
|
// media-query-list
|
|
@@ -19,7 +18,7 @@ function validateAtRuleSupports(atRule, options, root) {
|
|
|
19
18
|
valid: ValidationLevel.Drop,
|
|
20
19
|
matches: [],
|
|
21
20
|
node: atRule,
|
|
22
|
-
syntax: '@
|
|
21
|
+
syntax: '@' + atRule.nam,
|
|
23
22
|
error: 'expected supports query list',
|
|
24
23
|
tokens: []
|
|
25
24
|
};
|
|
@@ -37,7 +36,7 @@ function validateAtRuleSupports(atRule, options, root) {
|
|
|
37
36
|
valid: ValidationLevel.Drop,
|
|
38
37
|
matches: [],
|
|
39
38
|
node: atRule,
|
|
40
|
-
syntax: '@
|
|
39
|
+
syntax: '@' + atRule.nam,
|
|
41
40
|
error: 'expected at-rule body',
|
|
42
41
|
tokens: []
|
|
43
42
|
};
|
|
@@ -47,12 +46,13 @@ function validateAtRuleSupports(atRule, options, root) {
|
|
|
47
46
|
valid: ValidationLevel.Valid,
|
|
48
47
|
matches: [],
|
|
49
48
|
node: atRule,
|
|
50
|
-
syntax: '@
|
|
49
|
+
syntax: '@' + atRule.nam,
|
|
51
50
|
error: '',
|
|
52
51
|
tokens: []
|
|
53
52
|
};
|
|
54
53
|
}
|
|
55
54
|
function validateAtRuleSupportsConditions(atRule, tokenList) {
|
|
55
|
+
let result = null;
|
|
56
56
|
for (const tokens of splitTokenList(tokenList)) {
|
|
57
57
|
if (tokens.length == 0) {
|
|
58
58
|
// @ts-ignore
|
|
@@ -60,28 +60,52 @@ function validateAtRuleSupportsConditions(atRule, tokenList) {
|
|
|
60
60
|
valid: ValidationLevel.Drop,
|
|
61
61
|
matches: [],
|
|
62
62
|
node: tokens[0] ?? atRule,
|
|
63
|
-
syntax: '@
|
|
63
|
+
syntax: '@' + atRule.nam,
|
|
64
64
|
error: 'unexpected token',
|
|
65
65
|
tokens: []
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
let previousToken = null;
|
|
69
|
-
let result = null;
|
|
70
69
|
while (tokens.length > 0) {
|
|
71
70
|
result = validateSupportCondition(atRule, tokens[0]);
|
|
72
71
|
// supports-condition
|
|
73
|
-
if (result
|
|
72
|
+
if (result.valid == ValidationLevel.Valid) {
|
|
74
73
|
previousToken = tokens[0];
|
|
75
74
|
tokens.shift();
|
|
76
75
|
}
|
|
77
76
|
else {
|
|
78
77
|
result = validateSupportFeature(tokens[0]);
|
|
79
|
-
if (result == null || result.valid == ValidationLevel.Valid) {
|
|
78
|
+
if ( /*result == null || */result.valid == ValidationLevel.Valid) {
|
|
80
79
|
previousToken = tokens[0];
|
|
81
80
|
tokens.shift();
|
|
82
81
|
}
|
|
83
82
|
else {
|
|
84
|
-
|
|
83
|
+
if (tokens[0].typ == EnumToken.ParensTokenType) {
|
|
84
|
+
result = validateAtRuleSupportsConditions(atRule, tokens[0].chi);
|
|
85
|
+
if ( /* result == null || */result.valid == ValidationLevel.Valid) {
|
|
86
|
+
previousToken = tokens[0];
|
|
87
|
+
tokens.shift();
|
|
88
|
+
// continue;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
// if (result!= null && result.valid == ValidationLevel.Drop) {
|
|
98
|
+
//
|
|
99
|
+
// return {
|
|
100
|
+
// valid: ValidationLevel.Drop,
|
|
101
|
+
// matches: [],
|
|
102
|
+
// node: tokens[0] ?? atRule,
|
|
103
|
+
// syntax: '@' + atRule.nam,
|
|
104
|
+
// // @ts-ignore
|
|
105
|
+
// error: result.error as string ?? 'unexpected token',
|
|
106
|
+
// tokens: []
|
|
107
|
+
// };
|
|
108
|
+
// }
|
|
85
109
|
}
|
|
86
110
|
}
|
|
87
111
|
if (tokens.length == 0) {
|
|
@@ -94,7 +118,7 @@ function validateAtRuleSupportsConditions(atRule, tokenList) {
|
|
|
94
118
|
valid: ValidationLevel.Drop,
|
|
95
119
|
matches: [],
|
|
96
120
|
node: tokens[0] ?? previousToken ?? atRule,
|
|
97
|
-
syntax: '@
|
|
121
|
+
syntax: '@' + atRule.nam,
|
|
98
122
|
error: 'expected whitespace',
|
|
99
123
|
tokens: []
|
|
100
124
|
};
|
|
@@ -106,7 +130,7 @@ function validateAtRuleSupportsConditions(atRule, tokenList) {
|
|
|
106
130
|
valid: ValidationLevel.Drop,
|
|
107
131
|
matches: [],
|
|
108
132
|
node: tokens[0] ?? atRule,
|
|
109
|
-
syntax: '@
|
|
133
|
+
syntax: '@' + atRule.nam,
|
|
110
134
|
error: 'expected and/or',
|
|
111
135
|
tokens: []
|
|
112
136
|
};
|
|
@@ -117,7 +141,7 @@ function validateAtRuleSupportsConditions(atRule, tokenList) {
|
|
|
117
141
|
valid: ValidationLevel.Drop,
|
|
118
142
|
matches: [],
|
|
119
143
|
node: tokens[0] ?? atRule,
|
|
120
|
-
syntax: '@
|
|
144
|
+
syntax: '@' + atRule.nam,
|
|
121
145
|
error: 'expected supports-condition',
|
|
122
146
|
tokens: []
|
|
123
147
|
};
|
|
@@ -129,26 +153,33 @@ function validateAtRuleSupportsConditions(atRule, tokenList) {
|
|
|
129
153
|
valid: ValidationLevel.Drop,
|
|
130
154
|
matches: [],
|
|
131
155
|
node: tokens[0] ?? atRule,
|
|
132
|
-
syntax: '@
|
|
156
|
+
syntax: '@' + atRule.nam,
|
|
133
157
|
error: 'expected whitespace',
|
|
134
158
|
tokens: []
|
|
135
159
|
};
|
|
136
160
|
}
|
|
137
161
|
}
|
|
138
162
|
}
|
|
139
|
-
return
|
|
163
|
+
return {
|
|
164
|
+
valid: ValidationLevel.Valid,
|
|
165
|
+
matches: [],
|
|
166
|
+
node: atRule,
|
|
167
|
+
syntax: '@' + atRule.nam,
|
|
168
|
+
error: '',
|
|
169
|
+
tokens: []
|
|
170
|
+
};
|
|
140
171
|
}
|
|
141
172
|
function validateSupportCondition(atRule, token) {
|
|
142
173
|
if (token.typ == EnumToken.MediaFeatureNotTokenType) {
|
|
143
174
|
return validateSupportCondition(atRule, token.val);
|
|
144
175
|
}
|
|
145
|
-
if (token.typ != EnumToken.ParensTokenType) {
|
|
176
|
+
if (token.typ != EnumToken.ParensTokenType && !(['when', 'else'].includes(atRule.nam) && token.typ == EnumToken.FunctionTokenType && ['supports', 'font-format', 'font-tech'].includes(token.val))) {
|
|
146
177
|
// @ts-ignore
|
|
147
178
|
return {
|
|
148
179
|
valid: ValidationLevel.Drop,
|
|
149
180
|
matches: [],
|
|
150
181
|
node: token,
|
|
151
|
-
syntax: '@
|
|
182
|
+
syntax: '@' + atRule.nam,
|
|
152
183
|
error: 'expected supports condition-in-parens',
|
|
153
184
|
tokens: []
|
|
154
185
|
};
|
|
@@ -163,7 +194,7 @@ function validateSupportCondition(atRule, token) {
|
|
|
163
194
|
valid: ValidationLevel.Valid,
|
|
164
195
|
matches: [],
|
|
165
196
|
node: null,
|
|
166
|
-
syntax: '@
|
|
197
|
+
syntax: '@' + atRule.nam,
|
|
167
198
|
error: '',
|
|
168
199
|
tokens: []
|
|
169
200
|
};
|
|
@@ -203,7 +234,7 @@ function validateSupportCondition(atRule, token) {
|
|
|
203
234
|
function validateSupportFeature(token) {
|
|
204
235
|
if (token.typ == EnumToken.FunctionTokenType) {
|
|
205
236
|
if (token.val.localeCompare('selector', undefined, { sensitivity: 'base' }) == 0) {
|
|
206
|
-
return
|
|
237
|
+
return validateComplexSelector(parseSelector(token.chi));
|
|
207
238
|
}
|
|
208
239
|
if (token.val.localeCompare('font-tech', undefined, { sensitivity: 'base' }) == 0) {
|
|
209
240
|
const chi = token.chi.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ));
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { ValidationLevel, EnumToken } from '../../ast/types.js';
|
|
2
|
+
import '../../ast/minify.js';
|
|
3
|
+
import '../../ast/walk.js';
|
|
4
|
+
import '../../parser/parse.js';
|
|
5
|
+
import '../../renderer/color/utils/constants.js';
|
|
6
|
+
import '../../renderer/sourcemap/lib/encode.js';
|
|
7
|
+
import '../../parser/utils/config.js';
|
|
8
|
+
import { consumeWhitespace } from '../utils/whitespace.js';
|
|
9
|
+
import { splitTokenList } from '../utils/list.js';
|
|
10
|
+
import { validateMediaFeature, validateMediaCondition } from './media.js';
|
|
11
|
+
import { validateSupportCondition } from './supports.js';
|
|
12
|
+
|
|
13
|
+
function validateAtRuleWhen(atRule, options, root) {
|
|
14
|
+
const slice = Array.isArray(atRule.tokens) ? atRule.tokens.slice() : [];
|
|
15
|
+
consumeWhitespace(slice);
|
|
16
|
+
if (slice.length == 0) {
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
return {
|
|
19
|
+
valid: ValidationLevel.Valid,
|
|
20
|
+
matches: [],
|
|
21
|
+
node: atRule,
|
|
22
|
+
syntax: '@when',
|
|
23
|
+
error: '',
|
|
24
|
+
tokens: []
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const result = validateAtRuleWhenQueryList(atRule.tokens, atRule);
|
|
28
|
+
if (result.valid == ValidationLevel.Drop) {
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
if (!('chi' in atRule)) {
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
return {
|
|
34
|
+
valid: ValidationLevel.Drop,
|
|
35
|
+
matches: [],
|
|
36
|
+
node: atRule,
|
|
37
|
+
syntax: '@when',
|
|
38
|
+
error: 'expected at-rule body',
|
|
39
|
+
tokens: []
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
valid: ValidationLevel.Valid,
|
|
44
|
+
matches: [],
|
|
45
|
+
node: atRule,
|
|
46
|
+
syntax: '@when',
|
|
47
|
+
error: '',
|
|
48
|
+
tokens: result.tokens
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// media() = media( [ <mf-plain> | <mf-boolean> | <mf-range> ] )
|
|
52
|
+
// supports() = supports( <declaration> )
|
|
53
|
+
function validateAtRuleWhenQueryList(tokenList, atRule) {
|
|
54
|
+
const matched = [];
|
|
55
|
+
let result = null;
|
|
56
|
+
for (const split of splitTokenList(tokenList)) {
|
|
57
|
+
const match = [];
|
|
58
|
+
result = null;
|
|
59
|
+
consumeWhitespace(split);
|
|
60
|
+
if (split.length == 0) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
while (split.length > 0) {
|
|
64
|
+
if (split[0].typ != EnumToken.FunctionTokenType || !['media', 'supports', 'font-tech', 'font-format'].includes(split[0].val)) {
|
|
65
|
+
result = {
|
|
66
|
+
valid: ValidationLevel.Drop,
|
|
67
|
+
matches: [],
|
|
68
|
+
node: split[0] ?? atRule,
|
|
69
|
+
syntax: '@when',
|
|
70
|
+
error: 'unexpected token',
|
|
71
|
+
tokens: []
|
|
72
|
+
};
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
const chi = split[0].chi.slice();
|
|
76
|
+
consumeWhitespace(chi);
|
|
77
|
+
if (split[0].val == 'media') {
|
|
78
|
+
// result = valida
|
|
79
|
+
if (chi.length != 1 || !(validateMediaFeature(chi[0]) || validateMediaCondition(split[0], atRule))) {
|
|
80
|
+
result = {
|
|
81
|
+
valid: ValidationLevel.Drop,
|
|
82
|
+
matches: [],
|
|
83
|
+
node: split[0] ?? atRule,
|
|
84
|
+
syntax: 'media( [ <mf-plain> | <mf-boolean> | <mf-range> ] )',
|
|
85
|
+
error: 'unexpected token',
|
|
86
|
+
tokens: []
|
|
87
|
+
};
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (['supports', 'font-tech', 'font-format'].includes(split[0].val)) {
|
|
92
|
+
// result = valida
|
|
93
|
+
if (!validateSupportCondition(atRule, split[0])) {
|
|
94
|
+
result = {
|
|
95
|
+
valid: ValidationLevel.Drop,
|
|
96
|
+
matches: [],
|
|
97
|
+
node: split[0] ?? atRule,
|
|
98
|
+
syntax: 'media( [ <mf-plain> | <mf-boolean> | <mf-range> ] )',
|
|
99
|
+
error: 'unexpected token',
|
|
100
|
+
tokens: []
|
|
101
|
+
};
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (match.length > 0) {
|
|
106
|
+
match.push({ typ: EnumToken.WhitespaceTokenType });
|
|
107
|
+
}
|
|
108
|
+
match.push(split.shift());
|
|
109
|
+
consumeWhitespace(split);
|
|
110
|
+
if (split.length == 0) {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
if (![EnumToken.MediaFeatureAndTokenType, EnumToken.MediaFeatureOrTokenType].includes(split[0].typ)) {
|
|
114
|
+
result = {
|
|
115
|
+
valid: ValidationLevel.Drop,
|
|
116
|
+
matches: [],
|
|
117
|
+
node: split[0] ?? atRule,
|
|
118
|
+
syntax: '@when',
|
|
119
|
+
error: 'expecting and/or media-condition',
|
|
120
|
+
tokens: []
|
|
121
|
+
};
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
if (match.length > 0) {
|
|
125
|
+
match.push({ typ: EnumToken.WhitespaceTokenType });
|
|
126
|
+
}
|
|
127
|
+
match.push(split.shift());
|
|
128
|
+
consumeWhitespace(split);
|
|
129
|
+
if (split.length == 0) {
|
|
130
|
+
result = {
|
|
131
|
+
valid: ValidationLevel.Drop,
|
|
132
|
+
matches: [],
|
|
133
|
+
node: split[0] ?? atRule,
|
|
134
|
+
syntax: '@when',
|
|
135
|
+
error: 'expecting media-condition',
|
|
136
|
+
tokens: []
|
|
137
|
+
};
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (result == null && match.length > 0) {
|
|
142
|
+
matched.push(match);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (result != null) {
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
if (matched.length == 0) {
|
|
149
|
+
return {
|
|
150
|
+
valid: ValidationLevel.Drop,
|
|
151
|
+
matches: [],
|
|
152
|
+
// @ts-ignore
|
|
153
|
+
node: result?.node ?? atRule,
|
|
154
|
+
syntax: '@when',
|
|
155
|
+
error: 'invalid at-rule body',
|
|
156
|
+
tokens: []
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
tokenList.length = 0;
|
|
160
|
+
for (const match of matched) {
|
|
161
|
+
if (tokenList.length > 0) {
|
|
162
|
+
tokenList.push({
|
|
163
|
+
typ: EnumToken.CommaTokenType
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
tokenList.push(...match);
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
valid: ValidationLevel.Valid,
|
|
170
|
+
matches: [],
|
|
171
|
+
node: atRule,
|
|
172
|
+
syntax: '@when',
|
|
173
|
+
error: '',
|
|
174
|
+
tokens: tokenList
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export { validateAtRuleWhen, validateAtRuleWhenQueryList };
|
|
@@ -5,7 +5,7 @@ import '../parser/parse.js';
|
|
|
5
5
|
import '../renderer/color/utils/constants.js';
|
|
6
6
|
import '../renderer/sourcemap/lib/encode.js';
|
|
7
7
|
import '../parser/utils/config.js';
|
|
8
|
-
import {
|
|
8
|
+
import { getSyntaxConfig, getParsedSyntax } from './config.js';
|
|
9
9
|
import { validateAtRuleMedia } from './at-rules/media.js';
|
|
10
10
|
import { validateAtRuleCounterStyle } from './at-rules/counter-style.js';
|
|
11
11
|
import { validateAtRulePage } from './at-rules/page.js';
|
|
@@ -17,6 +17,10 @@ import { validateAtRuleFontFeatureValues } from './at-rules/font-feature-values.
|
|
|
17
17
|
import { validateAtRuleNamespace } from './at-rules/namespace.js';
|
|
18
18
|
import { validateAtRuleDocument } from './at-rules/document.js';
|
|
19
19
|
import { validateAtRuleKeyframes } from './at-rules/keyframes.js';
|
|
20
|
+
import { validateAtRuleWhen } from './at-rules/when.js';
|
|
21
|
+
import { validateAtRuleElse } from './at-rules/else.js';
|
|
22
|
+
import { validateAtRuleContainer } from './at-rules/container.js';
|
|
23
|
+
import { validateAtRuleCustomMedia } from './at-rules/custom-media.js';
|
|
20
24
|
|
|
21
25
|
function validateAtRule(atRule, options, root) {
|
|
22
26
|
if (atRule.nam == 'charset') {
|
|
@@ -60,9 +64,21 @@ function validateAtRule(atRule, options, root) {
|
|
|
60
64
|
if (atRule.nam == 'namespace') {
|
|
61
65
|
return validateAtRuleNamespace(atRule);
|
|
62
66
|
}
|
|
67
|
+
if (atRule.nam == 'when') {
|
|
68
|
+
return validateAtRuleWhen(atRule);
|
|
69
|
+
}
|
|
70
|
+
if (atRule.nam == 'else') {
|
|
71
|
+
return validateAtRuleElse(atRule);
|
|
72
|
+
}
|
|
73
|
+
if (atRule.nam == 'container') {
|
|
74
|
+
return validateAtRuleContainer(atRule);
|
|
75
|
+
}
|
|
63
76
|
if (atRule.nam == 'document') {
|
|
64
77
|
return validateAtRuleDocument(atRule);
|
|
65
78
|
}
|
|
79
|
+
if (atRule.nam == 'custom-media') {
|
|
80
|
+
return validateAtRuleCustomMedia(atRule);
|
|
81
|
+
}
|
|
66
82
|
if (['position-try', 'property', 'font-palette-values'].includes(atRule.nam)) {
|
|
67
83
|
if (!('tokens' in atRule)) {
|
|
68
84
|
return {
|
|
@@ -132,15 +148,14 @@ function validateAtRule(atRule, options, root) {
|
|
|
132
148
|
}
|
|
133
149
|
}
|
|
134
150
|
if (!(name in config.atRules)) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// }
|
|
151
|
+
if (options.lenient) {
|
|
152
|
+
return {
|
|
153
|
+
valid: ValidationLevel.Lenient,
|
|
154
|
+
node: atRule,
|
|
155
|
+
syntax: null,
|
|
156
|
+
error: ''
|
|
157
|
+
};
|
|
158
|
+
}
|
|
144
159
|
return {
|
|
145
160
|
valid: ValidationLevel.Drop,
|
|
146
161
|
node: atRule,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import config from './config.json.js';
|
|
2
2
|
import './parser/types.js';
|
|
3
|
-
import { parseSyntax
|
|
3
|
+
import { parseSyntax } from './parser/parse.js';
|
|
4
4
|
|
|
5
5
|
const parsedSyntaxes = new Map();
|
|
6
6
|
Object.freeze(config);
|
|
@@ -9,25 +9,30 @@ function getSyntaxConfig() {
|
|
|
9
9
|
return config;
|
|
10
10
|
}
|
|
11
11
|
function getParsedSyntax(group, key) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (!(key in
|
|
18
|
-
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
let obj = config[group];
|
|
14
|
+
const keys = Array.isArray(key) ? key : [key];
|
|
15
|
+
for (let i = 0; i < keys.length; i++) {
|
|
16
|
+
key = keys[i];
|
|
17
|
+
if (!(key in obj)) {
|
|
18
|
+
if ((i == 0 && key.charAt(0) == '@') || key.charAt(0) == '-') {
|
|
19
|
+
const matches = key.match(/^(@?)(-[a-zA-Z]+)-(.*?)$/);
|
|
20
|
+
if (matches != null) {
|
|
21
|
+
key = matches[1] + matches[3];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!(key in obj)) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
19
27
|
}
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
obj = obj[key];
|
|
20
30
|
}
|
|
21
|
-
const index = group + '.' +
|
|
31
|
+
const index = group + '.' + keys.join('.');
|
|
22
32
|
// @ts-ignore
|
|
23
33
|
if (!parsedSyntaxes.has(index)) {
|
|
24
34
|
// @ts-ignore
|
|
25
|
-
const syntax = parseSyntax(
|
|
26
|
-
for (const node of syntax.chi) {
|
|
27
|
-
for (const { token, parent } of walkValidationToken(node)) {
|
|
28
|
-
token.text = renderSyntax(token);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
35
|
+
const syntax = parseSyntax(obj.syntax);
|
|
31
36
|
// @ts-ignore
|
|
32
37
|
parsedSyntaxes.set(index, syntax.chi);
|
|
33
38
|
}
|