@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,114 @@
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 validateAtRuleDocument(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: '@document',
19
+ error: 'expecting at-rule prelude',
20
+ tokens: []
21
+ };
22
+ }
23
+ const tokens = atRule.tokens.slice();
24
+ let result = null;
25
+ consumeWhitespace(tokens);
26
+ if (tokens.length == 0) {
27
+ // @ts-ignore
28
+ return {
29
+ valid: ValidationLevel.Drop,
30
+ matches: [],
31
+ node: atRule,
32
+ syntax: '@document',
33
+ error: 'expecting at-rule prelude',
34
+ tokens
35
+ };
36
+ }
37
+ if (tokens[0].typ == EnumToken.CommaTokenType) {
38
+ // @ts-ignore
39
+ return {
40
+ valid: ValidationLevel.Drop,
41
+ matches: [],
42
+ node: tokens[0],
43
+ syntax: '@document',
44
+ error: 'unexpected token',
45
+ tokens
46
+ };
47
+ }
48
+ while (tokens.length > 0) {
49
+ if (tokens[0].typ == EnumToken.CommentTokenType) {
50
+ tokens.shift();
51
+ consumeWhitespace(tokens);
52
+ }
53
+ result = validateURL(tokens[0]);
54
+ if (result.valid == ValidationLevel.Valid) {
55
+ tokens.shift();
56
+ consumeWhitespace(tokens);
57
+ continue;
58
+ }
59
+ if (tokens[0].typ == EnumToken.FunctionTokenType) {
60
+ if (!['url-prefix', 'domain', 'media-document', 'regexp'].some((t) => t.localeCompare(tokens[0].val, undefined, { sensitivity: 'base' }) == 0)) {
61
+ // @ts-ignore
62
+ return {
63
+ valid: ValidationLevel.Drop,
64
+ matches: [],
65
+ node: tokens[0],
66
+ syntax: '@document',
67
+ error: 'unexpected token',
68
+ tokens
69
+ };
70
+ }
71
+ const children = tokens[0].chi.slice();
72
+ consumeWhitespace(children);
73
+ if (children.length == 0) {
74
+ // @ts-ignore
75
+ return {
76
+ valid: ValidationLevel.Drop,
77
+ matches: [],
78
+ node: tokens[0],
79
+ syntax: '@document',
80
+ error: 'expecting string argument',
81
+ tokens
82
+ };
83
+ }
84
+ if (children[0].typ == EnumToken.StringTokenType) {
85
+ children.shift();
86
+ consumeWhitespace(children);
87
+ }
88
+ if (children.length > 0) {
89
+ // @ts-ignore
90
+ return {
91
+ valid: ValidationLevel.Drop,
92
+ matches: [],
93
+ node: children[0],
94
+ syntax: '@document',
95
+ error: 'unexpected token',
96
+ tokens
97
+ };
98
+ }
99
+ tokens.shift();
100
+ consumeWhitespace(tokens);
101
+ }
102
+ }
103
+ // @ts-ignore
104
+ return {
105
+ valid: ValidationLevel.Valid,
106
+ matches: [],
107
+ node: atRule,
108
+ syntax: '@document',
109
+ error: '',
110
+ tokens
111
+ };
112
+ }
113
+
114
+ export { validateAtRuleDocument };
@@ -0,0 +1,49 @@
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 { validateFamilyName } from '../syntaxes/family-name.js';
9
+ import '../syntaxes/complex-selector.js';
10
+
11
+ function validateAtRuleFontFeatureValues(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: null,
18
+ syntax: '@' + atRule.nam,
19
+ error: 'expected at-rule prelude',
20
+ tokens: []
21
+ };
22
+ }
23
+ const result = validateFamilyName(atRule.tokens, atRule);
24
+ if (result.valid == ValidationLevel.Drop) {
25
+ return result;
26
+ }
27
+ if (!('chi' in atRule)) {
28
+ // @ts-ignore
29
+ return {
30
+ valid: ValidationLevel.Drop,
31
+ matches: [],
32
+ node: atRule,
33
+ syntax: '@' + atRule.nam,
34
+ error: 'expected at-rule body',
35
+ tokens: []
36
+ };
37
+ }
38
+ // @ts-ignore
39
+ return {
40
+ valid: ValidationLevel.Valid,
41
+ matches: [],
42
+ node: atRule,
43
+ syntax: '@' + atRule.nam,
44
+ error: '',
45
+ tokens: []
46
+ };
47
+ }
48
+
49
+ export { validateAtRuleFontFeatureValues };
@@ -0,0 +1,196 @@
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
+
14
+ function validateAtRuleImport(atRule, options, root) {
15
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
16
+ // @ts-ignore
17
+ return {
18
+ valid: ValidationLevel.Drop,
19
+ matches: [],
20
+ node: null,
21
+ syntax: '@' + atRule.nam,
22
+ error: 'expected @import media query list',
23
+ tokens: []
24
+ };
25
+ }
26
+ if ('chi' in atRule) {
27
+ // @ts-ignore
28
+ return {
29
+ valid: ValidationLevel.Drop,
30
+ matches: [],
31
+ node: null,
32
+ syntax: '@' + atRule.nam,
33
+ error: 'unexpected at-rule body',
34
+ tokens: []
35
+ };
36
+ }
37
+ const tokens = atRule.tokens.filter((t) => ![EnumToken.CommentTokenType].includes(t.typ));
38
+ if (tokens.length == 0) {
39
+ // @ts-ignore
40
+ return {
41
+ valid: ValidationLevel.Drop,
42
+ matches: [],
43
+ node: null,
44
+ syntax: '@' + atRule.nam,
45
+ error: 'expected @import media query list',
46
+ tokens: []
47
+ };
48
+ }
49
+ if (tokens[0].typ == EnumToken.StringTokenType) {
50
+ tokens.shift();
51
+ // @ts-ignore
52
+ consumeWhitespace(tokens);
53
+ }
54
+ else if (tokens[0].typ == EnumToken.UrlFunctionTokenType) {
55
+ const slice = tokens[0].chi.filter((t) => t.typ != EnumToken.CommentTokenType && t.typ != EnumToken.WhitespaceTokenType);
56
+ if (slice.length != 1 || ![EnumToken.StringTokenType, EnumToken.UrlTokenTokenType].includes(slice[0].typ)) {
57
+ // @ts-ignore
58
+ return {
59
+ valid: ValidationLevel.Drop,
60
+ matches: [],
61
+ node: tokens[0],
62
+ syntax: '@' + atRule.nam,
63
+ error: 'invalid url()',
64
+ tokens
65
+ };
66
+ }
67
+ else {
68
+ tokens.shift();
69
+ // @ts-ignore
70
+ if (!consumeWhitespace(tokens)) {
71
+ // @ts-ignore
72
+ return {
73
+ valid: ValidationLevel.Drop,
74
+ matches: [],
75
+ node: tokens[0],
76
+ syntax: '@' + atRule.nam,
77
+ error: 'expecting whitespace',
78
+ tokens
79
+ };
80
+ }
81
+ }
82
+ }
83
+ else {
84
+ // @ts-ignore
85
+ return {
86
+ valid: ValidationLevel.Drop,
87
+ matches: [],
88
+ node: tokens[0],
89
+ syntax: '@' + atRule.nam,
90
+ error: 'expecting url() or string',
91
+ tokens
92
+ };
93
+ }
94
+ if (tokens.length > 0) {
95
+ // @ts-ignore
96
+ if (tokens[0].typ == EnumToken.IdenTokenType) {
97
+ // @ts-ignore
98
+ if ('layer'.localeCompare(tokens[0].val, undefined, { sensitivity: 'base' }) == 0) {
99
+ tokens.shift();
100
+ // @ts-ignore
101
+ if (!consumeWhitespace(tokens)) {
102
+ // @ts-ignore
103
+ return {
104
+ valid: ValidationLevel.Drop,
105
+ matches: [],
106
+ node: tokens[0],
107
+ syntax: '@' + atRule.nam,
108
+ error: 'expecting whitespace',
109
+ tokens
110
+ };
111
+ }
112
+ }
113
+ }
114
+ // @ts-ignore
115
+ else if (tokens[0].typ == EnumToken.FunctionTokenType) {
116
+ // @ts-ignore
117
+ if ('layer'.localeCompare(tokens[0].val, undefined, { sensitivity: 'base' }) != 0) {
118
+ // @ts-ignore
119
+ return {
120
+ valid: ValidationLevel.Drop,
121
+ matches: [],
122
+ node: tokens[0],
123
+ syntax: '@' + atRule.nam,
124
+ error: 'expecting layer()',
125
+ tokens
126
+ };
127
+ }
128
+ // @ts-ignore
129
+ const result = validateLayerName(tokens[0].chi);
130
+ if (result.valid == ValidationLevel.Drop) {
131
+ return result;
132
+ }
133
+ tokens.shift();
134
+ // @ts-ignore
135
+ if (!consumeWhitespace(tokens)) {
136
+ // @ts-ignore
137
+ return {
138
+ valid: ValidationLevel.Drop,
139
+ matches: [],
140
+ node: tokens[0],
141
+ syntax: '@' + atRule.nam,
142
+ error: 'expecting whitespace',
143
+ tokens
144
+ };
145
+ }
146
+ }
147
+ }
148
+ if (tokens.length > 0) {
149
+ // @ts-ignore
150
+ if (tokens[0].typ == EnumToken.AtRuleTokenType) {
151
+ if (tokens[0].nam != 'supports') {
152
+ // @ts-ignore
153
+ return {
154
+ valid: ValidationLevel.Drop,
155
+ matches: [],
156
+ node: tokens[0],
157
+ syntax: '@' + atRule.nam,
158
+ error: 'expecting @supports or media query list',
159
+ tokens
160
+ };
161
+ }
162
+ // @ts-ignore
163
+ const result = validateAtRuleSupports(tokens[0]);
164
+ if (result.valid == ValidationLevel.Drop) {
165
+ return result;
166
+ }
167
+ tokens.shift();
168
+ // @ts-ignore
169
+ if (!consumeWhitespace(tokens)) {
170
+ // @ts-ignore
171
+ return {
172
+ valid: ValidationLevel.Drop,
173
+ matches: [],
174
+ node: tokens[0],
175
+ syntax: '@' + atRule.nam,
176
+ error: 'expecting whitespace',
177
+ tokens
178
+ };
179
+ }
180
+ }
181
+ }
182
+ if (tokens.length > 0) {
183
+ return validateAtRuleMediaQueryList(tokens, atRule);
184
+ }
185
+ // @ts-ignore
186
+ return {
187
+ valid: ValidationLevel.Valid,
188
+ matches: [],
189
+ node: null,
190
+ syntax: '@' + atRule.nam,
191
+ error: '',
192
+ tokens: []
193
+ };
194
+ }
195
+
196
+ 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,27 @@
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
+
11
+ function validateAtRuleLayer(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: atRule,
19
+ syntax: '@layer',
20
+ error: '',
21
+ tokens: []
22
+ };
23
+ }
24
+ return validateLayerName(atRule.tokens);
25
+ }
26
+
27
+ export { validateAtRuleLayer };
@@ -0,0 +1,166 @@
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.Drop,
17
+ matches: [],
18
+ node: atRule,
19
+ syntax: '@media',
20
+ error: 'expected media query list',
21
+ tokens: []
22
+ };
23
+ }
24
+ const result = validateAtRuleMediaQueryList(atRule.tokens, atRule);
25
+ if (result.valid == ValidationLevel.Drop) {
26
+ return result;
27
+ }
28
+ if (!('chi' in atRule)) {
29
+ // @ts-ignore
30
+ return {
31
+ valid: ValidationLevel.Drop,
32
+ matches: [],
33
+ node: atRule,
34
+ syntax: '@media',
35
+ error: 'expected at-rule body',
36
+ tokens: []
37
+ };
38
+ }
39
+ // @ts-ignore
40
+ return {
41
+ valid: ValidationLevel.Valid,
42
+ matches: [],
43
+ node: atRule,
44
+ syntax: '@media',
45
+ error: '',
46
+ tokens: []
47
+ };
48
+ }
49
+ function validateAtRuleMediaQueryList(tokenList, atRule) {
50
+ for (const tokens of splitTokenList(tokenList)) {
51
+ if (tokens.length == 0) {
52
+ // @ts-ignore
53
+ return {
54
+ valid: ValidationLevel.Drop,
55
+ matches: [],
56
+ node: tokens[0] ?? atRule,
57
+ syntax: '@media',
58
+ error: 'unexpected token',
59
+ tokens: []
60
+ };
61
+ }
62
+ let previousToken = null;
63
+ while (tokens.length > 0) {
64
+ // media-condition
65
+ if (validateMediaCondition(tokens[0])) {
66
+ previousToken = tokens[0];
67
+ tokens.shift();
68
+ }
69
+ // media-type
70
+ else if (validateMediaFeature(tokens[0])) {
71
+ previousToken = tokens[0];
72
+ tokens.shift();
73
+ }
74
+ if (tokens.length == 0) {
75
+ break;
76
+ }
77
+ if (!consumeWhitespace(tokens)) {
78
+ if (previousToken?.typ != EnumToken.ParensTokenType) {
79
+ // @ts-ignore
80
+ return {
81
+ valid: ValidationLevel.Drop,
82
+ matches: [],
83
+ node: tokens[0] ?? atRule,
84
+ syntax: '@media',
85
+ error: 'expected media query list',
86
+ tokens: []
87
+ };
88
+ }
89
+ }
90
+ if (![EnumToken.MediaFeatureOrTokenType, EnumToken.MediaFeatureAndTokenType].includes(tokens[0].typ)) {
91
+ // @ts-ignore
92
+ return {
93
+ valid: ValidationLevel.Drop,
94
+ matches: [],
95
+ node: tokens[0] ?? atRule,
96
+ syntax: '@media',
97
+ error: 'expected and/or',
98
+ tokens: []
99
+ };
100
+ }
101
+ if (tokens.length == 1) {
102
+ // @ts-ignore
103
+ return {
104
+ valid: ValidationLevel.Drop,
105
+ matches: [],
106
+ node: tokens[0] ?? atRule,
107
+ syntax: '@media',
108
+ error: 'expected media-condition',
109
+ tokens: []
110
+ };
111
+ }
112
+ tokens.shift();
113
+ if (!consumeWhitespace(tokens)) {
114
+ // @ts-ignore
115
+ return {
116
+ valid: ValidationLevel.Drop,
117
+ matches: [],
118
+ node: tokens[0] ?? atRule,
119
+ syntax: '@media',
120
+ error: 'expected whitespace',
121
+ tokens: []
122
+ };
123
+ }
124
+ }
125
+ }
126
+ // @ts-ignore
127
+ return {
128
+ valid: ValidationLevel.Valid,
129
+ matches: [],
130
+ node: atRule,
131
+ syntax: '@media',
132
+ error: '',
133
+ tokens: []
134
+ };
135
+ }
136
+ function validateMediaCondition(token) {
137
+ if (token.typ == EnumToken.MediaFeatureNotTokenType) {
138
+ return validateMediaCondition(token.val);
139
+ }
140
+ if (token.typ != EnumToken.ParensTokenType) {
141
+ return false;
142
+ }
143
+ const chi = token.chi.filter((t) => t.typ != EnumToken.CommentTokenType && t.typ != EnumToken.WhitespaceTokenType);
144
+ if (chi.length != 1) {
145
+ return false;
146
+ }
147
+ if (chi[0].typ == EnumToken.IdenTokenType) {
148
+ return true;
149
+ }
150
+ if (chi[0].typ == EnumToken.MediaFeatureNotTokenType) {
151
+ return validateMediaCondition(chi[0].val);
152
+ }
153
+ if (chi[0].typ == EnumToken.MediaQueryConditionTokenType) {
154
+ return chi[0].l.typ == EnumToken.IdenTokenType;
155
+ }
156
+ return false;
157
+ }
158
+ function validateMediaFeature(token) {
159
+ let val = token;
160
+ if (token.typ == EnumToken.MediaFeatureOnlyTokenType || token.typ == EnumToken.MediaFeatureNotTokenType) {
161
+ val = token.val;
162
+ }
163
+ return val.typ == EnumToken.MediaFeatureTokenType;
164
+ }
165
+
166
+ export { validateAtRuleMedia, validateAtRuleMediaQueryList };