@tbela99/css-parser 0.7.1 → 0.9.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 (90) hide show
  1. package/.editorconfig +484 -0
  2. package/README.md +140 -84
  3. package/dist/index-umd-web.js +8461 -51655
  4. package/dist/index.cjs +8437 -51636
  5. package/dist/index.d.ts +220 -68
  6. package/dist/lib/ast/expand.js +46 -9
  7. package/dist/lib/ast/features/calc.js +76 -12
  8. package/dist/lib/ast/features/inlinecssvariables.js +6 -1
  9. package/dist/lib/ast/features/prefix.js +17 -9
  10. package/dist/lib/ast/features/shorthand.js +1 -0
  11. package/dist/lib/ast/math/expression.js +299 -11
  12. package/dist/lib/ast/math/math.js +7 -1
  13. package/dist/lib/ast/minify.js +30 -16
  14. package/dist/lib/ast/types.js +59 -49
  15. package/dist/lib/ast/walk.js +92 -18
  16. package/dist/lib/parser/declaration/list.js +1 -0
  17. package/dist/lib/parser/declaration/map.js +60 -52
  18. package/dist/lib/parser/declaration/set.js +1 -12
  19. package/dist/lib/parser/parse.js +371 -119
  20. package/dist/lib/parser/tokenize.js +31 -6
  21. package/dist/lib/parser/utils/declaration.js +2 -2
  22. package/dist/lib/parser/utils/type.js +6 -6
  23. package/dist/lib/renderer/color/a98rgb.js +1 -0
  24. package/dist/lib/renderer/color/color.js +1 -0
  25. package/dist/lib/renderer/color/colormix.js +1 -0
  26. package/dist/lib/renderer/color/hex.js +2 -1
  27. package/dist/lib/renderer/color/hsl.js +2 -1
  28. package/dist/lib/renderer/color/hwb.js +3 -2
  29. package/dist/lib/renderer/color/lab.js +2 -1
  30. package/dist/lib/renderer/color/lch.js +2 -1
  31. package/dist/lib/renderer/color/oklab.js +3 -2
  32. package/dist/lib/renderer/color/oklch.js +2 -1
  33. package/dist/lib/renderer/color/p3.js +2 -1
  34. package/dist/lib/renderer/color/prophotoRgb.js +56 -0
  35. package/dist/lib/renderer/color/prophotorgb.js +1 -1
  36. package/dist/lib/renderer/color/rec2020.js +1 -0
  37. package/dist/lib/renderer/color/relativecolor.js +52 -28
  38. package/dist/lib/renderer/color/rgb.js +2 -1
  39. package/dist/lib/renderer/color/srgb.js +3 -2
  40. package/dist/lib/renderer/color/utils/components.js +1 -0
  41. package/dist/lib/renderer/color/utils/constants.js +2 -1
  42. package/dist/lib/renderer/color/xyz.js +2 -1
  43. package/dist/lib/renderer/color/xyzd50.js +1 -0
  44. package/dist/lib/renderer/render.js +62 -12
  45. package/dist/lib/syntax/syntax.js +362 -4
  46. package/dist/lib/validation/at-rules/container.js +353 -0
  47. package/dist/lib/validation/at-rules/counter-style.js +78 -0
  48. package/dist/lib/validation/at-rules/custom-media.js +52 -0
  49. package/dist/lib/validation/at-rules/document.js +114 -0
  50. package/dist/lib/validation/at-rules/else.js +5 -0
  51. package/dist/lib/validation/at-rules/font-feature-values.js +52 -0
  52. package/dist/lib/validation/at-rules/import.js +199 -0
  53. package/dist/lib/validation/at-rules/keyframes.js +70 -0
  54. package/dist/lib/validation/at-rules/layer.js +30 -0
  55. package/dist/lib/validation/at-rules/media.js +254 -0
  56. package/dist/lib/validation/at-rules/namespace.js +85 -0
  57. package/dist/lib/validation/at-rules/page-margin-box.js +56 -0
  58. package/dist/lib/validation/at-rules/page.js +88 -0
  59. package/dist/lib/validation/at-rules/supports.js +262 -0
  60. package/dist/lib/validation/at-rules/when.js +178 -0
  61. package/dist/lib/validation/atrule.js +187 -0
  62. package/dist/lib/validation/config.js +35 -2
  63. package/dist/lib/validation/config.json.js +1683 -50905
  64. package/dist/lib/validation/declaration.js +102 -0
  65. package/dist/lib/validation/parser/parse.js +1137 -7
  66. package/dist/lib/validation/parser/types.js +28 -12
  67. package/dist/lib/validation/selector.js +26 -444
  68. package/dist/lib/validation/syntax.js +1475 -0
  69. package/dist/lib/validation/syntaxes/complex-selector-list.js +45 -0
  70. package/dist/lib/validation/syntaxes/complex-selector.js +53 -0
  71. package/dist/lib/validation/syntaxes/compound-selector.js +226 -0
  72. package/dist/lib/validation/syntaxes/family-name.js +91 -0
  73. package/dist/lib/validation/syntaxes/image.js +29 -0
  74. package/dist/lib/validation/syntaxes/keyframe-block-list.js +27 -0
  75. package/dist/lib/validation/syntaxes/keyframe-selector.js +137 -0
  76. package/dist/lib/validation/syntaxes/layer-name.js +67 -0
  77. package/dist/lib/validation/syntaxes/relative-selector-list.js +57 -0
  78. package/dist/lib/validation/syntaxes/relative-selector.js +36 -0
  79. package/dist/lib/validation/syntaxes/selector-list.js +5 -0
  80. package/dist/lib/validation/syntaxes/selector.js +5 -0
  81. package/dist/lib/validation/syntaxes/url.js +75 -0
  82. package/dist/lib/validation/utils/list.js +24 -0
  83. package/dist/lib/validation/utils/whitespace.js +22 -0
  84. package/dist/node/index.js +5 -5
  85. package/dist/web/index.js +5 -1
  86. package/dist/web/load.js +1 -0
  87. package/package.json +16 -14
  88. package/dist/lib/ast/utils/minifyfeature.js +0 -9
  89. package/dist/lib/iterable/weakset.js +0 -58
  90. package/dist/lib/parser/utils/syntax.js +0 -450
@@ -0,0 +1,199 @@
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 { validateAtRuleSupports } from './supports.js';
9
+ import { validateAtRuleMediaQueryList } from './media.js';
10
+ import { consumeWhitespace } from '../utils/whitespace.js';
11
+ import { validateLayerName } from '../syntaxes/layer-name.js';
12
+ import '../syntaxes/complex-selector.js';
13
+ import '../parser/types.js';
14
+ import '../parser/parse.js';
15
+ import '../config.js';
16
+
17
+ function validateAtRuleImport(atRule, options, root) {
18
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
19
+ // @ts-ignore
20
+ return {
21
+ valid: ValidationLevel.Drop,
22
+ matches: [],
23
+ node: null,
24
+ syntax: '@' + atRule.nam,
25
+ error: 'expected @import media query list',
26
+ tokens: []
27
+ };
28
+ }
29
+ if ('chi' in atRule) {
30
+ // @ts-ignore
31
+ return {
32
+ valid: ValidationLevel.Drop,
33
+ matches: [],
34
+ node: null,
35
+ syntax: '@' + atRule.nam,
36
+ error: 'unexpected at-rule body',
37
+ tokens: []
38
+ };
39
+ }
40
+ const tokens = atRule.tokens.filter((t) => ![EnumToken.CommentTokenType].includes(t.typ));
41
+ if (tokens.length == 0) {
42
+ // @ts-ignore
43
+ return {
44
+ valid: ValidationLevel.Drop,
45
+ matches: [],
46
+ node: null,
47
+ syntax: '@' + atRule.nam,
48
+ error: 'expected @import media query list',
49
+ tokens: []
50
+ };
51
+ }
52
+ if (tokens[0].typ == EnumToken.StringTokenType) {
53
+ tokens.shift();
54
+ // @ts-ignore
55
+ consumeWhitespace(tokens);
56
+ }
57
+ else if (tokens[0].typ == EnumToken.UrlFunctionTokenType) {
58
+ const slice = tokens[0].chi.filter((t) => t.typ != EnumToken.CommentTokenType && t.typ != EnumToken.WhitespaceTokenType);
59
+ if (slice.length != 1 || ![EnumToken.StringTokenType, EnumToken.UrlTokenTokenType].includes(slice[0].typ)) {
60
+ // @ts-ignore
61
+ return {
62
+ valid: ValidationLevel.Drop,
63
+ matches: [],
64
+ node: tokens[0],
65
+ syntax: '@' + atRule.nam,
66
+ error: 'invalid url()',
67
+ tokens
68
+ };
69
+ }
70
+ else {
71
+ tokens.shift();
72
+ // @ts-ignore
73
+ if (!consumeWhitespace(tokens)) {
74
+ // @ts-ignore
75
+ return {
76
+ valid: ValidationLevel.Drop,
77
+ matches: [],
78
+ node: tokens[0],
79
+ syntax: '@' + atRule.nam,
80
+ error: 'expecting whitespace',
81
+ tokens
82
+ };
83
+ }
84
+ }
85
+ }
86
+ else {
87
+ // @ts-ignore
88
+ return {
89
+ valid: ValidationLevel.Drop,
90
+ matches: [],
91
+ node: tokens[0],
92
+ syntax: '@' + atRule.nam,
93
+ error: 'expecting url() or string',
94
+ tokens
95
+ };
96
+ }
97
+ if (tokens.length > 0) {
98
+ // @ts-ignore
99
+ if (tokens[0].typ == EnumToken.IdenTokenType) {
100
+ // @ts-ignore
101
+ if ('layer'.localeCompare(tokens[0].val, undefined, { sensitivity: 'base' }) == 0) {
102
+ tokens.shift();
103
+ // @ts-ignore
104
+ if (!consumeWhitespace(tokens)) {
105
+ // @ts-ignore
106
+ return {
107
+ valid: ValidationLevel.Drop,
108
+ matches: [],
109
+ node: tokens[0],
110
+ syntax: '@' + atRule.nam,
111
+ error: 'expecting whitespace',
112
+ tokens
113
+ };
114
+ }
115
+ }
116
+ }
117
+ // @ts-ignore
118
+ else if (tokens[0].typ == EnumToken.FunctionTokenType) {
119
+ // @ts-ignore
120
+ if ('layer'.localeCompare(tokens[0].val, undefined, { sensitivity: 'base' }) != 0) {
121
+ // @ts-ignore
122
+ return {
123
+ valid: ValidationLevel.Drop,
124
+ matches: [],
125
+ node: tokens[0],
126
+ syntax: '@' + atRule.nam,
127
+ error: 'expecting layer()',
128
+ tokens
129
+ };
130
+ }
131
+ // @ts-ignore
132
+ const result = validateLayerName(tokens[0].chi);
133
+ if (result.valid == ValidationLevel.Drop) {
134
+ return result;
135
+ }
136
+ tokens.shift();
137
+ // @ts-ignore
138
+ if (!consumeWhitespace(tokens)) {
139
+ // @ts-ignore
140
+ return {
141
+ valid: ValidationLevel.Drop,
142
+ matches: [],
143
+ node: tokens[0],
144
+ syntax: '@' + atRule.nam,
145
+ error: 'expecting whitespace',
146
+ tokens
147
+ };
148
+ }
149
+ }
150
+ }
151
+ if (tokens.length > 0) {
152
+ // @ts-ignore
153
+ if (tokens[0].typ == EnumToken.AtRuleTokenType) {
154
+ if (tokens[0].nam != 'supports') {
155
+ // @ts-ignore
156
+ return {
157
+ valid: ValidationLevel.Drop,
158
+ matches: [],
159
+ node: tokens[0],
160
+ syntax: '@' + atRule.nam,
161
+ error: 'expecting @supports or media query list',
162
+ tokens
163
+ };
164
+ }
165
+ // @ts-ignore
166
+ const result = validateAtRuleSupports(tokens[0]);
167
+ if (result.valid == ValidationLevel.Drop) {
168
+ return result;
169
+ }
170
+ tokens.shift();
171
+ // @ts-ignore
172
+ if (!consumeWhitespace(tokens)) {
173
+ // @ts-ignore
174
+ return {
175
+ valid: ValidationLevel.Drop,
176
+ matches: [],
177
+ node: tokens[0],
178
+ syntax: '@' + atRule.nam,
179
+ error: 'expecting whitespace',
180
+ tokens
181
+ };
182
+ }
183
+ }
184
+ }
185
+ if (tokens.length > 0) {
186
+ return validateAtRuleMediaQueryList(tokens, atRule);
187
+ }
188
+ // @ts-ignore
189
+ return {
190
+ valid: ValidationLevel.Valid,
191
+ matches: [],
192
+ node: null,
193
+ syntax: '@' + atRule.nam,
194
+ error: '',
195
+ tokens: []
196
+ };
197
+ }
198
+
199
+ export { validateAtRuleImport };
@@ -0,0 +1,70 @@
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
+
10
+ function validateAtRuleKeyframes(atRule, options, root) {
11
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
12
+ // @ts-ignore
13
+ return {
14
+ valid: ValidationLevel.Drop,
15
+ matches: [],
16
+ node: atRule,
17
+ syntax: '@document',
18
+ error: 'expecting at-rule prelude',
19
+ tokens: []
20
+ };
21
+ }
22
+ const tokens = atRule.tokens.slice();
23
+ consumeWhitespace(tokens);
24
+ if (tokens.length == 0) {
25
+ // @ts-ignore
26
+ return {
27
+ valid: ValidationLevel.Drop,
28
+ matches: [],
29
+ node: atRule,
30
+ syntax: '@keyframes',
31
+ error: 'expecting at-rule prelude',
32
+ tokens
33
+ };
34
+ }
35
+ if (![EnumToken.StringTokenType, EnumToken.IdenTokenType].includes(tokens[0].typ)) {
36
+ // @ts-ignore
37
+ return {
38
+ valid: ValidationLevel.Drop,
39
+ matches: [],
40
+ node: atRule,
41
+ syntax: '@keyframes',
42
+ error: 'expecting ident or string token',
43
+ tokens
44
+ };
45
+ }
46
+ tokens.shift();
47
+ consumeWhitespace(tokens);
48
+ if (tokens.length > 0) {
49
+ // @ts-ignore
50
+ return {
51
+ valid: ValidationLevel.Drop,
52
+ matches: [],
53
+ node: tokens[0],
54
+ syntax: '@keyframes',
55
+ error: 'unexpected token',
56
+ tokens
57
+ };
58
+ }
59
+ // @ts-ignore
60
+ return {
61
+ valid: ValidationLevel.Valid,
62
+ matches: [],
63
+ node: atRule,
64
+ syntax: '@keyframes',
65
+ error: '',
66
+ tokens
67
+ };
68
+ }
69
+
70
+ export { validateAtRuleKeyframes };
@@ -0,0 +1,30 @@
1
+ import { ValidationLevel } 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 { validateLayerName } from '../syntaxes/layer-name.js';
9
+ import '../syntaxes/complex-selector.js';
10
+ import '../parser/types.js';
11
+ import '../parser/parse.js';
12
+ import '../config.js';
13
+
14
+ function validateAtRuleLayer(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.Valid,
20
+ matches: [],
21
+ node: atRule,
22
+ syntax: '@layer',
23
+ error: '',
24
+ tokens: []
25
+ };
26
+ }
27
+ return validateLayerName(atRule.tokens);
28
+ }
29
+
30
+ export { validateAtRuleLayer };
@@ -0,0 +1,254 @@
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
+
11
+ function validateAtRuleMedia(atRule, options, root) {
12
+ // media-query-list
13
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
14
+ // @ts-ignore
15
+ return {
16
+ valid: ValidationLevel.Valid,
17
+ matches: [],
18
+ node: null,
19
+ syntax: null,
20
+ error: '',
21
+ tokens: []
22
+ };
23
+ }
24
+ let result = null;
25
+ const slice = atRule.tokens.slice();
26
+ consumeWhitespace(slice);
27
+ if (slice.length == 0) {
28
+ return {
29
+ valid: ValidationLevel.Valid,
30
+ matches: [],
31
+ node: atRule,
32
+ syntax: '@media',
33
+ error: '',
34
+ tokens: []
35
+ };
36
+ }
37
+ result = validateAtRuleMediaQueryList(atRule.tokens, atRule);
38
+ if (result.valid == ValidationLevel.Drop) {
39
+ return result;
40
+ }
41
+ if (!('chi' in atRule)) {
42
+ // @ts-ignore
43
+ return {
44
+ valid: ValidationLevel.Drop,
45
+ matches: [],
46
+ node: atRule,
47
+ syntax: '@media',
48
+ error: 'expected at-rule body',
49
+ tokens: []
50
+ };
51
+ }
52
+ // @ts-ignore
53
+ return {
54
+ valid: ValidationLevel.Valid,
55
+ matches: [],
56
+ node: atRule,
57
+ syntax: '@media',
58
+ error: '',
59
+ tokens: []
60
+ };
61
+ }
62
+ function validateAtRuleMediaQueryList(tokenList, atRule) {
63
+ const split = splitTokenList(tokenList);
64
+ const matched = [];
65
+ let result = null;
66
+ let previousToken;
67
+ let mediaFeatureType;
68
+ for (let i = 0; i < split.length; i++) {
69
+ const tokens = split[i].slice();
70
+ const match = [];
71
+ result = null;
72
+ mediaFeatureType = null;
73
+ previousToken = null;
74
+ if (tokens.length == 0) {
75
+ // @ts-ignore
76
+ result = {
77
+ valid: ValidationLevel.Drop,
78
+ matches: [],
79
+ node: tokens[0] ?? atRule,
80
+ syntax: '@media',
81
+ error: 'unexpected token',
82
+ tokens: []
83
+ };
84
+ continue;
85
+ }
86
+ while (tokens.length > 0) {
87
+ previousToken = tokens[0];
88
+ // media-condition | media-type | custom-media
89
+ if (!(validateMediaCondition(tokens[0], atRule) || validateMediaFeature(tokens[0]) || validateCustomMediaCondition(tokens[0], atRule))) {
90
+ if (tokens[0].typ == EnumToken.ParensTokenType) {
91
+ result = validateAtRuleMediaQueryList(tokens[0].chi, atRule);
92
+ }
93
+ else {
94
+ result = {
95
+ valid: ValidationLevel.Drop,
96
+ matches: [],
97
+ node: tokens[0] ?? atRule,
98
+ syntax: '@media',
99
+ error: 'expecting media feature or media condition',
100
+ tokens: []
101
+ };
102
+ }
103
+ if (result.valid == ValidationLevel.Drop) {
104
+ break;
105
+ }
106
+ result = null;
107
+ }
108
+ match.push(tokens.shift());
109
+ if (tokens.length == 0) {
110
+ break;
111
+ }
112
+ if (!consumeWhitespace(tokens)) {
113
+ if (previousToken?.typ != EnumToken.ParensTokenType) {
114
+ // @ts-ignore
115
+ result = {
116
+ valid: ValidationLevel.Drop,
117
+ matches: [],
118
+ node: tokens[0] ?? atRule,
119
+ syntax: '@media',
120
+ error: 'expected media query list',
121
+ tokens: []
122
+ };
123
+ break;
124
+ }
125
+ }
126
+ else if (![EnumToken.MediaFeatureOrTokenType, EnumToken.MediaFeatureAndTokenType].includes(tokens[0].typ)) {
127
+ // @ts-ignore
128
+ result = {
129
+ valid: ValidationLevel.Drop,
130
+ matches: [],
131
+ node: tokens[0] ?? atRule,
132
+ syntax: '@media',
133
+ error: 'expected and/or',
134
+ tokens: []
135
+ };
136
+ break;
137
+ }
138
+ if (mediaFeatureType == null) {
139
+ mediaFeatureType = tokens[0];
140
+ }
141
+ if (mediaFeatureType.typ != tokens[0].typ) {
142
+ // @ts-ignore
143
+ result = {
144
+ valid: ValidationLevel.Drop,
145
+ matches: [],
146
+ node: tokens[0] ?? atRule,
147
+ syntax: '@media',
148
+ error: 'mixing and/or not allowed at the same level',
149
+ tokens: []
150
+ };
151
+ break;
152
+ }
153
+ match.push({ typ: EnumToken.WhitespaceTokenType }, tokens.shift());
154
+ consumeWhitespace(tokens);
155
+ if (tokens.length == 0) {
156
+ // @ts-ignore
157
+ result = {
158
+ valid: ValidationLevel.Drop,
159
+ matches: [],
160
+ node: tokens[0] ?? atRule,
161
+ syntax: '@media',
162
+ error: 'expected media-condition',
163
+ tokens: []
164
+ };
165
+ break;
166
+ }
167
+ match.push({ typ: EnumToken.WhitespaceTokenType });
168
+ }
169
+ if (result == null && match.length > 0) {
170
+ matched.push(match);
171
+ }
172
+ }
173
+ if (result != null) {
174
+ return result;
175
+ }
176
+ if (matched.length == 0) {
177
+ return {
178
+ valid: ValidationLevel.Drop,
179
+ matches: [],
180
+ node: atRule,
181
+ syntax: '@media',
182
+ error: 'expected media query list',
183
+ tokens: []
184
+ };
185
+ }
186
+ tokenList.length = 0;
187
+ let hasAll = false;
188
+ for (let i = 0; i < matched.length; i++) {
189
+ if (tokenList.length > 0) {
190
+ tokenList.push({ typ: EnumToken.CommaTokenType });
191
+ }
192
+ if (matched[i].length == 1 && matched.length > 1 && matched[i][0].typ == EnumToken.MediaFeatureTokenType && matched[i][0].val == 'all') {
193
+ hasAll = true;
194
+ continue;
195
+ }
196
+ tokenList.push(...matched[i]);
197
+ }
198
+ if (hasAll && tokenList.length == 0) {
199
+ tokenList.push({ typ: EnumToken.MediaFeatureTokenType, val: 'all' });
200
+ }
201
+ // @ts-ignore
202
+ return {
203
+ valid: ValidationLevel.Valid,
204
+ matches: [],
205
+ node: atRule,
206
+ syntax: '@media',
207
+ error: '',
208
+ tokens: []
209
+ };
210
+ }
211
+ function validateCustomMediaCondition(token, atRule) {
212
+ if (token.typ == EnumToken.MediaFeatureNotTokenType) {
213
+ return validateMediaCondition(token.val, atRule);
214
+ }
215
+ if (token.typ != EnumToken.ParensTokenType) {
216
+ return false;
217
+ }
218
+ const chi = token.chi.filter((t) => t.typ != EnumToken.CommentTokenType && t.typ != EnumToken.WhitespaceTokenType);
219
+ if (chi.length != 1) {
220
+ return false;
221
+ }
222
+ return chi[0].typ == EnumToken.DashedIdenTokenType;
223
+ }
224
+ function validateMediaCondition(token, atRule) {
225
+ if (token.typ == EnumToken.MediaFeatureNotTokenType) {
226
+ return validateMediaCondition(token.val, atRule);
227
+ }
228
+ if (token.typ != EnumToken.ParensTokenType && !(['when', 'else'].includes(atRule.nam) && token.typ == EnumToken.FunctionTokenType && ['media', 'supports'].includes(token.val))) {
229
+ return false;
230
+ }
231
+ const chi = token.chi.filter((t) => t.typ != EnumToken.CommentTokenType && t.typ != EnumToken.WhitespaceTokenType);
232
+ if (chi.length != 1) {
233
+ return false;
234
+ }
235
+ if (chi[0].typ == EnumToken.IdenTokenType) {
236
+ return true;
237
+ }
238
+ if (chi[0].typ == EnumToken.MediaFeatureNotTokenType) {
239
+ return validateMediaCondition(chi[0].val, atRule);
240
+ }
241
+ if (chi[0].typ == EnumToken.MediaQueryConditionTokenType) {
242
+ return chi[0].l.typ == EnumToken.IdenTokenType;
243
+ }
244
+ return false;
245
+ }
246
+ function validateMediaFeature(token) {
247
+ let val = token;
248
+ if (token.typ == EnumToken.MediaFeatureOnlyTokenType || token.typ == EnumToken.MediaFeatureNotTokenType) {
249
+ val = token.val;
250
+ }
251
+ return val.typ == EnumToken.MediaFeatureTokenType;
252
+ }
253
+
254
+ export { validateAtRuleMedia, validateAtRuleMediaQueryList, validateMediaCondition, validateMediaFeature };
@@ -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 };