@tbela99/css-parser 1.4.2 → 1.4.3

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 (216) hide show
  1. package/.nyc_output/4874b20e-6f53-4d7a-be5a-cf68316925f2.json +1 -0
  2. package/.nyc_output/6193bc4c-6f5f-4898-8950-c628825e6342.json +1 -0
  3. package/.nyc_output/processinfo/4874b20e-6f53-4d7a-be5a-cf68316925f2.json +1 -0
  4. package/.nyc_output/processinfo/6193bc4c-6f5f-4898-8950-c628825e6342.json +1 -0
  5. package/.repl_history +4 -0
  6. package/CHANGELOG.md +164 -4
  7. package/README.md +43 -0
  8. package/badges/coverage.svg +20 -0
  9. package/deno.lock +2861 -0
  10. package/dist/config.json.js +33 -1
  11. package/dist/index-umd-web.js +24382 -18476
  12. package/dist/index.cjs +24522 -18618
  13. package/dist/index.d.ts +1396 -929
  14. package/dist/lib/ast/clone.d.ts +10 -0
  15. package/dist/lib/ast/clone.js +45 -0
  16. package/dist/lib/ast/expand.d.ts +14 -0
  17. package/dist/lib/ast/expand.js +89 -64
  18. package/dist/lib/ast/features/calc.d.ts +10 -0
  19. package/dist/lib/ast/features/calc.js +62 -24
  20. package/dist/lib/ast/features/if.d.ts +10 -0
  21. package/dist/lib/ast/features/if.js +215 -0
  22. package/dist/lib/ast/features/index.d.ts +6 -0
  23. package/dist/lib/ast/features/index.js +1 -0
  24. package/dist/lib/ast/features/inlinecssvariables.d.ts +15 -0
  25. package/dist/lib/ast/features/inlinecssvariables.js +32 -27
  26. package/dist/lib/ast/features/prefix.d.ts +8 -0
  27. package/dist/lib/ast/features/prefix.js +68 -43
  28. package/dist/lib/ast/features/shorthand.d.ts +12 -0
  29. package/dist/lib/ast/features/shorthand.js +6 -9
  30. package/dist/lib/ast/features/transform.d.ts +10 -0
  31. package/dist/lib/ast/features/transform.js +9 -13
  32. package/dist/lib/ast/features/type.d.ts +15 -0
  33. package/dist/lib/ast/find.d.ts +165 -0
  34. package/dist/lib/ast/find.js +175 -0
  35. package/dist/lib/ast/math/expression.d.ts +18 -0
  36. package/dist/lib/ast/math/expression.js +140 -98
  37. package/dist/lib/ast/math/math.d.ts +6 -0
  38. package/dist/lib/ast/math/math.js +30 -41
  39. package/dist/lib/ast/minify.d.ts +19 -0
  40. package/dist/lib/ast/minify.js +541 -217
  41. package/dist/lib/ast/transform/compute.d.ts +8 -0
  42. package/dist/lib/ast/transform/compute.js +82 -69
  43. package/dist/lib/ast/transform/matrix.d.ts +22 -0
  44. package/dist/lib/ast/transform/matrix.js +12 -26
  45. package/dist/lib/ast/transform/minify.d.ts +5 -0
  46. package/dist/lib/ast/transform/minify.js +20 -20
  47. package/dist/lib/ast/transform/perspective.d.ts +3 -0
  48. package/dist/lib/ast/transform/perspective.js +1 -1
  49. package/dist/lib/ast/transform/rotate.d.ts +12 -0
  50. package/dist/lib/ast/transform/rotate.js +1 -1
  51. package/dist/lib/ast/transform/scale.d.ts +6 -0
  52. package/dist/lib/ast/transform/scale.js +1 -1
  53. package/dist/lib/ast/transform/skew.d.ts +4 -0
  54. package/dist/lib/ast/transform/skew.js +1 -1
  55. package/dist/lib/ast/transform/translate.d.ts +6 -0
  56. package/dist/lib/ast/transform/translate.js +1 -1
  57. package/dist/lib/ast/transform/utils.d.ts +9 -0
  58. package/dist/lib/ast/types.d.ts +903 -0
  59. package/dist/lib/ast/types.js +277 -23
  60. package/dist/lib/ast/walk.d.ts +162 -0
  61. package/dist/lib/ast/walk.js +116 -60
  62. package/dist/lib/fs/resolve.d.ts +20 -0
  63. package/dist/lib/fs/resolve.js +37 -45
  64. package/dist/lib/parser/declaration/list.d.ts +16 -0
  65. package/dist/lib/parser/declaration/list.js +26 -24
  66. package/dist/lib/parser/declaration/map.d.ts +15 -0
  67. package/dist/lib/parser/declaration/map.js +140 -95
  68. package/dist/lib/parser/declaration/set.d.ts +9 -0
  69. package/dist/lib/parser/declaration/set.js +30 -25
  70. package/dist/lib/parser/node.d.ts +7 -0
  71. package/dist/lib/parser/parse.d.ts +107 -0
  72. package/dist/lib/parser/parse.js +1454 -1445
  73. package/dist/lib/parser/tokenize.d.ts +57 -0
  74. package/dist/lib/parser/tokenize.js +557 -404
  75. package/dist/lib/parser/utils/at-rule-container.d.ts +5 -0
  76. package/dist/lib/parser/utils/at-rule-container.js +486 -0
  77. package/dist/lib/parser/utils/at-rule-font-feature-values.d.ts +5 -0
  78. package/dist/lib/parser/utils/at-rule-font-feature-values.js +13 -0
  79. package/dist/lib/parser/utils/at-rule-generic.d.ts +5 -0
  80. package/dist/lib/parser/utils/at-rule-generic.js +118 -0
  81. package/dist/lib/parser/utils/at-rule-import.d.ts +5 -0
  82. package/dist/lib/parser/utils/at-rule-import.js +393 -0
  83. package/dist/lib/parser/utils/at-rule-media.d.ts +5 -0
  84. package/dist/lib/parser/utils/at-rule-media.js +603 -0
  85. package/dist/lib/parser/utils/at-rule-page.d.ts +5 -0
  86. package/dist/lib/parser/utils/at-rule-page.js +28 -0
  87. package/dist/lib/parser/utils/at-rule-support.d.ts +5 -0
  88. package/dist/lib/parser/utils/at-rule-support.js +366 -0
  89. package/dist/lib/parser/utils/at-rule-token.d.ts +1 -0
  90. package/dist/lib/parser/utils/at-rule-when-else.d.ts +5 -0
  91. package/dist/lib/parser/utils/at-rule-when-else.js +363 -0
  92. package/dist/lib/parser/utils/at-rule.d.ts +13 -0
  93. package/dist/lib/parser/utils/at-rule.js +37 -0
  94. package/dist/lib/parser/utils/cache.d.ts +6 -0
  95. package/dist/lib/parser/utils/cache.js +19 -0
  96. package/dist/lib/parser/utils/config.d.ts +2 -0
  97. package/dist/lib/parser/utils/config.js +1 -0
  98. package/dist/lib/parser/utils/declaration-list.d.ts +5 -0
  99. package/dist/lib/parser/utils/declaration.d.ts +18 -0
  100. package/dist/lib/parser/utils/declaration.js +569 -91
  101. package/dist/lib/parser/utils/eq.d.ts +1 -0
  102. package/dist/lib/parser/utils/hash.d.ts +21 -0
  103. package/dist/lib/parser/utils/hash.js +1 -1
  104. package/dist/lib/parser/utils/selector.d.ts +5 -0
  105. package/dist/lib/parser/utils/selector.js +476 -0
  106. package/dist/lib/parser/utils/text.d.ts +3 -0
  107. package/dist/lib/parser/utils/text.js +17 -1
  108. package/dist/lib/parser/utils/token.d.ts +14 -0
  109. package/dist/lib/parser/utils/token.js +102 -0
  110. package/dist/lib/parser/utils/type.d.ts +2 -0
  111. package/dist/lib/parser/utils/type.js +29 -18
  112. package/dist/lib/renderer/render.d.ts +28 -0
  113. package/dist/lib/renderer/render.js +421 -262
  114. package/dist/lib/renderer/sourcemap/lib/encode.d.ts +1 -0
  115. package/dist/lib/renderer/sourcemap/sourcemap.d.ts +26 -0
  116. package/dist/lib/renderer/sourcemap/sourcemap.js +17 -7
  117. package/dist/lib/syntax/color/a98rgb.d.ts +2 -0
  118. package/dist/lib/syntax/color/a98rgb.js +8 -12
  119. package/dist/lib/syntax/color/cmyk.d.ts +10 -0
  120. package/dist/lib/syntax/color/cmyk.js +23 -21
  121. package/dist/lib/syntax/color/color-mix.d.ts +2 -0
  122. package/dist/lib/syntax/color/color-mix.js +88 -77
  123. package/dist/lib/syntax/color/color.d.ts +42 -0
  124. package/dist/lib/syntax/color/color.js +65 -68
  125. package/dist/lib/syntax/color/hex.d.ts +16 -0
  126. package/dist/lib/syntax/color/hex.js +27 -31
  127. package/dist/lib/syntax/color/hsl.d.ts +20 -0
  128. package/dist/lib/syntax/color/hsl.js +5 -12
  129. package/dist/lib/syntax/color/hsv.d.ts +2 -0
  130. package/dist/lib/syntax/color/hwb.d.ts +21 -0
  131. package/dist/lib/syntax/color/hwb.js +8 -21
  132. package/dist/lib/syntax/color/lab.d.ts +25 -0
  133. package/dist/lib/syntax/color/lab.js +20 -21
  134. package/dist/lib/syntax/color/lch.d.ts +23 -0
  135. package/dist/lib/syntax/color/lch.js +13 -15
  136. package/dist/lib/syntax/color/oklab.d.ts +22 -0
  137. package/dist/lib/syntax/color/oklab.js +20 -39
  138. package/dist/lib/syntax/color/oklch.d.ts +20 -0
  139. package/dist/lib/syntax/color/oklch.js +14 -16
  140. package/dist/lib/syntax/color/p3.d.ts +6 -0
  141. package/dist/lib/syntax/color/p3.js +0 -8
  142. package/dist/lib/syntax/color/prophotorgb.d.ts +2 -0
  143. package/dist/lib/syntax/color/rec2020.d.ts +2 -0
  144. package/dist/lib/syntax/color/rec2020.js +9 -13
  145. package/dist/lib/syntax/color/relativecolor.d.ts +13 -0
  146. package/dist/lib/syntax/color/relativecolor.js +68 -41
  147. package/dist/lib/syntax/color/rgb.d.ts +20 -0
  148. package/dist/lib/syntax/color/rgb.js +14 -18
  149. package/dist/lib/syntax/color/srgb.d.ts +23 -0
  150. package/dist/lib/syntax/color/srgb.js +27 -26
  151. package/dist/lib/syntax/color/utils/components.d.ts +2 -0
  152. package/dist/lib/syntax/color/utils/components.js +30 -14
  153. package/dist/lib/syntax/color/utils/distance.d.ts +18 -0
  154. package/dist/lib/syntax/color/utils/distance.js +1 -8
  155. package/dist/lib/syntax/color/utils/matrix.d.ts +6 -0
  156. package/dist/lib/syntax/color/xyz.d.ts +5 -0
  157. package/dist/lib/syntax/color/xyz.js +8 -20
  158. package/dist/lib/syntax/color/xyzd50.d.ts +4 -0
  159. package/dist/lib/syntax/color/xyzd50.js +6 -20
  160. package/dist/lib/syntax/constants.d.ts +67 -0
  161. package/dist/lib/syntax/constants.js +436 -0
  162. package/dist/lib/syntax/syntax.d.ts +38 -0
  163. package/dist/lib/syntax/syntax.js +533 -568
  164. package/dist/lib/validation/config.d.ts +14 -0
  165. package/dist/lib/validation/config.js +72 -33
  166. package/dist/lib/validation/config.json.js +1159 -74
  167. package/dist/lib/validation/json.d.ts +2 -0
  168. package/dist/lib/validation/match.d.ts +38 -0
  169. package/dist/lib/validation/match.js +2985 -0
  170. package/dist/lib/validation/parser/parse.d.ts +8 -0
  171. package/dist/lib/validation/parser/parse.js +684 -935
  172. package/dist/lib/validation/parser/typedef.d.ts +95 -0
  173. package/dist/lib/validation/parser/typedef.js +100 -0
  174. package/dist/lib/validation/utils/list.d.ts +4 -0
  175. package/dist/lib/validation/utils/list.js +4 -11
  176. package/dist/lib/validation/utils/whitespace.d.ts +2 -0
  177. package/dist/lib/validation/utils/whitespace.js +2 -8
  178. package/dist/node.d.ts +207 -0
  179. package/dist/node.js +42 -39
  180. package/dist/web.d.ts +169 -0
  181. package/dist/web.js +38 -33
  182. package/package.json +15 -12
  183. package/playground/index.html +1328 -0
  184. package/playground/sw.js +55 -0
  185. package/playground/tree.js +176 -0
  186. package/dist/lib/syntax/color/utils/constants.js +0 -214
  187. package/dist/lib/syntax/utils.js +0 -70
  188. package/dist/lib/validation/at-rules/container.js +0 -342
  189. package/dist/lib/validation/at-rules/counter-style.js +0 -90
  190. package/dist/lib/validation/at-rules/custom-media.js +0 -50
  191. package/dist/lib/validation/at-rules/document.js +0 -89
  192. package/dist/lib/validation/at-rules/else.js +0 -5
  193. package/dist/lib/validation/at-rules/font-feature-values.js +0 -63
  194. package/dist/lib/validation/at-rules/import.js +0 -150
  195. package/dist/lib/validation/at-rules/keyframes.js +0 -67
  196. package/dist/lib/validation/at-rules/layer.js +0 -41
  197. package/dist/lib/validation/at-rules/media.js +0 -255
  198. package/dist/lib/validation/at-rules/namespace.js +0 -81
  199. package/dist/lib/validation/at-rules/page-margin-box.js +0 -64
  200. package/dist/lib/validation/at-rules/page.js +0 -100
  201. package/dist/lib/validation/at-rules/supports.js +0 -295
  202. package/dist/lib/validation/at-rules/when.js +0 -185
  203. package/dist/lib/validation/atrule.js +0 -184
  204. package/dist/lib/validation/selector.js +0 -36
  205. package/dist/lib/validation/syntax.js +0 -1073
  206. package/dist/lib/validation/syntaxes/complex-selector-list.js +0 -27
  207. package/dist/lib/validation/syntaxes/complex-selector.js +0 -52
  208. package/dist/lib/validation/syntaxes/compound-selector.js +0 -196
  209. package/dist/lib/validation/syntaxes/family-name.js +0 -57
  210. package/dist/lib/validation/syntaxes/keyframe-selector.js +0 -36
  211. package/dist/lib/validation/syntaxes/layer-name.js +0 -57
  212. package/dist/lib/validation/syntaxes/relative-selector-list.js +0 -31
  213. package/dist/lib/validation/syntaxes/relative-selector.js +0 -38
  214. package/dist/lib/validation/syntaxes/selector-list.js +0 -5
  215. package/dist/lib/validation/syntaxes/selector.js +0 -5
  216. package/dist/lib/validation/syntaxes/url.js +0 -40
@@ -0,0 +1,603 @@
1
+ import { EnumToken } from '../../ast/types.js';
2
+ import { evaluate } from '../../ast/math/expression.js';
3
+ import { gcd } from '../../ast/math/math.js';
4
+ import { tokensfuncDefMap, mediaTypes, definedPropertySettings, mFLT, mFGT } from '../../syntax/constants.js';
5
+ import { trimArray, matchAllSyntax, createValidationContext, getMFInfo, isMFValue, isMFName } from '../../validation/match.js';
6
+ import { ValidationSyntaxGroupEnum, MediaFeatureType } from '../../validation/parser/typedef.js';
7
+ import { getParsedSyntax } from '../../validation/config.js';
8
+
9
+ // https://drafts.csswg.org/mediaqueries/#media-descriptor-table:~:text=It%20is%20invalid%20to%20mix%20and%20and%20or%20and%20not%20at%20the%20same%20%E2%80%9Clevel%E2%80%9D%20of%20a%20media%20query%2E
10
+ // 'or' is not allowed at the same level as 'and' and 'not'
11
+ // 'or' is not allowed outside of parentheses
12
+ // https://drafts.csswg.org/mediaqueries/#error-handling
13
+ // error recovery
14
+ function parseMediaqueryList(stream, options) {
15
+ let matchCount = 0;
16
+ const errors = [];
17
+ let hasErrors = false;
18
+ const parts = stream.reduce((acc, t) => {
19
+ if (t.typ === EnumToken.CommaTokenType && matchCount === 0) {
20
+ acc.push([]);
21
+ }
22
+ else {
23
+ acc[acc.length - 1].push(t);
24
+ if (t.typ === EnumToken.StartParensTokenType || tokensfuncDefMap.has(t.typ)) {
25
+ matchCount++;
26
+ }
27
+ else if (t.typ === EnumToken.EndParensTokenType) {
28
+ if (matchCount > 0) {
29
+ matchCount--;
30
+ }
31
+ }
32
+ }
33
+ return acc;
34
+ }, [[]]);
35
+ {
36
+ for (const stream of parts.slice()) {
37
+ let success = true;
38
+ let i;
39
+ let currentScope = new Set();
40
+ const scopes = [currentScope];
41
+ const stack = [];
42
+ const tokens = [];
43
+ let expectAndOrComma = false;
44
+ i = 0;
45
+ while (i < stream.length &&
46
+ (stream[i]?.typ === EnumToken.WhitespaceTokenType || stream[i]?.typ === EnumToken.CommentTokenType)) {
47
+ tokens.push(stream[i]);
48
+ i++;
49
+ }
50
+ // [not | only] <media-type> [ and <media-condition-without-or> ]?
51
+ if (i < stream.length) {
52
+ if (stream[i].typ === EnumToken.IdenTokenType) {
53
+ const val = stream[i].val.toLowerCase();
54
+ if ("not" === val || "only" === val) {
55
+ tokens.push(stream[i]);
56
+ stack.push(stream[i]);
57
+ i++;
58
+ while (i < stream.length &&
59
+ (stream[i]?.typ === EnumToken.WhitespaceTokenType ||
60
+ stream[i]?.typ === EnumToken.CommentTokenType)) {
61
+ tokens.push(stream[i]);
62
+ i++;
63
+ }
64
+ if (stream[i]?.typ !== EnumToken.IdenTokenType ||
65
+ !mediaTypes.includes(stream[i].val.toLowerCase())) {
66
+ errors.push({
67
+ action: "drop",
68
+ node: stream[i],
69
+ message: `expecting '<media-type>' at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
70
+ });
71
+ continue;
72
+ }
73
+ const index = tokens.indexOf(stack[stack.length - 1]);
74
+ tokens[index] = Object.defineProperty(Object.assign(tokens[index], {
75
+ typ: val === "not" ? EnumToken.NotTokenType : EnumToken.OnlyTokenType,
76
+ val: stream[i],
77
+ }), "loc", { ...definedPropertySettings, value: { ...tokens[index].loc, end: stream[i].loc.end } });
78
+ tokens.length = index + 1;
79
+ i++;
80
+ // expect end of stream | and | or | not
81
+ while (i < stream.length &&
82
+ (stream[i]?.typ === EnumToken.WhitespaceTokenType ||
83
+ stream[i]?.typ === EnumToken.CommentTokenType)) {
84
+ tokens.push(stream[i]);
85
+ i++;
86
+ }
87
+ if (i < stream.length) {
88
+ if (stream[i].typ === EnumToken.AndTokenType) {
89
+ tokens.push(Object.assign(stream[i], { typ: EnumToken.AndTokenType }));
90
+ stack.push(stream[i]);
91
+ i++;
92
+ }
93
+ else if (stream[i].typ === EnumToken.OrTokenType) {
94
+ tokens.push(Object.assign(stream[i], { typ: EnumToken.OrTokenType }));
95
+ stack.push(stream[i]);
96
+ i++;
97
+ }
98
+ else {
99
+ success = false;
100
+ errors.push({
101
+ action: "drop",
102
+ node: stream[i],
103
+ message: `expecting 'and' or 'or' at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
104
+ });
105
+ }
106
+ }
107
+ }
108
+ else if (mediaTypes.includes(val)) {
109
+ tokens.push(stream[i]);
110
+ i++;
111
+ }
112
+ else {
113
+ success = false;
114
+ errors.push({
115
+ action: "drop",
116
+ message: `expecting '<media-type>' at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
117
+ node: stream[i],
118
+ location: stream[i].loc,
119
+ });
120
+ }
121
+ }
122
+ else if (stream[i].typ !== EnumToken.StartParensTokenType) {
123
+ success = false;
124
+ errors.push({
125
+ action: "drop",
126
+ message: `expecting '(' at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
127
+ node: stream[i],
128
+ location: stream[i].loc,
129
+ });
130
+ }
131
+ }
132
+ for (; i < stream.length; i++) {
133
+ tokens.push(stream[i]);
134
+ if (stream[i].typ === EnumToken.WhitespaceTokenType || stream[i].typ === EnumToken.CommentTokenType) {
135
+ continue;
136
+ }
137
+ if (expectAndOrComma) {
138
+ let valid = true;
139
+ if (stream[i].typ === EnumToken.IdenTokenType) {
140
+ const val = stream[i].val.toLowerCase();
141
+ valid = val === "and" || val === "or";
142
+ }
143
+ else {
144
+ valid = stream[i].typ !== EnumToken.CommaTokenType;
145
+ }
146
+ if (!valid) {
147
+ success = false;
148
+ errors.push({
149
+ action: "drop",
150
+ node: stream[i],
151
+ message: `expecting <and>, <or> or comma at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
152
+ });
153
+ break;
154
+ }
155
+ expectAndOrComma = false;
156
+ }
157
+ if (stream[i].typ === EnumToken.StartParensTokenType || tokensfuncDefMap.has(stream[i].typ)) {
158
+ scopes.push((currentScope = new Set()));
159
+ stack.push(stream[i]);
160
+ continue;
161
+ }
162
+ switch (stream[i].typ) {
163
+ case EnumToken.LiteralTokenType:
164
+ if (stream[i].val === "<") {
165
+ stack.push(Object.assign(stream[i], { typ: EnumToken.LtTokenType }));
166
+ }
167
+ if (stream[i].val === ">") {
168
+ stack.push(Object.assign(stream[i], { typ: EnumToken.GtTokenType }));
169
+ }
170
+ break;
171
+ case EnumToken.ColonTokenType:
172
+ case EnumToken.LtTokenType:
173
+ case EnumToken.LteTokenType:
174
+ case EnumToken.GtTokenType:
175
+ case EnumToken.GteTokenType:
176
+ case EnumToken.DelimTokenType:
177
+ stack.push(stream[i]);
178
+ break;
179
+ case EnumToken.IdenTokenType:
180
+ {
181
+ const val = stream[i].val.toLowerCase();
182
+ if (val === "not" || val === "only") {
183
+ Object.assign(stream[i], {
184
+ typ: val === "not" ? EnumToken.NotTokenType : EnumToken.OnlyTokenType,
185
+ });
186
+ stack.push(stream[i]);
187
+ }
188
+ else if (val === "and" || val === "or") {
189
+ Object.assign(stream[i], {
190
+ typ: val === "and" ? EnumToken.AndTokenType : EnumToken.OrTokenType,
191
+ });
192
+ if (val === "or" && scopes.length <= 1) {
193
+ success = false;
194
+ errors.push({
195
+ action: "drop",
196
+ node: stream[i],
197
+ message: `<or> is not allowed outside of parentheses ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
198
+ });
199
+ break;
200
+ }
201
+ if (currentScope.has(val === "or" ? EnumToken.AndTokenType : EnumToken.OrTokenType)) {
202
+ success = false;
203
+ errors.push({
204
+ action: "drop",
205
+ node: stream[i],
206
+ message: `cannot mix <and> and <or> at the same level at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
207
+ });
208
+ }
209
+ currentScope.add(stream[i].typ);
210
+ stack.push(stream[i]);
211
+ }
212
+ }
213
+ break;
214
+ case EnumToken.EndParensTokenType:
215
+ if (tokensfuncDefMap.has(stack.at(-1)?.typ)) {
216
+ const index = tokens.indexOf(stack.at(-1));
217
+ Object.defineProperty(Object.assign(tokens[index], {
218
+ typ: tokensfuncDefMap.get(stack.at(-1)?.typ),
219
+ chi: trimArray(tokens.slice(index + 1, tokens.length - 1)),
220
+ }), "loc", {
221
+ ...definedPropertySettings,
222
+ value: { ...tokens[index].loc, end: stream[i].loc.end },
223
+ });
224
+ tokens.length = index + 1;
225
+ const result = matchAllSyntax(getParsedSyntax(ValidationSyntaxGroupEnum.Syntaxes, tokens[index].val + "()")?.[0]?.chi, createValidationContext(tokens[index].chi), options);
226
+ stack.pop();
227
+ scopes.pop();
228
+ currentScope = scopes.at(-1);
229
+ if (!result.success) {
230
+ errors.push(...result.errors);
231
+ success = false;
232
+ }
233
+ break;
234
+ }
235
+ // feature
236
+ if (mFLT.has(stack.at(-1)?.typ) || mFGT.has(stack.at(-1)?.typ)) {
237
+ // <mf-lt> | <mf-gt>
238
+ const index = tokens.indexOf(stack.at(-1));
239
+ const prevToken = stack[stack.length - 2];
240
+ if (mFLT.has(prevToken?.typ) || mFGT.has(prevToken?.typ)) {
241
+ if (stack[stack.length - 3]?.typ !== EnumToken.StartParensTokenType) {
242
+ success = false;
243
+ errors.push({
244
+ action: "drop",
245
+ node: stream[i],
246
+ message: `unmatched '(' at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
247
+ });
248
+ break;
249
+ }
250
+ if (!mFLT.has(stack.at(-1)?.typ) && mFLT.has(prevToken?.typ)) {
251
+ success = false;
252
+ errors.push({
253
+ action: "drop",
254
+ node: stack.at(-1),
255
+ message: `expected <mf-lt> at ${stack.at(-1)?.loc?.src}:${stack.at(-1)?.loc?.sta.lin}:${stack.at(-1)?.loc?.sta.col}`,
256
+ });
257
+ break;
258
+ }
259
+ else if (!mFGT.has(stack.at(-1)?.typ) && mFGT.has(prevToken?.typ)) {
260
+ success = false;
261
+ errors.push({
262
+ action: "drop",
263
+ node: stream[i],
264
+ message: `expected <mf-gt> at ${stack.at(-1)?.loc?.src}:${stack.at(-1)?.loc?.sta.lin}:${stack.at(-1)?.loc?.sta.col}`,
265
+ });
266
+ break;
267
+ }
268
+ // const index: number = tokens.indexOf(stack.at(-1)!);
269
+ // <mf-lt> | <mf-name>
270
+ const index2 = tokens.indexOf(prevToken);
271
+ // '('
272
+ const index3 = tokens.indexOf(stack.at(-3));
273
+ const left = trimArray(tokens.slice(index3 + 1, index2));
274
+ const right = trimArray(tokens.slice(index + 1, tokens.length - 1));
275
+ const names = trimArray(tokens.slice(index2 + 1, index));
276
+ const filteredNames = names.filter((n) => n.typ !== EnumToken.WhitespaceTokenType && n.typ !== EnumToken.CommentTokenType);
277
+ if (filteredNames.length !== 1 || filteredNames[0].typ !== EnumToken.IdenTokenType) {
278
+ success = false;
279
+ errors.push({
280
+ action: "drop",
281
+ node: stream[i],
282
+ message: `expected <mf-name>> at ${filteredNames[0]?.loc?.src}:${filteredNames[0]?.loc?.sta.lin}:${filteredNames[0]?.loc?.sta.col}`,
283
+ });
284
+ break;
285
+ }
286
+ const name = filteredNames[0].val;
287
+ const mfInfo = getMFInfo(name);
288
+ for (const val of [left, right]) {
289
+ if (options.computeCalcExpression) {
290
+ if (mfInfo == null ||
291
+ (mfInfo.type != MediaFeatureType.KeywordType &&
292
+ mfInfo.type != MediaFeatureType.StringType)) {
293
+ for (let l = 0; l < val.length; l++) {
294
+ if (val[l].typ === EnumToken.MathFunctionTokenType &&
295
+ val[l].val === "calc") {
296
+ const value = evaluate([val[l]]);
297
+ if (value.length == 1) {
298
+ if (mfInfo?.type === MediaFeatureType.RatioType) {
299
+ if (value[0].typ !== EnumToken.NumberTokenType ||
300
+ !(value[0].val
301
+ ?.typ === EnumToken.FractionTokenType)) {
302
+ continue;
303
+ }
304
+ }
305
+ Object.defineProperty(value[0], "loc", {
306
+ ...definedPropertySettings,
307
+ value: val[l].loc,
308
+ });
309
+ val[l] = value[0];
310
+ }
311
+ }
312
+ }
313
+ }
314
+ }
315
+ }
316
+ let isValidMFValue = isMFValue(name, left, true);
317
+ if (isValidMFValue.valid && !isValidMFValue.success) {
318
+ success = false;
319
+ errors.push({
320
+ action: "drop",
321
+ node: left[0] ?? prevToken,
322
+ message: `${isValidMFValue.isValueAllowed === false ? "invalid <mf-name>" : "expected <mf-value>"} at ${(left[0] ?? prevToken)?.loc?.src}:${(left[0] ?? prevToken)?.loc?.sta.lin}:${(left[0] ?? prevToken)?.loc?.sta.col}`,
323
+ });
324
+ break;
325
+ }
326
+ isValidMFValue = isMFValue(name, right, true);
327
+ if (isValidMFValue.valid && !isValidMFValue.success) {
328
+ success = false;
329
+ errors.push({
330
+ action: "drop",
331
+ node: right[0] ?? stream[i],
332
+ location: (right[0] ?? stream[i])?.loc,
333
+ message: `${isValidMFValue.isValueAllowed === false ? "invalid <mf-name>" : "expected <mf-value>"} at ${(right[0] ?? stream[i])?.loc?.src}:${(right[0] ?? stream[i])?.loc?.sta.lin}:${(left[0] ?? stream[i])?.loc?.sta.col}`,
334
+ });
335
+ break;
336
+ }
337
+ for (const val of [left, right]) {
338
+ if (mfInfo?.type === MediaFeatureType.RatioType) {
339
+ const filteredValues = val.filter((n) => n.typ !== EnumToken.WhitespaceTokenType &&
340
+ n.typ !== EnumToken.CommentTokenType);
341
+ if (filteredValues.length === 3) {
342
+ if (options.computeCalcExpression) {
343
+ const div = gcd(filteredValues[0].val, filteredValues[2].val);
344
+ if (div > 1) {
345
+ filteredValues[0].val =
346
+ filteredValues[0].val / div;
347
+ filteredValues[2].val =
348
+ filteredValues[2].val / div;
349
+ }
350
+ }
351
+ val.splice(0, val.length, ...filteredValues);
352
+ }
353
+ }
354
+ }
355
+ tokens.splice(index3 + 1, tokens.length - index3 - 2, Object.defineProperty({
356
+ typ: EnumToken.MediaRangeQueryTokenType,
357
+ l: left,
358
+ val: filteredNames,
359
+ op1: prevToken,
360
+ op2: stack.at(-1),
361
+ r: right,
362
+ }, "loc", {
363
+ ...definedPropertySettings,
364
+ value: { ...left[0].loc, end: right.at(-1).loc.end },
365
+ }));
366
+ stack.pop();
367
+ stack.pop();
368
+ }
369
+ else if (stack[stack.length - 2]?.typ !== EnumToken.StartParensTokenType) {
370
+ success = false;
371
+ errors.push({
372
+ action: "drop",
373
+ node: stream[i],
374
+ location: stream[i]?.loc,
375
+ message: `expected '(' at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
376
+ });
377
+ break;
378
+ }
379
+ }
380
+ if (mFGT.has(stack.at(-1)?.typ) ||
381
+ mFLT.has(stack.at(-1)?.typ) ||
382
+ stack.at(-1)?.typ === EnumToken.DelimTokenType ||
383
+ stack.at(-1)?.typ === EnumToken.ColonTokenType) {
384
+ if (stack[stack.length - 2]?.typ !== EnumToken.StartParensTokenType) {
385
+ success = false;
386
+ errors.push({
387
+ action: "drop",
388
+ node: stream[i],
389
+ location: stream[i]?.loc,
390
+ message: `expected '(' at ${(stack[stack.length - 2] ?? tokens[0])?.loc?.src}:${(stack[stack.length - 2] ?? tokens[0])?.loc?.sta.lin}:${(stack[stack.length - 2] ?? tokens[0])?.loc?.sta.col}`,
391
+ });
392
+ break;
393
+ }
394
+ const index2 = tokens.indexOf(stack.at(-1));
395
+ const index3 = tokens.indexOf(stack.at(-2));
396
+ let names = trimArray(tokens.slice(index3 + 1, index2));
397
+ let values = trimArray(tokens.slice(index2 + 1, tokens.length - 1));
398
+ let swapped = false;
399
+ if (stack.at(-1)?.typ !== EnumToken.ColonTokenType) {
400
+ const filteredNames = names.filter((n) => n.typ !== EnumToken.WhitespaceTokenType && n.typ !== EnumToken.CommentTokenType);
401
+ if (filteredNames.length !== 1 ||
402
+ (filteredNames[0].typ !== EnumToken.IdenTokenType &&
403
+ filteredNames[0].typ !== EnumToken.DashedIdenTokenType)) {
404
+ swapped = true;
405
+ }
406
+ }
407
+ const filteredNames = (swapped ? values : names).filter((n) => n.typ !== EnumToken.WhitespaceTokenType && n.typ !== EnumToken.CommentTokenType);
408
+ if (filteredNames.length !== 1 ||
409
+ (filteredNames[0].typ !== EnumToken.IdenTokenType &&
410
+ filteredNames[0].typ !== EnumToken.DashedIdenTokenType)) {
411
+ success = false;
412
+ errors.push({
413
+ action: "drop",
414
+ node: names[0] ?? stack.at(-1),
415
+ location: names[0]?.loc,
416
+ message: `expected <mf-name> at ${(names[0] ?? stack.at(-1))?.loc?.src}:${(names[0] ?? stack.at(-1))?.loc?.sta.lin}:${(names[0] ?? stack.at(-1))?.loc?.sta.col}`,
417
+ });
418
+ break;
419
+ }
420
+ const name = filteredNames[0].val;
421
+ if (!isMFName(name)) {
422
+ success = false;
423
+ errors.push({
424
+ action: "drop",
425
+ node: names[0] ?? stack.at(-1),
426
+ location: names[0]?.loc ?? stack.at(-1)?.loc,
427
+ message: `expected <mf-name> at ${names[0]?.loc?.src}:${names[0]?.loc?.sta.lin}:${names[0]?.loc?.sta.col}`,
428
+ });
429
+ break;
430
+ }
431
+ const mfInfo = getMFInfo(name);
432
+ if (options.computeCalcExpression) {
433
+ if (mfInfo == null ||
434
+ (mfInfo.type != MediaFeatureType.KeywordType &&
435
+ mfInfo.type != MediaFeatureType.StringType)) {
436
+ const val = swapped ? names : values;
437
+ for (let l = 0; l < val.length; l++) {
438
+ if (val[l].typ === EnumToken.MathFunctionTokenType &&
439
+ val[l].val === "calc") {
440
+ const value = evaluate([val[l]]);
441
+ if (value.length == 1) {
442
+ if (mfInfo?.type === MediaFeatureType.RatioType) {
443
+ if (value[0].typ !== EnumToken.NumberTokenType ||
444
+ !(value[0].val?.typ ===
445
+ EnumToken.FractionTokenType)) {
446
+ continue;
447
+ }
448
+ }
449
+ Object.defineProperty(value[0], "loc", {
450
+ ...definedPropertySettings,
451
+ value: val[l].loc,
452
+ });
453
+ val[l] = value[0];
454
+ }
455
+ }
456
+ }
457
+ }
458
+ }
459
+ const mfValue = isMFValue(name, swapped ? names : values, mFGT.has(stack.at(-1)?.typ) ||
460
+ mFLT.has(stack.at(-1)?.typ) ||
461
+ stack.at(-1)?.typ === EnumToken.DelimTokenType);
462
+ if (!mfValue.success) {
463
+ success = false;
464
+ const arr = swapped ? names : values;
465
+ errors.push({
466
+ action: "drop",
467
+ node: arr[0],
468
+ location: arr[0]?.loc,
469
+ message: `${mfValue.isValueAllowed === false ? "invalid <mf-name>" : "expected <mf-value>"} at ${arr[0]?.loc?.src}:${arr[0]?.loc?.sta.lin}:${arr[0]?.loc?.sta.col}`,
470
+ });
471
+ break;
472
+ }
473
+ if (mfInfo?.type === MediaFeatureType.RatioType) {
474
+ const val = swapped ? names : values;
475
+ const filteredValues = val.filter((n) => n.typ !== EnumToken.WhitespaceTokenType && n.typ !== EnumToken.CommentTokenType);
476
+ if (filteredValues.length === 3) {
477
+ if (options.computeCalcExpression) {
478
+ const div = gcd(filteredValues[0].val, filteredValues[2].val);
479
+ if (div > 1) {
480
+ filteredValues[0].val =
481
+ filteredValues[0].val / div;
482
+ filteredValues[2].val =
483
+ filteredValues[2].val / div;
484
+ }
485
+ }
486
+ val.splice(0, val.length, ...filteredValues);
487
+ }
488
+ }
489
+ tokens.splice(index3 + 1, tokens.length - index3 - 2, Object.defineProperty({
490
+ typ: EnumToken.MediaQueryConditionTokenType,
491
+ l: names,
492
+ op: stack.pop(),
493
+ r: values,
494
+ }, "loc", {
495
+ ...definedPropertySettings,
496
+ value: { ...names[0].loc, end: values.at(-1).loc.end },
497
+ }));
498
+ }
499
+ if (stack.length === 0) {
500
+ success = false;
501
+ errors.push({
502
+ action: "drop",
503
+ node: stream[i],
504
+ location: stream[i]?.loc,
505
+ message: `unmatched ')' at ${stream[i]?.loc?.src}:${stream[i]?.loc?.sta.lin}:${stream[i]?.loc?.sta.col}`,
506
+ });
507
+ break;
508
+ }
509
+ {
510
+ const index = tokens.indexOf(stack.at(-1));
511
+ tokens[index] = Object.defineProperty({
512
+ typ: EnumToken.ParensTokenType,
513
+ chi: tokens.slice(index + 1, tokens.length - 1),
514
+ }, "loc", {
515
+ ...definedPropertySettings,
516
+ value: { ...tokens[index].loc, end: stream[i].loc.end },
517
+ });
518
+ tokens.length = index + 1;
519
+ scopes.pop();
520
+ currentScope = scopes.at(-1);
521
+ stack.pop();
522
+ if (stack.at(-1)?.typ === EnumToken.NotTokenType ||
523
+ stack.at(-1)?.typ === EnumToken.OnlyTokenType) {
524
+ const index = tokens.indexOf(stack.at(-1));
525
+ const slice = trimArray(tokens.slice(index + 1));
526
+ tokens[index] = Object.defineProperty({
527
+ typ: EnumToken.MediaQueryUnaryFeatureTokenType,
528
+ l: stack.pop(),
529
+ r: slice,
530
+ }, "loc", {
531
+ ...definedPropertySettings,
532
+ value: { ...tokens[index].loc, end: slice.at(-1).loc.end },
533
+ });
534
+ tokens.length = index + 1;
535
+ }
536
+ if (stack.at(-1)?.typ === EnumToken.AndTokenType ||
537
+ stack.at(-1)?.typ === EnumToken.OrTokenType) {
538
+ const index = tokens.indexOf(stack.at(-1));
539
+ let l = index - 1;
540
+ while (l > 0 &&
541
+ (tokens[l].typ === EnumToken.WhitespaceTokenType ||
542
+ tokens[l].typ === EnumToken.CommentTokenType)) {
543
+ l--;
544
+ }
545
+ const left = trimArray(tokens.slice(l, index));
546
+ const right = trimArray(tokens.slice(index + 1));
547
+ tokens[l] = Object.defineProperty({
548
+ typ: EnumToken.MediaQueryConditionTokenType,
549
+ op: stack.pop(),
550
+ l: left,
551
+ r: right,
552
+ }, "loc", {
553
+ ...definedPropertySettings,
554
+ value: { ...left[0].loc, end: right.at(-1).loc.end },
555
+ });
556
+ tokens.length = l + 1;
557
+ expectAndOrComma = true;
558
+ }
559
+ }
560
+ break;
561
+ }
562
+ if (!success) {
563
+ break;
564
+ }
565
+ }
566
+ if (success && stack.length > 0) {
567
+ success = false;
568
+ errors.push({
569
+ action: "drop",
570
+ node: stack.at(-1),
571
+ location: stack.at(-1)?.loc,
572
+ message: `unmatched token '${EnumToken[stack.at(-1)?.typ]}' at ${stack.at(-1)?.loc?.src}:${stack.at(-1)?.loc?.sta.lin}:${stack.at(-1)?.loc?.sta.col}`,
573
+ });
574
+ }
575
+ if (!success) {
576
+ hasErrors = true;
577
+ parts.splice(parts.indexOf(stream), 1);
578
+ }
579
+ stream.length = 0;
580
+ stream.push(...trimArray(tokens));
581
+ }
582
+ }
583
+ stream.length = 0;
584
+ stream.push(...parts
585
+ .filter((p) => p.length > 0 && p[0].typ !== EnumToken.InvalidMediaQueryTokenType)
586
+ .reduce((acc, b) => {
587
+ if (acc.length > 0) {
588
+ acc.push({ typ: EnumToken.CommaTokenType });
589
+ }
590
+ acc.push(...b);
591
+ return acc;
592
+ }, []));
593
+ return {
594
+ success: !hasErrors ||
595
+ stream.filter((t) => t.typ !== EnumToken.WhitespaceTokenType &&
596
+ t.typ !== EnumToken.CommentTokenType &&
597
+ t.typ !== EnumToken.InvalidMediaQueryTokenType &&
598
+ t.typ !== EnumToken.CommaTokenType).length !== 0,
599
+ errors,
600
+ };
601
+ }
602
+
603
+ export { parseMediaqueryList };
@@ -0,0 +1,5 @@
1
+ import type { AstAtRule, AtRuleToken, ErrorDescription, ParserOptions, Token } from "../../../@types/index.d.ts";
2
+ export declare function parseAtRulePage(context: AstAtRule | AtRuleToken, stream: Token[], options: ParserOptions, errors: ErrorDescription[]): {
3
+ success: boolean;
4
+ errors: ErrorDescription[];
5
+ };
@@ -0,0 +1,28 @@
1
+ import { EnumToken } from '../../ast/types.js';
2
+ import { getSyntaxRule } from '../../validation/config.js';
3
+ import { matchAllSyntax, createValidationContext } from '../../validation/match.js';
4
+ import { trimSyntaxArray } from '../../validation/parser/parse.js';
5
+ import { ValidationSyntaxGroupEnum } from '../../validation/parser/typedef.js';
6
+
7
+ function parseAtRulePage(context, stream, options, errors) {
8
+ const syntaxRules = getSyntaxRule(ValidationSyntaxGroupEnum.AtRules, "@page");
9
+ const syntax = syntaxRules?.getPreludeRules?.()?.slice?.(1);
10
+ let validate = false;
11
+ for (const token of stream) {
12
+ if (token.typ !== EnumToken.WhitespaceTokenType && token.typ !== EnumToken.CommentTokenType) {
13
+ validate = true;
14
+ break;
15
+ }
16
+ }
17
+ if (!validate) {
18
+ return {
19
+ success: true,
20
+ errors,
21
+ };
22
+ }
23
+ const result = matchAllSyntax(trimSyntaxArray(syntax), createValidationContext(stream), options);
24
+ errors.push(...result.errors);
25
+ return { success: result.success, errors };
26
+ }
27
+
28
+ export { parseAtRulePage };
@@ -0,0 +1,5 @@
1
+ import type { Token, AstAtRule, ParserOptions, ErrorDescription, AtRuleToken } from "../../../@types/index.d.ts";
2
+ export declare function parseAtRuleSupportSyntax(stream: Token[], context: AstAtRule | AtRuleToken, options?: ParserOptions): {
3
+ success: boolean;
4
+ errors: ErrorDescription[];
5
+ };