@tbela99/css-parser 0.7.0 → 0.8.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.
Files changed (82) hide show
  1. package/README.md +142 -81
  2. package/dist/index-umd-web.js +7027 -51519
  3. package/dist/index.cjs +7022 -51515
  4. package/dist/index.d.ts +189 -60
  5. package/dist/lib/ast/expand.js +87 -2
  6. package/dist/lib/ast/features/calc.js +76 -12
  7. package/dist/lib/ast/features/inlinecssvariables.js +6 -1
  8. package/dist/lib/ast/features/prefix.js +17 -9
  9. package/dist/lib/ast/features/shorthand.js +1 -0
  10. package/dist/lib/ast/math/expression.js +299 -11
  11. package/dist/lib/ast/math/math.js +7 -1
  12. package/dist/lib/ast/minify.js +1 -1
  13. package/dist/lib/ast/types.js +58 -49
  14. package/dist/lib/ast/walk.js +80 -18
  15. package/dist/lib/parser/declaration/list.js +1 -0
  16. package/dist/lib/parser/declaration/map.js +1 -0
  17. package/dist/lib/parser/declaration/set.js +1 -0
  18. package/dist/lib/parser/parse.js +285 -72
  19. package/dist/lib/parser/tokenize.js +23 -3
  20. package/dist/lib/parser/utils/declaration.js +2 -2
  21. package/dist/lib/parser/utils/type.js +6 -6
  22. package/dist/lib/renderer/color/a98rgb.js +1 -0
  23. package/dist/lib/renderer/color/color.js +1 -0
  24. package/dist/lib/renderer/color/colormix.js +1 -0
  25. package/dist/lib/renderer/color/hex.js +1 -0
  26. package/dist/lib/renderer/color/hsl.js +1 -0
  27. package/dist/lib/renderer/color/hwb.js +1 -0
  28. package/dist/lib/renderer/color/lab.js +1 -0
  29. package/dist/lib/renderer/color/lch.js +1 -0
  30. package/dist/lib/renderer/color/oklab.js +1 -0
  31. package/dist/lib/renderer/color/oklch.js +1 -0
  32. package/dist/lib/renderer/color/p3.js +1 -0
  33. package/dist/lib/renderer/color/prophotoRgb.js +56 -0
  34. package/dist/lib/renderer/color/rec2020.js +1 -0
  35. package/dist/lib/renderer/color/relativecolor.js +52 -28
  36. package/dist/lib/renderer/color/rgb.js +1 -0
  37. package/dist/lib/renderer/color/srgb.js +1 -0
  38. package/dist/lib/renderer/color/utils/components.js +1 -0
  39. package/dist/lib/renderer/color/utils/constants.js +1 -0
  40. package/dist/lib/renderer/color/xyz.js +1 -0
  41. package/dist/lib/renderer/color/xyzd50.js +1 -0
  42. package/dist/lib/renderer/render.js +28 -6
  43. package/dist/lib/syntax/syntax.js +27 -4
  44. package/dist/lib/validation/at-rules/counter-style.js +78 -0
  45. package/dist/lib/validation/at-rules/document.js +114 -0
  46. package/dist/lib/validation/at-rules/font-feature-values.js +49 -0
  47. package/dist/lib/validation/at-rules/import.js +196 -0
  48. package/dist/lib/validation/at-rules/keyframes.js +70 -0
  49. package/dist/lib/validation/at-rules/layer.js +27 -0
  50. package/dist/lib/validation/at-rules/media.js +166 -0
  51. package/dist/lib/validation/at-rules/namespace.js +85 -0
  52. package/dist/lib/validation/at-rules/page-margin-box.js +56 -0
  53. package/dist/lib/validation/at-rules/page.js +88 -0
  54. package/dist/lib/validation/at-rules/supports.js +262 -0
  55. package/dist/lib/validation/atrule.js +172 -0
  56. package/dist/lib/validation/config.js +30 -2
  57. package/dist/lib/validation/config.json.js +1560 -50902
  58. package/dist/lib/validation/declaration.js +72 -0
  59. package/dist/lib/validation/parser/parse.js +1059 -7
  60. package/dist/lib/validation/parser/types.js +27 -12
  61. package/dist/lib/validation/selector.js +23 -444
  62. package/dist/lib/validation/syntax.js +1429 -0
  63. package/dist/lib/validation/syntaxes/complex-selector-list.js +41 -0
  64. package/dist/lib/validation/syntaxes/complex-selector.js +283 -0
  65. package/dist/lib/validation/syntaxes/family-name.js +91 -0
  66. package/dist/lib/validation/syntaxes/keyframe-block-list.js +27 -0
  67. package/dist/lib/validation/syntaxes/keyframe-selector.js +137 -0
  68. package/dist/lib/validation/syntaxes/layer-name.js +67 -0
  69. package/dist/lib/validation/syntaxes/relative-selector-list.js +27 -0
  70. package/dist/lib/validation/syntaxes/relative-selector.js +36 -0
  71. package/dist/lib/validation/syntaxes/selector-list.js +5 -0
  72. package/dist/lib/validation/syntaxes/selector.js +5 -0
  73. package/dist/lib/validation/syntaxes/url.js +75 -0
  74. package/dist/lib/validation/utils/list.js +24 -0
  75. package/dist/lib/validation/utils/whitespace.js +22 -0
  76. package/dist/node/index.js +13 -0
  77. package/dist/web/index.js +13 -0
  78. package/dist/web/load.js +1 -0
  79. package/package.json +17 -15
  80. package/dist/lib/ast/utils/minifyfeature.js +0 -9
  81. package/dist/lib/iterable/weakset.js +0 -58
  82. package/dist/lib/parser/utils/syntax.js +0 -450
@@ -0,0 +1,85 @@
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 { validateURL } from '../syntaxes/url.js';
10
+
11
+ function validateAtRuleNamespace(atRule, options, root) {
12
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
13
+ // @ts-ignore
14
+ return {
15
+ valid: ValidationLevel.Drop,
16
+ matches: [],
17
+ node: atRule,
18
+ syntax: '@namespace',
19
+ error: 'expected at-rule prelude',
20
+ tokens: []
21
+ };
22
+ }
23
+ if ('chi' in atRule) {
24
+ // @ts-ignore
25
+ return {
26
+ valid: ValidationLevel.Drop,
27
+ matches: [],
28
+ node: atRule,
29
+ syntax: '@namespace',
30
+ error: 'unexpected at-rule body',
31
+ tokens: []
32
+ };
33
+ }
34
+ const tokens = atRule.tokens.slice();
35
+ consumeWhitespace(tokens);
36
+ if (tokens[0].typ == EnumToken.IdenTokenType) {
37
+ tokens.shift();
38
+ consumeWhitespace(tokens);
39
+ }
40
+ if (tokens.length == 0) {
41
+ // @ts-ignore
42
+ return {
43
+ valid: ValidationLevel.Drop,
44
+ matches: [],
45
+ node: atRule,
46
+ syntax: '@namespace',
47
+ error: 'expected string or url()',
48
+ tokens
49
+ };
50
+ }
51
+ if (tokens[0].typ != EnumToken.StringTokenType) {
52
+ const result = validateURL(tokens[0]);
53
+ if (result.valid != ValidationLevel.Valid) {
54
+ return result;
55
+ }
56
+ tokens.shift();
57
+ consumeWhitespace(tokens);
58
+ }
59
+ else {
60
+ tokens.shift();
61
+ consumeWhitespace(tokens);
62
+ }
63
+ if (tokens.length > 0) {
64
+ // @ts-ignore
65
+ return {
66
+ valid: ValidationLevel.Drop,
67
+ matches: [],
68
+ node: tokens[0],
69
+ syntax: '@namespace',
70
+ error: 'unexpected token',
71
+ tokens
72
+ };
73
+ }
74
+ // @ts-ignore
75
+ return {
76
+ valid: ValidationLevel.Valid,
77
+ matches: [],
78
+ node: atRule,
79
+ syntax: '@namespace',
80
+ error: '',
81
+ tokens
82
+ };
83
+ }
84
+
85
+ export { validateAtRuleNamespace };
@@ -0,0 +1,56 @@
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
+
9
+ function validateAtRulePageMarginBox(atRule, options, root) {
10
+ if (Array.isArray(atRule.tokens) && atRule.tokens.length > 0) {
11
+ // @ts-ignore
12
+ return {
13
+ valid: ValidationLevel.Valid,
14
+ matches: [],
15
+ node: null,
16
+ syntax: '@' + atRule.nam,
17
+ error: '',
18
+ tokens: []
19
+ };
20
+ }
21
+ if (!('chi' in atRule)) {
22
+ // @ts-ignore
23
+ return {
24
+ valid: ValidationLevel.Drop,
25
+ matches: [],
26
+ node: atRule,
27
+ syntax: '@' + atRule.nam,
28
+ error: 'expected margin-box body',
29
+ tokens: []
30
+ };
31
+ }
32
+ for (const token of atRule.chi) {
33
+ if (![EnumToken.DeclarationNodeType, EnumToken.CommentNodeType, EnumToken.WhitespaceTokenType].includes(token.typ)) {
34
+ // @ts-ignore
35
+ return {
36
+ valid: ValidationLevel.Drop,
37
+ matches: [],
38
+ node: token,
39
+ syntax: 'declaration-list',
40
+ error: 'expected margin-box body',
41
+ tokens: []
42
+ };
43
+ }
44
+ }
45
+ // @ts-ignore
46
+ return {
47
+ valid: ValidationLevel.Valid,
48
+ matches: [],
49
+ node: null,
50
+ syntax: '@' + atRule.nam,
51
+ error: '',
52
+ tokens: []
53
+ };
54
+ }
55
+
56
+ export { validateAtRulePageMarginBox };
@@ -0,0 +1,88 @@
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 { splitTokenList } from '../utils/list.js';
9
+
10
+ function validateAtRulePage(atRule, options, root) {
11
+ // media-query-list
12
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
13
+ // @ts-ignore
14
+ return {
15
+ valid: ValidationLevel.Valid,
16
+ matches: [],
17
+ node: null,
18
+ syntax: '@page',
19
+ error: '',
20
+ tokens: []
21
+ };
22
+ }
23
+ // page-selector-list
24
+ for (const tokens of splitTokenList(atRule.tokens)) {
25
+ if (tokens.length == 0) {
26
+ // @ts-ignore
27
+ return {
28
+ valid: ValidationLevel.Drop,
29
+ matches: [],
30
+ node: tokens[0] ?? atRule,
31
+ syntax: '@page',
32
+ error: 'unexpected token',
33
+ tokens: []
34
+ };
35
+ }
36
+ // <pseudo-page>+ | <ident> <pseudo-page>*
37
+ // ident pseudo-page* | pseudo-page+
38
+ if (tokens[0].typ == EnumToken.IdenTokenType) {
39
+ tokens.shift();
40
+ if (tokens.length == 0) {
41
+ continue;
42
+ }
43
+ // @ts-ignore
44
+ if (tokens[0].typ != EnumToken.WhitespaceTokenType) {
45
+ // @ts-ignore
46
+ return {
47
+ valid: ValidationLevel.Drop,
48
+ matches: [],
49
+ node: tokens[0] ?? atRule,
50
+ syntax: '@page',
51
+ error: 'unexpected token',
52
+ tokens: []
53
+ };
54
+ }
55
+ }
56
+ while (tokens.length > 0) {
57
+ if (tokens[0].typ == EnumToken.PseudoPageTokenType) {
58
+ tokens.shift();
59
+ if (tokens.length == 0) {
60
+ continue;
61
+ }
62
+ // @ts-ignore
63
+ if (tokens[0].typ != EnumToken.WhitespaceTokenType) {
64
+ // @ts-ignore
65
+ return {
66
+ valid: ValidationLevel.Drop,
67
+ matches: [],
68
+ node: tokens[0] ?? atRule,
69
+ syntax: '@page',
70
+ error: 'unexpected token',
71
+ tokens: []
72
+ };
73
+ }
74
+ }
75
+ }
76
+ }
77
+ // @ts-ignore
78
+ return {
79
+ valid: ValidationLevel.Valid,
80
+ matches: [],
81
+ node: atRule,
82
+ syntax: '@page',
83
+ error: '',
84
+ tokens: []
85
+ };
86
+ }
87
+
88
+ export { validateAtRulePage };
@@ -0,0 +1,262 @@
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 { colorFontTech, fontFeaturesTech, fontFormat } from '../../syntax/syntax.js';
6
+ import '../../parser/utils/config.js';
7
+ import '../../renderer/color/utils/constants.js';
8
+ import '../../renderer/sourcemap/lib/encode.js';
9
+ import { consumeWhitespace } from '../utils/whitespace.js';
10
+ import { splitTokenList } from '../utils/list.js';
11
+ import { validateSyntax } from '../syntax.js';
12
+ import { getParsedSyntax } from '../config.js';
13
+
14
+ function validateAtRuleSupports(atRule, options, root) {
15
+ // media-query-list
16
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
17
+ // @ts-ignore
18
+ return {
19
+ valid: ValidationLevel.Drop,
20
+ matches: [],
21
+ node: atRule,
22
+ syntax: '@supports',
23
+ error: 'expected supports query list',
24
+ tokens: []
25
+ };
26
+ }
27
+ const result = validateAtRuleSupportsConditions(atRule, atRule.tokens);
28
+ if (result) {
29
+ if (result.node == null) {
30
+ result.node = atRule;
31
+ }
32
+ return result;
33
+ }
34
+ if (!('chi' in atRule)) {
35
+ // @ts-ignore
36
+ return {
37
+ valid: ValidationLevel.Drop,
38
+ matches: [],
39
+ node: atRule,
40
+ syntax: '@supports',
41
+ error: 'expected at-rule body',
42
+ tokens: []
43
+ };
44
+ }
45
+ // @ts-ignore
46
+ return {
47
+ valid: ValidationLevel.Valid,
48
+ matches: [],
49
+ node: atRule,
50
+ syntax: '@supports',
51
+ error: '',
52
+ tokens: []
53
+ };
54
+ }
55
+ function validateAtRuleSupportsConditions(atRule, tokenList) {
56
+ for (const tokens of splitTokenList(tokenList)) {
57
+ if (tokens.length == 0) {
58
+ // @ts-ignore
59
+ return {
60
+ valid: ValidationLevel.Drop,
61
+ matches: [],
62
+ node: tokens[0] ?? atRule,
63
+ syntax: '@supports',
64
+ error: 'unexpected token',
65
+ tokens: []
66
+ };
67
+ }
68
+ let previousToken = null;
69
+ let result = null;
70
+ while (tokens.length > 0) {
71
+ result = validateSupportCondition(atRule, tokens[0]);
72
+ // supports-condition
73
+ if (result == null || result.valid == ValidationLevel.Valid) {
74
+ previousToken = tokens[0];
75
+ tokens.shift();
76
+ }
77
+ else {
78
+ result = validateSupportFeature(tokens[0]);
79
+ if (result == null || result.valid == ValidationLevel.Valid) {
80
+ previousToken = tokens[0];
81
+ tokens.shift();
82
+ }
83
+ else {
84
+ return result;
85
+ }
86
+ }
87
+ if (tokens.length == 0) {
88
+ break;
89
+ }
90
+ if (!consumeWhitespace(tokens)) {
91
+ if (previousToken?.typ != EnumToken.ParensTokenType) {
92
+ // @ts-ignore
93
+ return {
94
+ valid: ValidationLevel.Drop,
95
+ matches: [],
96
+ node: tokens[0] ?? previousToken ?? atRule,
97
+ syntax: '@supports',
98
+ error: 'expected whitespace',
99
+ tokens: []
100
+ };
101
+ }
102
+ }
103
+ if (![EnumToken.MediaFeatureOrTokenType, EnumToken.MediaFeatureAndTokenType].includes(tokens[0].typ)) {
104
+ // @ts-ignore
105
+ return {
106
+ valid: ValidationLevel.Drop,
107
+ matches: [],
108
+ node: tokens[0] ?? atRule,
109
+ syntax: '@supports',
110
+ error: 'expected and/or',
111
+ tokens: []
112
+ };
113
+ }
114
+ if (tokens.length == 1) {
115
+ // @ts-ignore
116
+ return {
117
+ valid: ValidationLevel.Drop,
118
+ matches: [],
119
+ node: tokens[0] ?? atRule,
120
+ syntax: '@supports',
121
+ error: 'expected supports-condition',
122
+ tokens: []
123
+ };
124
+ }
125
+ tokens.shift();
126
+ if (!consumeWhitespace(tokens)) {
127
+ // @ts-ignore
128
+ return {
129
+ valid: ValidationLevel.Drop,
130
+ matches: [],
131
+ node: tokens[0] ?? atRule,
132
+ syntax: '@supports',
133
+ error: 'expected whitespace',
134
+ tokens: []
135
+ };
136
+ }
137
+ }
138
+ }
139
+ return null;
140
+ }
141
+ function validateSupportCondition(atRule, token) {
142
+ if (token.typ == EnumToken.MediaFeatureNotTokenType) {
143
+ return validateSupportCondition(atRule, token.val);
144
+ }
145
+ if (token.typ != EnumToken.ParensTokenType) {
146
+ // @ts-ignore
147
+ return {
148
+ valid: ValidationLevel.Drop,
149
+ matches: [],
150
+ node: token,
151
+ syntax: '@supports',
152
+ error: 'expected supports condition-in-parens',
153
+ tokens: []
154
+ };
155
+ }
156
+ const chi = token.chi.filter((t) => t.typ != EnumToken.CommentTokenType && t.typ != EnumToken.WhitespaceTokenType);
157
+ if (chi.length != 1) {
158
+ return validateAtRuleSupportsConditions(atRule, token.chi);
159
+ }
160
+ if (chi[0].typ == EnumToken.IdenTokenType) {
161
+ // @ts-ignore
162
+ return {
163
+ valid: ValidationLevel.Valid,
164
+ matches: [],
165
+ node: null,
166
+ syntax: '@supports',
167
+ error: '',
168
+ tokens: []
169
+ };
170
+ }
171
+ if (chi[0].typ == EnumToken.MediaFeatureNotTokenType) {
172
+ return validateSupportCondition(atRule, chi[0].val);
173
+ }
174
+ if (chi[0].typ == EnumToken.MediaQueryConditionTokenType) {
175
+ // @ts-ignore
176
+ return chi[0].l.typ == EnumToken.IdenTokenType && chi[0].op.typ == EnumToken.ColonTokenType ?
177
+ {
178
+ valid: ValidationLevel.Valid,
179
+ matches: [],
180
+ node: null,
181
+ syntax: 'supports-condition',
182
+ error: '',
183
+ tokens: []
184
+ } : {
185
+ valid: ValidationLevel.Drop,
186
+ matches: [],
187
+ node: token,
188
+ syntax: 'supports-condition',
189
+ error: 'expected supports condition-in-parens',
190
+ tokens: []
191
+ };
192
+ }
193
+ // @ts-ignore
194
+ return {
195
+ valid: ValidationLevel.Drop,
196
+ matches: [],
197
+ node: token,
198
+ syntax: 'supports-condition',
199
+ error: 'expected supports condition-in-parens',
200
+ tokens: []
201
+ };
202
+ }
203
+ function validateSupportFeature(token) {
204
+ if (token.typ == EnumToken.FunctionTokenType) {
205
+ if (token.val.localeCompare('selector', undefined, { sensitivity: 'base' }) == 0) {
206
+ return validateSyntax(getParsedSyntax("syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */, 'complex-selector'), token.chi);
207
+ }
208
+ if (token.val.localeCompare('font-tech', undefined, { sensitivity: 'base' }) == 0) {
209
+ const chi = token.chi.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ));
210
+ // @ts-ignore
211
+ return chi.length == 1 && chi[0].typ == EnumToken.IdenTokenType && colorFontTech.concat(fontFeaturesTech).some((t) => t.localeCompare(chi[0].val, undefined, { sensitivity: 'base' }) == 0) ?
212
+ {
213
+ valid: ValidationLevel.Valid,
214
+ matches: [],
215
+ node: token,
216
+ syntax: 'font-tech',
217
+ error: '',
218
+ tokens: []
219
+ } :
220
+ {
221
+ valid: ValidationLevel.Drop,
222
+ matches: [],
223
+ node: token,
224
+ syntax: 'font-tech',
225
+ error: 'expected font-tech',
226
+ tokens: []
227
+ };
228
+ }
229
+ if (token.val.localeCompare('font-format', undefined, { sensitivity: 'base' }) == 0) {
230
+ const chi = token.chi.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ));
231
+ // @ts-ignore
232
+ return chi.length == 1 && chi[0].typ == EnumToken.IdenTokenType && fontFormat.some((t) => t.localeCompare(chi[0].val, undefined, { sensitivity: 'base' }) == 0) ?
233
+ {
234
+ valid: ValidationLevel.Valid,
235
+ matches: [],
236
+ node: token,
237
+ syntax: 'font-format',
238
+ error: '',
239
+ tokens: []
240
+ } :
241
+ {
242
+ valid: ValidationLevel.Drop,
243
+ matches: [],
244
+ node: token,
245
+ syntax: 'font-format',
246
+ error: 'expected font-format',
247
+ tokens: []
248
+ };
249
+ }
250
+ }
251
+ // @ts-ignore
252
+ return {
253
+ valid: ValidationLevel.Drop,
254
+ matches: [],
255
+ node: token,
256
+ syntax: '@supports',
257
+ error: 'expected feature',
258
+ tokens: []
259
+ };
260
+ }
261
+
262
+ export { validateAtRuleSupports, validateAtRuleSupportsConditions, validateSupportCondition };
@@ -0,0 +1,172 @@
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 { getParsedSyntax, getSyntaxConfig } from './config.js';
9
+ import { validateAtRuleMedia } from './at-rules/media.js';
10
+ import { validateAtRuleCounterStyle } from './at-rules/counter-style.js';
11
+ import { validateAtRulePage } from './at-rules/page.js';
12
+ import { validateAtRulePageMarginBox } from './at-rules/page-margin-box.js';
13
+ import { validateAtRuleSupports } from './at-rules/supports.js';
14
+ import { validateAtRuleImport } from './at-rules/import.js';
15
+ import { validateAtRuleLayer } from './at-rules/layer.js';
16
+ import { validateAtRuleFontFeatureValues } from './at-rules/font-feature-values.js';
17
+ import { validateAtRuleNamespace } from './at-rules/namespace.js';
18
+ import { validateAtRuleDocument } from './at-rules/document.js';
19
+ import { validateAtRuleKeyframes } from './at-rules/keyframes.js';
20
+
21
+ function validateAtRule(atRule, options, root) {
22
+ if (atRule.nam == 'charset') {
23
+ const valid = atRule.val.match(/^"[a-zA-Z][a-zA-Z0-9_-]+"$/i) != null;
24
+ return {
25
+ valid: valid ? ValidationLevel.Valid : ValidationLevel.Drop,
26
+ node: atRule,
27
+ syntax: null,
28
+ error: ''
29
+ };
30
+ }
31
+ if (atRule.nam == 'keyframes') {
32
+ return validateAtRuleKeyframes(atRule);
33
+ }
34
+ if (['font-face', 'view-transition', 'starting-style'].includes(atRule.nam)) {
35
+ return {
36
+ valid: ValidationLevel.Valid,
37
+ node: atRule,
38
+ syntax: '@' + atRule.nam,
39
+ error: ''
40
+ };
41
+ }
42
+ if (atRule.nam == 'media') {
43
+ return validateAtRuleMedia(atRule);
44
+ }
45
+ if (atRule.nam == 'import') {
46
+ return validateAtRuleImport(atRule);
47
+ }
48
+ if (atRule.nam == 'supports') {
49
+ return validateAtRuleSupports(atRule);
50
+ }
51
+ if (atRule.nam == 'counter-style') {
52
+ return validateAtRuleCounterStyle(atRule);
53
+ }
54
+ if (atRule.nam == 'layer') {
55
+ return validateAtRuleLayer(atRule);
56
+ }
57
+ if (atRule.nam == 'font-feature-values') {
58
+ return validateAtRuleFontFeatureValues(atRule);
59
+ }
60
+ if (atRule.nam == 'namespace') {
61
+ return validateAtRuleNamespace(atRule);
62
+ }
63
+ if (atRule.nam == 'document') {
64
+ return validateAtRuleDocument(atRule);
65
+ }
66
+ if (['position-try', 'property', 'font-palette-values'].includes(atRule.nam)) {
67
+ if (!('tokens' in atRule)) {
68
+ return {
69
+ valid: ValidationLevel.Drop,
70
+ node: atRule,
71
+ syntax: '@' + atRule.nam,
72
+ error: 'expected prelude'
73
+ };
74
+ }
75
+ if (!('chi' in atRule)) {
76
+ return {
77
+ valid: ValidationLevel.Drop,
78
+ node: atRule,
79
+ syntax: '@' + atRule.nam,
80
+ error: 'expected body'
81
+ };
82
+ }
83
+ const chi = atRule.tokens.filter((t) => t.typ != EnumToken.WhitespaceTokenType && t.typ != EnumToken.CommentTokenType);
84
+ if (chi.length != 1) {
85
+ return {
86
+ valid: ValidationLevel.Drop,
87
+ node: atRule,
88
+ syntax: '@' + atRule.nam,
89
+ error: 'expected ' + (atRule.nam == 'property' ? 'custom-property-name' : 'dashed-ident')
90
+ };
91
+ }
92
+ if (chi[0].typ != EnumToken.DashedIdenTokenType) {
93
+ // @ts-ignore
94
+ return {
95
+ valid: ValidationLevel.Drop,
96
+ node: atRule,
97
+ syntax: '@' + atRule.nam,
98
+ error: 'expected ' + (atRule.nam == 'property' ? 'custom-property-name' : 'dashed-ident')
99
+ };
100
+ }
101
+ // @ts-ignore
102
+ return {
103
+ valid: ValidationLevel.Valid,
104
+ node: atRule,
105
+ syntax: '@' + atRule.nam,
106
+ error: ''
107
+ };
108
+ }
109
+ // scope
110
+ if (atRule.nam == 'page') {
111
+ return validateAtRulePage(atRule);
112
+ }
113
+ if (['top-left-corner', 'top-left', 'top-center', 'top-right', 'top-right-corner', 'bottom-left-corner', 'bottom-left', 'bottom-center', 'bottom-right', 'bottom-right-corner', 'left-top', 'left-middle', 'left-bottom', 'right-top', 'right-middle', 'right-bottom'].includes(atRule.nam)) {
114
+ if (!(root == null || (root.typ == EnumToken.AtRuleNodeType && root.nam == 'page'))) {
115
+ // @ts-ignore
116
+ return {
117
+ valid: ValidationLevel.Drop,
118
+ node: atRule,
119
+ syntax: '@page',
120
+ error: 'not allowed here'
121
+ };
122
+ }
123
+ return validateAtRulePageMarginBox(atRule);
124
+ }
125
+ // handle keyframe as special case
126
+ // check if the node exists
127
+ const config = getSyntaxConfig();
128
+ let name = '@' + atRule.nam;
129
+ if (!(name in config.atRules)) {
130
+ if (name.charAt(1) == '-') {
131
+ name = name.replace(/@-[a-zA-Z]+-([a-zA-Z][a-zA-Z0-9_-]*)/, '@$1');
132
+ }
133
+ }
134
+ if (!(name in config.atRules)) {
135
+ // if (root?.typ == EnumToken.AtRuleNodeType) {
136
+ //
137
+ // const syntaxes: ValidationToken = (getParsedSyntax(ValidationSyntaxGroupEnum.AtRules, '@' + (root as AstAtRule).nam) as ValidationToken[])?.[0];
138
+ //
139
+ // if ('chi' in syntaxes) {
140
+ //
141
+ // return validateSyntax(syntaxes.chi as ValidationToken[], [atRule], root, options);
142
+ // }
143
+ // }
144
+ return {
145
+ valid: ValidationLevel.Drop,
146
+ node: atRule,
147
+ syntax: null,
148
+ error: 'unknown at-rule'
149
+ };
150
+ }
151
+ const syntax = getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, name)?.[0];
152
+ if ('chi' in syntax && !('chi' in atRule)) {
153
+ return {
154
+ valid: ValidationLevel.Drop,
155
+ node: atRule,
156
+ syntax,
157
+ error: 'missing at-rule body'
158
+ };
159
+ }
160
+ // if ('prelude' in syntax) {
161
+ //
162
+ // return validateSyntax(syntax.prelude as ValidationToken[], atRule.tokens as Token[], root, options);
163
+ // }
164
+ return {
165
+ valid: ValidationLevel.Valid,
166
+ node: null,
167
+ syntax,
168
+ error: ''
169
+ };
170
+ }
171
+
172
+ export { validateAtRule };