@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
@@ -1,121 +1,217 @@
1
- import { isIdent, isPseudo } from '../../syntax/syntax.js';
2
1
  import { EnumToken } from '../../ast/types.js';
3
- import '../../ast/minify.js';
4
- import '../../ast/walk.js';
5
- import { getTokenType as getTokenType$1 } from '../../parser/parse.js';
6
- import '../../parser/tokenize.js';
7
- import '../../parser/utils/config.js';
8
- import '../../syntax/color/utils/constants.js';
9
- import '../../renderer/sourcemap/lib/encode.js';
2
+ import { isIdentStart, isIdent, parseDimension, isPseudo } from '../../syntax/syntax.js';
3
+ import { ValidationTokenEnum } from './typedef.js';
10
4
 
11
- var ValidationTokenEnum;
12
- (function (ValidationTokenEnum) {
13
- ValidationTokenEnum[ValidationTokenEnum["Root"] = 0] = "Root";
14
- ValidationTokenEnum[ValidationTokenEnum["Keyword"] = 1] = "Keyword";
15
- ValidationTokenEnum[ValidationTokenEnum["PropertyType"] = 2] = "PropertyType";
16
- ValidationTokenEnum[ValidationTokenEnum["DeclarationType"] = 3] = "DeclarationType";
17
- ValidationTokenEnum[ValidationTokenEnum["AtRule"] = 4] = "AtRule";
18
- ValidationTokenEnum[ValidationTokenEnum["ValidationFunctionDefinition"] = 5] = "ValidationFunctionDefinition";
19
- ValidationTokenEnum[ValidationTokenEnum["OpenBracket"] = 6] = "OpenBracket";
20
- ValidationTokenEnum[ValidationTokenEnum["CloseBracket"] = 7] = "CloseBracket";
21
- ValidationTokenEnum[ValidationTokenEnum["OpenParenthesis"] = 8] = "OpenParenthesis";
22
- ValidationTokenEnum[ValidationTokenEnum["CloseParenthesis"] = 9] = "CloseParenthesis";
23
- ValidationTokenEnum[ValidationTokenEnum["Comma"] = 10] = "Comma";
24
- ValidationTokenEnum[ValidationTokenEnum["Pipe"] = 11] = "Pipe";
25
- ValidationTokenEnum[ValidationTokenEnum["Column"] = 12] = "Column";
26
- ValidationTokenEnum[ValidationTokenEnum["Star"] = 13] = "Star";
27
- ValidationTokenEnum[ValidationTokenEnum["OpenCurlyBrace"] = 14] = "OpenCurlyBrace";
28
- ValidationTokenEnum[ValidationTokenEnum["CloseCurlyBrace"] = 15] = "CloseCurlyBrace";
29
- ValidationTokenEnum[ValidationTokenEnum["HashMark"] = 16] = "HashMark";
30
- ValidationTokenEnum[ValidationTokenEnum["QuestionMark"] = 17] = "QuestionMark";
31
- ValidationTokenEnum[ValidationTokenEnum["Function"] = 18] = "Function";
32
- ValidationTokenEnum[ValidationTokenEnum["Number"] = 19] = "Number";
33
- ValidationTokenEnum[ValidationTokenEnum["Whitespace"] = 20] = "Whitespace";
34
- ValidationTokenEnum[ValidationTokenEnum["Parenthesis"] = 21] = "Parenthesis";
35
- ValidationTokenEnum[ValidationTokenEnum["Bracket"] = 22] = "Bracket";
36
- ValidationTokenEnum[ValidationTokenEnum["Block"] = 23] = "Block";
37
- ValidationTokenEnum[ValidationTokenEnum["AtLeastOnce"] = 24] = "AtLeastOnce";
38
- ValidationTokenEnum[ValidationTokenEnum["Separator"] = 25] = "Separator";
39
- ValidationTokenEnum[ValidationTokenEnum["Exclamation"] = 26] = "Exclamation";
40
- ValidationTokenEnum[ValidationTokenEnum["Ampersand"] = 27] = "Ampersand";
41
- ValidationTokenEnum[ValidationTokenEnum["PipeToken"] = 28] = "PipeToken";
42
- ValidationTokenEnum[ValidationTokenEnum["ColumnToken"] = 29] = "ColumnToken";
43
- ValidationTokenEnum[ValidationTokenEnum["AmpersandToken"] = 30] = "AmpersandToken";
44
- ValidationTokenEnum[ValidationTokenEnum["Parens"] = 31] = "Parens";
45
- ValidationTokenEnum[ValidationTokenEnum["PseudoClassToken"] = 32] = "PseudoClassToken";
46
- ValidationTokenEnum[ValidationTokenEnum["PseudoClassFunctionToken"] = 33] = "PseudoClassFunctionToken";
47
- ValidationTokenEnum[ValidationTokenEnum["StringToken"] = 34] = "StringToken";
48
- ValidationTokenEnum[ValidationTokenEnum["AtRuleDefinition"] = 35] = "AtRuleDefinition";
49
- ValidationTokenEnum[ValidationTokenEnum["DeclarationNameToken"] = 36] = "DeclarationNameToken";
50
- ValidationTokenEnum[ValidationTokenEnum["DeclarationDefinitionToken"] = 37] = "DeclarationDefinitionToken";
51
- ValidationTokenEnum[ValidationTokenEnum["SemiColon"] = 38] = "SemiColon";
52
- ValidationTokenEnum[ValidationTokenEnum["Character"] = 39] = "Character";
53
- ValidationTokenEnum[ValidationTokenEnum["InfinityToken"] = 40] = "InfinityToken";
54
- })(ValidationTokenEnum || (ValidationTokenEnum = {}));
55
- var ValidationSyntaxGroupEnum;
56
- (function (ValidationSyntaxGroupEnum) {
57
- ValidationSyntaxGroupEnum["Declarations"] = "declarations";
58
- ValidationSyntaxGroupEnum["Functions"] = "functions";
59
- ValidationSyntaxGroupEnum["Syntaxes"] = "syntaxes";
60
- ValidationSyntaxGroupEnum["Selectors"] = "selectors";
61
- ValidationSyntaxGroupEnum["AtRules"] = "atRules";
62
- })(ValidationSyntaxGroupEnum || (ValidationSyntaxGroupEnum = {}));
63
- const skipped = [
64
- ValidationTokenEnum.Star,
65
- ValidationTokenEnum.HashMark,
66
- ValidationTokenEnum.AtLeastOnce,
67
- ValidationTokenEnum.Exclamation,
68
- ValidationTokenEnum.QuestionMark,
69
- ValidationTokenEnum.OpenCurlyBrace
70
- ];
71
5
  const objectProperties = {
72
6
  enumerable: false,
73
7
  writable: true,
74
- configurable: true
8
+ configurable: true,
75
9
  };
76
- function* tokenize(syntax, position = { ind: 0, lin: 1, col: 0 }, currentPosition = {
10
+ const SymbolsMapTokens = {
11
+ "&&": ValidationTokenEnum.Ampersand,
12
+ "|": ValidationTokenEnum.Pipe,
13
+ "† ": ValidationTokenEnum.DisallowWhitespace,
14
+ "||": ValidationTokenEnum.Column,
15
+ "*": ValidationTokenEnum.Star,
16
+ ",": ValidationTokenEnum.Comma,
17
+ "/": ValidationTokenEnum.Separator,
18
+ "+": ValidationTokenEnum.Plus,
19
+ ";": ValidationTokenEnum.SemiColon,
20
+ "(": ValidationTokenEnum.OpenParenthesis,
21
+ ")": ValidationTokenEnum.CloseParenthesis,
22
+ "[": ValidationTokenEnum.OpenBracket,
23
+ "]": ValidationTokenEnum.CloseBracket,
24
+ "{": ValidationTokenEnum.OpenCurlyBrace,
25
+ "}": ValidationTokenEnum.CloseCurlyBrace,
26
+ "?": ValidationTokenEnum.QuestionMark,
27
+ "!": ValidationTokenEnum.Exclamation,
28
+ "#": ValidationTokenEnum.HashMark,
29
+ "<": ValidationTokenEnum.LessThan,
30
+ ">": ValidationTokenEnum.GreaterThan,
31
+ " ": ValidationTokenEnum.Whitespace,
32
+ "\t": ValidationTokenEnum.Whitespace,
33
+ "\r": ValidationTokenEnum.Whitespace,
34
+ "\n": ValidationTokenEnum.Whitespace,
35
+ "\f": ValidationTokenEnum.Whitespace,
36
+ // '∞'
37
+ "\u221e": ValidationTokenEnum.InfinityToken,
38
+ };
39
+ const makeBinaryOp = new Map([
40
+ [ValidationTokenEnum.Column, ValidationTokenEnum.ColumnToken],
41
+ [ValidationTokenEnum.Ampersand, ValidationTokenEnum.AmpersandToken],
42
+ ]);
43
+ function move(position, chr) {
44
+ for (const c of chr) {
45
+ position.col++;
46
+ position.ind += c.length;
47
+ }
48
+ return position;
49
+ }
50
+ function getTokenType(token, position, currentPosition) {
51
+ const pos = { ...position };
52
+ Object.assign(position, currentPosition);
53
+ if (token === "<an+b>") {
54
+ return Object.defineProperty({
55
+ typ: ValidationTokenEnum.PropertyType,
56
+ val: token.slice(1, -1),
57
+ }, "pos", { ...objectProperties, value: pos });
58
+ }
59
+ if (token.charAt(0) == '"' || token.charAt(0) == "'") {
60
+ return Object.defineProperty({
61
+ typ: ValidationTokenEnum.StringToken,
62
+ val: token,
63
+ }, "pos", { ...objectProperties, value: pos });
64
+ }
65
+ if (token.match(/^\d+$/)) {
66
+ return Object.defineProperty({
67
+ typ: ValidationTokenEnum.Number,
68
+ val: Number(token),
69
+ }, "pos", { ...objectProperties, value: pos });
70
+ }
71
+ let dimension = parseDimension(token);
72
+ if (dimension) {
73
+ // @ts-expect-error
74
+ return Object.defineProperty({
75
+ typ: ValidationTokenEnum.Dimension,
76
+ unit: EnumToken[dimension.typ],
77
+ val: dimension.val,
78
+ unitText: dimension.unit,
79
+ }, "pos", { ...objectProperties, value: pos });
80
+ }
81
+ if (isPseudo(token)) {
82
+ return Object.defineProperty({
83
+ typ: ValidationTokenEnum.PseudoClassToken,
84
+ val: token,
85
+ }, "pos", { ...objectProperties, value: pos });
86
+ }
87
+ if (token.startsWith("@") && isIdent(token.slice(1))) {
88
+ return Object.defineProperty({
89
+ typ: ValidationTokenEnum.AtRule,
90
+ val: token.slice(1),
91
+ }, "pos", { ...objectProperties, value: pos });
92
+ }
93
+ return Object.defineProperty({
94
+ typ: ValidationTokenEnum.Keyword,
95
+ val: token,
96
+ }, "pos", { ...objectProperties, value: pos });
97
+ }
98
+ function trimSyntaxArray(tokens) {
99
+ while (tokens[0]?.typ === ValidationTokenEnum.Whitespace) {
100
+ tokens.shift();
101
+ }
102
+ while (tokens[tokens.length - 1]?.typ === ValidationTokenEnum.Whitespace) {
103
+ tokens.pop();
104
+ }
105
+ let i = 0;
106
+ for (; i < tokens.length; i++) {
107
+ if (tokens[i].typ === ValidationTokenEnum.Comma) {
108
+ if (i + 1 < tokens.length && tokens[i + 1].typ === ValidationTokenEnum.Whitespace) {
109
+ tokens.splice(i + 1, 1);
110
+ }
111
+ if (i > 0 && tokens[i - 1].typ === ValidationTokenEnum.Whitespace) {
112
+ tokens.splice(--i, 1);
113
+ }
114
+ }
115
+ }
116
+ return tokens;
117
+ }
118
+ function* tokenizeSyntax(syntax, position = {
119
+ ind: 0,
120
+ lin: 1,
121
+ col: 0,
122
+ }, currentPosition = {
77
123
  ind: -1,
78
124
  lin: 1,
79
- col: 0
125
+ col: 0,
80
126
  }) {
81
127
  let i = -1;
82
- let buffer = '';
128
+ let buffer = "";
129
+ let pos;
83
130
  while (++i < syntax.length) {
84
131
  let chr = syntax.charAt(i);
85
132
  move(currentPosition, chr);
86
- switch (chr) {
87
- case '∞':
88
- if (buffer.length > 0) {
89
- yield getTokenType(buffer, position, currentPosition);
133
+ if (chr === "<" && "an+b>" === syntax.slice(i + 1, i + 6)) {
134
+ if (buffer.length > 0) {
135
+ yield getTokenType(buffer, position, currentPosition);
136
+ buffer = "";
137
+ }
138
+ yield getTokenType("<an+b>", position, currentPosition);
139
+ move(currentPosition, "an+b>");
140
+ i += 5;
141
+ continue;
142
+ }
143
+ if (SymbolsMapTokens[chr + syntax.charAt(i + 1)] != null) {
144
+ chr += syntax.charAt(++i);
145
+ move(currentPosition, syntax.charAt(i));
146
+ pos = { ...position };
147
+ Object.assign(position, currentPosition);
148
+ if (buffer.length > 0) {
149
+ yield getTokenType(buffer, position, currentPosition);
150
+ buffer = "";
151
+ }
152
+ yield Object.defineProperty({
153
+ typ: SymbolsMapTokens[chr],
154
+ }, "pos", { ...objectProperties, value: pos });
155
+ continue;
156
+ }
157
+ if (chr === ":") {
158
+ if (syntax.charAt(i + 1) === ":") {
159
+ if (isIdentStart(syntax.charCodeAt(i + 2)) ||
160
+ (syntax.charAt(i + 2) === "-" && isIdentStart(syntax.charCodeAt(i + 3)))) {
161
+ buffer += chr + ":";
162
+ i++;
163
+ continue;
90
164
  }
91
- yield getTokenType(chr, position, currentPosition);
92
- buffer = '';
93
- break;
94
- case '\\':
165
+ }
166
+ if (isIdentStart(syntax.charCodeAt(i + 1)) ||
167
+ (syntax.charAt(i + 1) === "-" && isIdentStart(syntax.charCodeAt(i + 2)))) {
168
+ buffer += chr;
169
+ continue;
170
+ }
171
+ }
172
+ if (SymbolsMapTokens[chr] != null) {
173
+ if (SymbolsMapTokens[chr] === ValidationTokenEnum.Whitespace) {
174
+ let ch;
175
+ let k = i;
176
+ while ((ch = syntax.charAt(k + 1)) &&
177
+ ch in SymbolsMapTokens &&
178
+ SymbolsMapTokens[ch] === ValidationTokenEnum.Whitespace) {
179
+ k++;
180
+ }
181
+ if (k != i) {
182
+ move(currentPosition, syntax.slice(i + 1, k + 1));
183
+ i = k;
184
+ }
185
+ }
186
+ pos = { ...position };
187
+ Object.assign(position, currentPosition);
188
+ if (buffer.length > 0) {
189
+ yield getTokenType(buffer, position, currentPosition);
190
+ buffer = "";
191
+ }
192
+ yield Object.defineProperty({
193
+ typ: SymbolsMapTokens[chr],
194
+ }, "pos", { ...objectProperties, value: pos });
195
+ continue;
196
+ }
197
+ switch (chr) {
198
+ case "\\":
95
199
  if (buffer.length > 0) {
96
200
  yield getTokenType(buffer, position, currentPosition);
97
- buffer = '';
201
+ buffer = "";
98
202
  }
99
203
  buffer += chr;
100
204
  chr = syntax.charAt(++i);
101
205
  buffer += chr;
102
206
  move(currentPosition, chr);
103
207
  break;
104
- case ';':
105
- if (buffer.length > 0) {
106
- yield getTokenType(buffer, position, currentPosition);
107
- buffer = '';
108
- }
109
- yield getTokenType(chr, position, currentPosition);
110
- buffer = '';
111
- break;
112
- case ':':
208
+ case ":":
113
209
  if (isIdent(buffer)) {
114
210
  yield Object.defineProperty({
115
211
  typ: ValidationTokenEnum.DeclarationNameToken,
116
- val: buffer
117
- }, 'pos', { ...objectProperties, value: { ...position } });
118
- buffer = '';
212
+ val: buffer,
213
+ }, "pos", { ...objectProperties, value: { ...position } });
214
+ buffer = "";
119
215
  move(currentPosition, chr);
120
216
  break;
121
217
  }
@@ -125,92 +221,24 @@ function* tokenize(syntax, position = { ind: 0, lin: 1, col: 0 }, currentPositio
125
221
  case "'":
126
222
  if (buffer.length > 0) {
127
223
  yield getTokenType(buffer, position, currentPosition);
128
- buffer = '';
224
+ buffer = "";
129
225
  }
130
226
  buffer += chr;
131
227
  while (i + 1 < syntax.length) {
132
228
  chr = syntax.charAt(++i);
133
229
  buffer += chr;
134
- move(currentPosition, chr);
135
- if (chr == '\\') {
230
+ if (chr == "\\") {
136
231
  chr = syntax.charAt(++i);
137
232
  buffer += chr;
138
- move(currentPosition, chr);
139
233
  continue;
140
234
  }
141
235
  if (chr == buffer.charAt(0)) {
142
236
  break;
143
237
  }
144
238
  }
145
- // check for type "<property>" or "<'property'>"
146
- if (buffer.at(1) == '<' && buffer.at(-2) == '>') {
147
- yield Object.defineProperty({
148
- typ: ValidationTokenEnum.Character,
149
- val: chr
150
- }, 'pos', { ...objectProperties, value: { ...position } });
151
- position = { ...currentPosition };
152
- move(currentPosition, chr);
153
- buffer = buffer.slice(1, -1);
154
- yield* tokenize(buffer, position, currentPosition);
155
- yield Object.defineProperty({
156
- typ: ValidationTokenEnum.Character,
157
- val: chr
158
- }, 'pos', { ...objectProperties, value: { ...position } });
159
- position = { ...currentPosition };
160
- move(currentPosition, chr);
161
- buffer = '';
162
- break;
163
- }
164
239
  yield getTokenType(buffer, position, currentPosition);
165
- buffer = '';
166
- break;
167
- case '<':
168
- buffer += chr;
169
- while (i + 1 < syntax.length) {
170
- chr = syntax.charAt(++i);
171
- buffer += chr;
172
- move(currentPosition, chr);
173
- if (chr == '>') {
174
- break;
175
- }
176
- }
177
- yield getTokenType(buffer, position, currentPosition);
178
- buffer = '';
179
- break;
180
- case ' ':
181
- case '\t':
182
- case '\n':
183
- case '\r':
184
- case '\f':
185
- case '|':
186
- case '#':
187
- case '+':
188
- case ',':
189
- case '[':
190
- case ']':
191
- case '(':
192
- case ')':
193
- case '*':
194
- case '{':
195
- case '}':
196
- case '?':
197
- case '!':
198
- case '&':
199
- if (buffer.length > 0) {
200
- yield getTokenType(buffer, position, currentPosition);
201
- }
202
- if (chr == '|' || chr == '&') {
203
- if (syntax.charAt(i + 1) == chr) {
204
- move(currentPosition, chr);
205
- yield getTokenType(chr + chr, position, currentPosition);
206
- i++;
207
- buffer = '';
208
- continue;
209
- }
210
- }
211
- Object.assign(position, currentPosition);
212
- yield getTokenType(chr, position, currentPosition);
213
- buffer = '';
240
+ move(currentPosition, buffer);
241
+ buffer = "";
214
242
  break;
215
243
  default:
216
244
  buffer += chr;
@@ -220,875 +248,596 @@ function* tokenize(syntax, position = { ind: 0, lin: 1, col: 0 }, currentPositio
220
248
  if (buffer.length > 0) {
221
249
  yield getTokenType(buffer, position, currentPosition);
222
250
  }
251
+ yield Object.defineProperty({
252
+ typ: ValidationTokenEnum.EOF,
253
+ }, "pos", { ...objectProperties, value: { ...position } });
223
254
  }
224
255
  function parseSyntax(syntax) {
225
- const root = Object.defineProperty({
226
- typ: ValidationTokenEnum.Root,
227
- chi: []
228
- }, 'pos', { ...objectProperties, value: { ind: 0, lin: 1, col: 0 } });
229
- return minify(doParseSyntax(syntax, tokenize(syntax), root));
230
- }
231
- function matchParens(syntax, iterator) {
232
- let item;
233
- let func = null;
234
- let items = [];
235
- let match = 0;
236
- while ((item = iterator.next()) && !item.done) {
237
- switch (item.value.typ) {
238
- case ValidationTokenEnum.OpenParenthesis:
239
- if (match > 0) {
240
- func.chi.push(item.value);
256
+ const stack = [];
257
+ let tokens = [];
258
+ let currentToken;
259
+ let startIndex;
260
+ let endIndex;
261
+ let iterator = tokenizeSyntax(syntax);
262
+ for (const token of iterator) {
263
+ tokens.push(token);
264
+ switch (token.typ) {
265
+ case ValidationTokenEnum.EOF:
266
+ if (stack.at(-1)?.typ == ValidationTokenEnum.PipeToken) {
267
+ let index = tokens.lastIndexOf(stack.at(-1));
268
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
269
+ stack.pop();
270
+ }
271
+ else if (stack.at(-1)?.typ == ValidationTokenEnum.AmpersandToken) {
272
+ let index = tokens.lastIndexOf(stack.at(-1));
273
+ stack.at(-1).r = trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2));
274
+ stack.pop();
275
+ }
276
+ else if (stack.at(-1)?.typ == ValidationTokenEnum.ColumnToken) {
277
+ let index = tokens.lastIndexOf(stack.at(-1));
278
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
279
+ stack.pop();
280
+ }
281
+ tokens.pop();
282
+ break;
283
+ case ValidationTokenEnum.Pipe:
284
+ {
285
+ while (stack.at(-1)?.typ == ValidationTokenEnum.AmpersandToken ||
286
+ stack.at(-1)?.typ == ValidationTokenEnum.ColumnToken) {
287
+ let index = tokens.lastIndexOf(stack.at(-1));
288
+ if (stack.at(-1)?.typ == ValidationTokenEnum.AmpersandToken) {
289
+ stack.at(-1).r = trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2));
290
+ }
291
+ else {
292
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
293
+ }
294
+ stack.pop();
295
+ }
296
+ let index = stack.length == 0 ? -1 : tokens.lastIndexOf(stack.at(-1));
297
+ if (stack.at(-1)?.typ != ValidationTokenEnum.PipeToken) {
298
+ stack.push(Object.assign(token, {
299
+ typ: ValidationTokenEnum.PipeToken,
300
+ chi: [trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2))],
301
+ }));
302
+ break;
303
+ }
304
+ tokens.pop();
305
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 1)));
241
306
  }
242
- else if (match == 0) {
243
- func = items.at(-1);
244
- if (func == null || func.val == null || func.val === '') {
245
- func = Object.defineProperty({
246
- typ: ValidationTokenEnum.Parens,
247
- val: '',
248
- chi: []
249
- }, 'pos', { ...objectProperties, value: item.value.pos });
250
- items.push(func);
307
+ break;
308
+ case ValidationTokenEnum.Ampersand:
309
+ {
310
+ let index = stack.length == 0 ? -1 : tokens.lastIndexOf(stack.at(-1));
311
+ if (stack.at(-1)?.typ === makeBinaryOp.get(token.typ)) {
312
+ if (token.typ === ValidationTokenEnum.Ampersand) {
313
+ stack.at(-1).r = trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2));
314
+ stack.pop();
315
+ stack.push(Object.assign(token, {
316
+ typ: makeBinaryOp.get(token.typ),
317
+ l: tokens.splice(index, 1),
318
+ r: [],
319
+ }));
320
+ }
321
+ else {
322
+ stack.at(-1).r = trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2));
323
+ stack.pop();
324
+ stack.push(Object.assign(token, {
325
+ typ: makeBinaryOp.get(token.typ),
326
+ l: tokens.splice(index, 1),
327
+ r: [],
328
+ }));
329
+ }
251
330
  }
252
331
  else {
253
- // @ts-ignore
254
- func.typ = func.typ == ValidationTokenEnum.PseudoClassToken ? ValidationTokenEnum.PseudoClassFunctionToken : ValidationTokenEnum.Function;
255
- func.chi = [];
332
+ stack.push(Object.assign(token, {
333
+ typ: makeBinaryOp.get(token.typ),
334
+ l: trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)),
335
+ r: [],
336
+ }));
256
337
  }
257
338
  }
258
- match++;
259
339
  break;
260
- case ValidationTokenEnum.CloseParenthesis:
261
- match--;
262
- if (match > 0) {
263
- func.chi.push(item.value);
340
+ case ValidationTokenEnum.Column:
341
+ {
342
+ let index = stack.length == 0 ? -1 : tokens.lastIndexOf(stack.at(-1));
343
+ if (stack.at(-1)?.typ === makeBinaryOp.get(token.typ)) {
344
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
345
+ tokens.pop();
346
+ }
347
+ else {
348
+ if (index != -1) {
349
+ stack.push(Object.assign(token, {
350
+ typ: makeBinaryOp.get(token.typ),
351
+ chi: [trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2))],
352
+ }));
353
+ }
354
+ else {
355
+ stack.push(Object.assign(token, {
356
+ typ: makeBinaryOp.get(token.typ),
357
+ chi: [trimSyntaxArray(tokens.splice(0, tokens.length - 2))],
358
+ }));
359
+ }
360
+ }
264
361
  }
265
362
  break;
266
- default:
267
- if (match > 0) {
268
- func.chi.push(item.value);
363
+ case ValidationTokenEnum.OpenParenthesis:
364
+ if (tokens.at(-2)?.typ == ValidationTokenEnum.Keyword) {
365
+ stack.push(Object.assign(tokens.at(-2), {
366
+ typ: ValidationTokenEnum.Function,
367
+ chi: [],
368
+ }));
369
+ tokens.pop();
370
+ break;
269
371
  }
270
- else {
271
- items.push(item.value);
372
+ if (tokens.at(-2)?.typ == ValidationTokenEnum.PseudoClassToken) {
373
+ stack.push(Object.assign(tokens.at(-2), {
374
+ typ: ValidationTokenEnum.PseudoClassFunctionToken,
375
+ chi: [],
376
+ }));
377
+ tokens.pop();
378
+ break;
272
379
  }
380
+ stack.push(token);
273
381
  break;
274
- }
275
- }
276
- for (const item of items) {
277
- if ('chi' in item) {
278
- // @ts-ignore
279
- item.chi = matchParens(syntax, item.chi[Symbol.iterator]());
280
- }
281
- }
282
- return items;
283
- }
284
- function matchBrackets(syntax, iterator) {
285
- let item;
286
- let bracket = null;
287
- let items = [];
288
- let match = 0;
289
- while ((item = iterator.next()) && !item.done) {
290
- switch (item.value.typ) {
291
- case ValidationTokenEnum.OpenBracket:
292
- if (match > 0) {
293
- bracket.chi.push(item.value);
294
- }
295
- else if (match == 0) {
296
- bracket = Object.defineProperty({
297
- typ: ValidationTokenEnum.Bracket,
298
- chi: []
299
- }, 'pos', { ...objectProperties, value: item.value.pos });
300
- items.push(bracket);
382
+ case ValidationTokenEnum.CloseParenthesis:
383
+ if (stack.at(-1)?.typ == ValidationTokenEnum.PipeToken) {
384
+ let index = tokens.lastIndexOf(stack.at(-1));
385
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
386
+ stack.pop();
387
+ }
388
+ if (stack.at(-1)?.typ == ValidationTokenEnum.OpenParenthesis ||
389
+ (stack.at(-1)?.typ == ValidationTokenEnum.PropertyType &&
390
+ stack.at(-1).val === "function-token")) {
391
+ stack.pop();
392
+ }
393
+ else if (stack.at(-1)?.typ === ValidationTokenEnum.PipeToken) {
394
+ let index = tokens.lastIndexOf(stack.at(-1));
395
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
396
+ stack.pop();
397
+ }
398
+ else if (stack.at(-1)?.typ === ValidationTokenEnum.AmpersandToken) {
399
+ let index = tokens.lastIndexOf(stack.at(-1));
400
+ stack.at(-1).r = trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2));
401
+ stack.pop();
402
+ }
403
+ if (stack.at(-1)?.typ === ValidationTokenEnum.Function ||
404
+ stack.at(-1)?.typ === ValidationTokenEnum.PseudoClassFunctionToken) {
405
+ let index = tokens.lastIndexOf(stack.at(-1));
406
+ tokens.pop();
407
+ stack.at(-1).chi =
408
+ trimSyntaxArray(tokens.splice(index + 1, tokens.length));
409
+ stack.pop();
301
410
  }
302
- match++;
303
411
  break;
304
- case ValidationTokenEnum.CloseBracket:
305
- match--;
306
- if (match > 0) {
307
- bracket.chi.push(item.value);
412
+ case ValidationTokenEnum.GreaterThan:
413
+ if (tokens[tokens.length - 3]?.typ === ValidationTokenEnum.LessThan) {
414
+ if (tokens[tokens.length - 2]?.typ === ValidationTokenEnum.Keyword) {
415
+ Object.assign(tokens[tokens.length - 3], {
416
+ typ: ValidationTokenEnum.PropertyType,
417
+ val: tokens[tokens.length - 2].val,
418
+ });
419
+ if ("range" in tokens[tokens.length - 2]) {
420
+ tokens[tokens.length - 3].range = tokens[tokens.length - 2].range;
421
+ }
422
+ tokens.splice(tokens.length - 2, 2);
423
+ if (tokens.at(-1).val == "function-token") {
424
+ // consume the closing ')'
425
+ stack.push(tokens.at(-1));
426
+ }
427
+ }
428
+ else if (tokens[tokens.length - 2]?.typ === ValidationTokenEnum.StringToken) {
429
+ Object.assign(tokens[tokens.length - 3], {
430
+ typ: ValidationTokenEnum.DeclarationType,
431
+ val: tokens[tokens.length - 2].val.slice(1, -1),
432
+ });
433
+ tokens.splice(tokens.length - 2, 2);
434
+ }
435
+ else if (tokens[tokens.length - 2]?.typ === ValidationTokenEnum.Function) {
436
+ Object.assign(tokens[tokens.length - 3], {
437
+ typ: ValidationTokenEnum.FunctionDefinition,
438
+ val: tokens[tokens.length - 2].val,
439
+ });
440
+ tokens.splice(tokens.length - 2, 2);
441
+ }
308
442
  }
309
443
  break;
310
- default:
311
- if (match > 0) {
312
- bracket.chi.push(item.value);
444
+ case ValidationTokenEnum.OpenBracket:
445
+ stack.push(token);
446
+ break;
447
+ case ValidationTokenEnum.CloseBracket:
448
+ while (true) {
449
+ if (stack.at(-1).typ == ValidationTokenEnum.AmpersandToken) {
450
+ let index = tokens.lastIndexOf(stack.at(-1));
451
+ stack.at(-1).r = trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2));
452
+ stack.pop();
453
+ continue;
454
+ }
455
+ else if (stack.at(-1).typ == ValidationTokenEnum.ColumnToken) {
456
+ let index = tokens.lastIndexOf(stack.at(-1));
457
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
458
+ stack.pop();
459
+ continue;
460
+ }
461
+ if (stack.at(-1).typ == ValidationTokenEnum.PipeToken) {
462
+ let index = tokens.lastIndexOf(stack.at(-1));
463
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
464
+ stack.pop();
465
+ continue;
466
+ }
467
+ break;
313
468
  }
314
- else {
315
- items.push(item.value);
469
+ currentToken = stack.at(-1);
470
+ if (currentToken?.typ !== ValidationTokenEnum.OpenBracket) {
471
+ console.debug(JSON.stringify(tokens, null, 1));
472
+ throw new SyntaxError(`Unexpected token: ']' at line ${token.pos.lin}:${token.pos.col} `);
473
+ }
474
+ {
475
+ let index = tokens.lastIndexOf(stack.at(-1));
476
+ // "fit-content( <length-percentage [0,∞]> )"
477
+ if ((tokens[index - 2]?.typ === ValidationTokenEnum.Keyword ||
478
+ tokens[index - 2]?.typ === ValidationTokenEnum.StringToken) &&
479
+ tokens[index - 1]?.typ === ValidationTokenEnum.Whitespace &&
480
+ (tokens[index + 1]?.typ === ValidationTokenEnum.Number ||
481
+ tokens[index + 1]?.typ === ValidationTokenEnum.Dimension)) {
482
+ if (tokens[index + 2]?.typ === ValidationTokenEnum.CloseBracket) {
483
+ stack.pop();
484
+ Object.assign(tokens[index - 2], {
485
+ range: {
486
+ min: tokens[index + 1],
487
+ max: tokens[index + 1],
488
+ },
489
+ });
490
+ tokens.splice(index - 1, 5);
491
+ break;
492
+ }
493
+ if (tokens[index + 2]?.typ === ValidationTokenEnum.Comma &&
494
+ (tokens[index + 3]?.typ === tokens[index + 1]?.typ ||
495
+ tokens[index + 3]?.typ === ValidationTokenEnum.InfinityToken) &&
496
+ tokens[index + 4]?.typ === ValidationTokenEnum.CloseBracket) {
497
+ stack.pop();
498
+ Object.assign(tokens[index - 2], {
499
+ range: {
500
+ min: tokens[index + 1],
501
+ max: tokens[index + 3]?.typ === tokens[index + 1]?.typ
502
+ ? tokens[index + 3]
503
+ : null,
504
+ },
505
+ });
506
+ tokens.splice(index - 1, 7);
507
+ break;
508
+ }
509
+ }
316
510
  }
511
+ stack.pop();
512
+ startIndex = tokens.lastIndexOf(currentToken);
513
+ endIndex = tokens.indexOf(token);
514
+ Object.assign(currentToken, {
515
+ typ: ValidationTokenEnum.Bracket,
516
+ chi: trimSyntaxArray(tokens.slice(startIndex + 1, endIndex)),
517
+ });
518
+ tokens.splice(startIndex + 1, tokens.length);
317
519
  break;
318
- }
319
- }
320
- for (const item of items) {
321
- if ('chi' in item) {
322
- // @ts-ignore
323
- item.chi = matchBrackets(syntax, item.chi[Symbol.iterator]());
324
- }
325
- }
326
- return items;
327
- }
328
- function matchCurlBraces(syntax, iterator) {
329
- let item;
330
- let block = null;
331
- let items = [];
332
- let match = 0;
333
- while ((item = iterator.next()) && !item.done) {
334
- switch (item.value.typ) {
520
+ // {
335
521
  case ValidationTokenEnum.OpenCurlyBrace:
336
- if (match > 0) {
337
- block.chi.push(item.value);
338
- }
339
- else if (match == 0) {
340
- block = Object.defineProperty({
341
- typ: ValidationTokenEnum.Block,
342
- chi: []
343
- }, 'pos', { ...objectProperties, value: item.value.pos });
344
- items.push(block);
345
- }
346
- match++;
522
+ stack.push(token);
347
523
  break;
524
+ // }
348
525
  case ValidationTokenEnum.CloseCurlyBrace:
349
- match--;
350
- if (match > 0) {
351
- block.chi.push(item.value);
352
- }
353
- break;
354
- default:
355
- if (match > 0) {
356
- block.chi.push(item.value);
357
- }
358
- else {
359
- items.push(item.value);
360
- }
361
- if ('chi' in item.value) {
362
- // @ts-ignore
363
- item.value.chi = matchCurlBraces(syntax, item.value.chi[Symbol.iterator]());
364
- }
365
- break;
366
- }
367
- }
368
- let it;
369
- let i = 0;
370
- for (; i < items.length; i++) {
371
- it = items[i];
372
- if (i > 0 && it.typ == ValidationTokenEnum.Block && it.chi[0]?.typ == ValidationTokenEnum.Number) {
373
- items[i - 1].occurence = {
374
- min: +it.chi[0].val,
375
- max: it.chi[2]?.typ == ValidationTokenEnum.InfinityToken ? Number.POSITIVE_INFINITY : +(it.chi[2] ?? it.chi[0]).val
376
- };
377
- items.splice(i--, 1);
378
- continue;
379
- }
380
- if ('chi' in it) {
381
- // @ts-ignore
382
- it.chi = matchBrackets(syntax, it.chi[Symbol.iterator]());
383
- }
384
- }
385
- return items;
386
- }
387
- function matchAtRule(syntax, iterator) {
388
- const children = [];
389
- let item;
390
- let token = null;
391
- while ((item = iterator.next()) && !item.done) {
392
- if (item.value.typ == ValidationTokenEnum.AtRule || item.value.typ == ValidationTokenEnum.AtRuleDefinition) {
393
- token = Object.defineProperty({
394
- ...item.value,
395
- typ: ValidationTokenEnum.AtRuleDefinition
396
- }, 'pos', { ...objectProperties, value: item.value.pos });
397
- children.push(token);
398
- item = iterator.next();
399
- if (item.done) {
400
- // @ts-ignore
401
- token.typ = ValidationTokenEnum.AtRule;
402
- break;
403
- }
404
- item = iterator.next();
405
- if (item.done) {
406
- break;
407
- }
408
- if (item.value.typ == ValidationTokenEnum.Pipe) {
409
- // @ts-ignore
410
- token.typ = ValidationTokenEnum.AtRule;
411
- children.push(item.value);
412
- continue;
413
- }
414
- if (item.value.typ != ValidationTokenEnum.OpenCurlyBrace) {
415
- if (!('prelude' in token)) {
416
- token.prelude = [];
417
- }
418
- token.prelude.push(item.value);
419
- }
420
- let braces = 0;
421
- let previousItem = item.value;
422
- while ((item = iterator.next()) && !item.done) {
423
- if (item.value.typ == ValidationTokenEnum.DeclarationNameToken) {
424
- iterator.next();
425
- const t = Object.defineProperty({
426
- typ: ValidationTokenEnum.DeclarationDefinitionToken,
427
- nam: item.value.val,
428
- val: iterator.next().value
429
- }, 'pos', {
430
- ...objectProperties,
431
- value: item.value.pos
432
- });
433
- if (braces > 0) {
434
- token.chi.push(t);
526
+ while (true) {
527
+ if (stack.at(-1).typ == ValidationTokenEnum.AmpersandToken) {
528
+ let index = tokens.lastIndexOf(stack.at(-1));
529
+ stack.at(-1).r = trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2));
530
+ stack.pop();
531
+ continue;
435
532
  }
436
- else {
437
- token.prelude.push(t);
533
+ else if (stack.at(-1).typ == ValidationTokenEnum.ColumnToken) {
534
+ let index = tokens.lastIndexOf(stack.at(-1));
535
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
536
+ stack.pop();
537
+ continue;
438
538
  }
439
- previousItem = t;
440
- continue;
441
- }
442
- if (item.value.typ == ValidationTokenEnum.OpenCurlyBrace) {
443
- previousItem = item.value;
444
- continue;
445
- }
446
- if (item.value.typ == ValidationTokenEnum.Whitespace && previousItem?.typ == ValidationTokenEnum.OpenCurlyBrace) {
447
- braces++;
448
- if (braces == 1) {
449
- previousItem = item.value;
539
+ if (stack.at(-1)?.typ == ValidationTokenEnum.PipeToken) {
540
+ let index = tokens.lastIndexOf(stack.at(-1));
541
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 2)));
542
+ stack.pop();
450
543
  continue;
451
544
  }
545
+ break;
452
546
  }
453
- if (previousItem?.typ == ValidationTokenEnum.Whitespace && item.value.typ == ValidationTokenEnum.CloseCurlyBrace) {
454
- braces--;
455
- if (braces == 0) {
456
- break;
547
+ if (stack.at(-1)?.typ != ValidationTokenEnum.OpenCurlyBrace) {
548
+ throw new SyntaxError(`Unexpected token } as ${token.pos.lin}:${token.pos.col}`);
549
+ }
550
+ {
551
+ let index = tokens.lastIndexOf(stack.at(-1));
552
+ const slice = tokens.slice(index + 1, -1);
553
+ if (slice.length === 1 || slice.length === 3) {
554
+ if (slice[0].typ == ValidationTokenEnum.Number) {
555
+ Object.assign(tokens[index - 1], {
556
+ match: {
557
+ min: slice[0],
558
+ max: slice[0],
559
+ },
560
+ });
561
+ if (slice.length === 3) {
562
+ if (slice[1].typ != ValidationTokenEnum.Comma) {
563
+ throw new SyntaxError(`Expecting ',' at ${slice[1].pos.lin}:${slice[1].pos.col}`);
564
+ }
565
+ if (slice[2].typ != ValidationTokenEnum.Number &&
566
+ slice[2].typ != ValidationTokenEnum.InfinityToken) {
567
+ throw new SyntaxError(`Expecting number or infinity at ${slice[2].pos.lin}:${slice[2].pos.col}`);
568
+ }
569
+ Object.assign(tokens[index - 1], {
570
+ match: {
571
+ min: slice[0],
572
+ max: slice[2].typ == ValidationTokenEnum.InfinityToken
573
+ ? Number.POSITIVE_INFINITY
574
+ : slice[2],
575
+ },
576
+ });
577
+ }
578
+ stack.pop();
579
+ tokens.length = index;
580
+ break;
581
+ }
457
582
  }
458
583
  }
459
- if (braces == 0) {
460
- if (!('prelude' in token)) {
461
- token.prelude = [];
584
+ stack.pop();
585
+ break;
586
+ case ValidationTokenEnum.Star:
587
+ tokens.pop();
588
+ tokens.at(-1).isRepeatable = true;
589
+ break;
590
+ case ValidationTokenEnum.QuestionMark:
591
+ tokens.pop();
592
+ // if the previous token is a comma, we wrap them in a virtual group and mark the group as optional
593
+ {
594
+ let sliceIndex = -1;
595
+ let isGroup = tokens.at(-2)?.typ == ValidationTokenEnum.Comma;
596
+ if (isGroup) {
597
+ sliceIndex = tokens.length - 2;
462
598
  }
463
- token.prelude.push(item.value);
464
- }
465
- else {
466
- if (!('chi' in token)) {
467
- token.chi = [];
599
+ else {
600
+ isGroup = tokens.at(-3)?.typ == ValidationTokenEnum.Comma;
601
+ if (isGroup) {
602
+ sliceIndex = tokens.length - 3;
603
+ }
468
604
  }
469
- token.chi.push(item.value);
470
- }
471
- previousItem = item.value;
472
- }
473
- if ('prelude' in token) {
474
- if (token?.prelude?.length == 1 && token.prelude[0].typ == ValidationTokenEnum.Whitespace) {
475
- delete token.prelude;
476
- }
477
- else {
478
- const t = { typ: ValidationTokenEnum.Root, chi: token.prelude };
479
- doParseSyntax(syntax, t.chi[Symbol.iterator](), t);
480
- token.prelude = t.chi;
481
- minify(token.prelude);
482
- }
483
- }
484
- // @ts-ignore
485
- if (token?.chi?.length > 0) {
486
- minify(doParseSyntax(syntax, token.chi[Symbol.iterator](), token));
487
- }
488
- }
489
- else {
490
- children.push(item.value);
491
- }
492
- }
493
- return children;
494
- }
495
- function matchToken(syntax, iterator, validationToken) {
496
- if (iterator.length == 0) {
497
- return [];
498
- }
499
- if (Array.isArray(iterator[0])) {
500
- const result = [];
501
- for (let i = 0; i < iterator.length; i++) {
502
- result.push(matchToken(syntax, iterator[i], validationToken));
503
- }
504
- return result;
505
- }
506
- let children = [];
507
- let token = null;
508
- let i;
509
- if (validationToken == ValidationTokenEnum.Ampersand) {
510
- // @ts-ignore
511
- children = [...iterator];
512
- let offsetL;
513
- let offsetR;
514
- for (i = 0; i < children.length; i++) {
515
- if (children[i].typ == ValidationTokenEnum.Ampersand) {
516
- offsetR = i + 1;
517
- offsetL = i - 1;
518
- while (offsetR < children.length - 1 && children[offsetR].typ == ValidationTokenEnum.Whitespace) {
519
- offsetR++;
520
- }
521
- while (offsetR + 1 < children.length && skipped.includes(children[offsetR + 1].typ)) {
522
- offsetR++;
523
- }
524
- while (offsetL > 0 && (children[offsetL].typ == ValidationTokenEnum.Whitespace || skipped.includes(children[offsetL].typ))) {
525
- offsetL--;
526
- }
527
- token = Object.defineProperty({
528
- typ: ValidationTokenEnum.AmpersandToken,
529
- l: children.slice(offsetL, i),
530
- r: children.slice(i + 1, offsetR + 1)
531
- }, 'pos', { ...objectProperties, value: children[i].pos });
532
- i = offsetL;
533
- children.splice(offsetL, offsetR - offsetL + 1, token);
534
- }
535
- else if ('chi' in children[i]) {
536
- // @ts-ignore
537
- children[i].chi = matchToken(syntax, children[i].chi, validationToken);
538
- }
539
- else if ('l' in children[i]) {
540
- // @ts-ignore
541
- children[i].l = matchToken(syntax, children[i].l, validationToken);
542
- // @ts-ignore
543
- children[i].r = matchToken(syntax, children[i].r, validationToken);
544
- }
545
- }
546
- return children;
547
- }
548
- let item;
549
- for (i = 0; i < iterator.length; i++) {
550
- item = iterator[i];
551
- if (item.typ == validationToken) {
552
- if (item.typ == ValidationTokenEnum.Pipe) {
553
- token = Object.defineProperty({
554
- typ: ValidationTokenEnum.PipeToken,
555
- chi: [matchToken(syntax, children.slice(), validationToken)], //.concat(matchToken(syntaxes, children.slice()[Symbol.iterator]() as Iterator<ValidationTokenIteratorValue>, validationToken), matchToken(syntaxes, iterator, validationToken)),
556
- // @ts-ignore
557
- // l: matchToken(syntaxes, children.slice()[Symbol.iterator](), validationToken),
558
- // r: matchToken(syntaxes, iterator, validationToken)
559
- }, 'pos', {
560
- ...objectProperties,
561
- value: item.pos
562
- });
563
- children.length = 0;
564
- while ((item = iterator[++i]) != null) {
565
- if (item.typ == ValidationTokenEnum.Pipe) {
566
- token.chi.push(matchToken(syntax, children.slice(), validationToken));
567
- children.length = 0;
605
+ if (isGroup) {
606
+ tokens.splice(sliceIndex, tokens.length - sliceIndex, {
607
+ typ: ValidationTokenEnum.OptionalGroupToken,
608
+ chi: trimSyntaxArray(tokens.slice(sliceIndex)),
609
+ isOptional: true,
610
+ });
568
611
  }
569
612
  else {
570
- children.push(item);
613
+ tokens.at(-1).isOptional = true;
571
614
  }
572
615
  }
573
- if (children.length > 0) {
574
- token.chi.push(matchToken(syntax, children.slice(), validationToken));
575
- }
576
- token.chi.sort((a, b) => {
577
- if (a.some((t) => t.isList)) {
578
- return -1;
579
- }
580
- if (b.some((t) => t.isList)) {
581
- return 1;
582
- }
583
- if (a.some((t) => t.occurence != null)) {
584
- return -1;
585
- }
586
- if (b.some((t) => t.occurence != null)) {
587
- return -1;
588
- }
589
- if (a.some((t) => t.isRepeatableGroup)) {
590
- return -1;
591
- }
592
- if (b.some((t) => t.isRepeatableGroup)) {
593
- return 1;
594
- }
595
- if (a.some((t) => t.isRepeatable)) {
596
- return -1;
597
- }
598
- if (b.some((t) => t.isRepeatable)) {
599
- return 1;
600
- }
601
- if (a.some((t) => t.isOptional)) {
602
- return 1;
603
- }
604
- if (b.some((t) => t.isOptional)) {
605
- return -1;
616
+ break;
617
+ case ValidationTokenEnum.Comma:
618
+ {
619
+ let sliceIndex = -1;
620
+ if (tokens.at(-2)?.isOptional && tokens.at(-2).typ !== ValidationTokenEnum.OptionalGroupToken) {
621
+ sliceIndex = tokens.length - 2;
606
622
  }
607
- return 0;
608
- });
609
- children = [token];
610
- }
611
- else {
612
- token = Object.defineProperty({
613
- typ: ValidationTokenEnum.ColumnToken,
614
- l: matchToken(syntax, children.slice(), validationToken),
615
- r: matchToken(syntax, iterator.slice(i + 1), validationToken)
616
- }, 'pos', {
617
- ...objectProperties,
618
- value: item.pos
619
- });
620
- i = iterator.length;
621
- }
622
- children.length = 0;
623
- children.push(token);
624
- while ((item = iterator[++i]) != null) {
625
- children.push(item);
626
- if ('chi' in item) {
627
- // @ts-ignore
628
- item.chi = matchToken(syntax, item.chi, validationToken);
629
- }
630
- else if ('l' in item) {
631
- // @ts-ignore
632
- item.l = matchToken(syntax, item.l, validationToken);
633
- // @ts-ignore
634
- item.r = matchToken(syntax, item.r, validationToken);
635
- }
636
- }
637
- // @ts-ignore
638
- return children;
639
- }
640
- else {
641
- // @ts-ignore
642
- children.push(item);
643
- if ('chi' in item) {
644
- // @ts-ignore
645
- item.chi = matchToken(syntax, item.chi, validationToken);
646
- }
647
- else if ('l' in item) {
648
- item.l = matchToken(syntax, item.l, validationToken);
649
- // @ts-ignore
650
- item.r = matchToken(syntax, item.r, validationToken);
651
- }
652
- }
653
- }
654
- return children;
655
- }
656
- function parseSyntaxTokens(syntax, iterator) {
657
- const items = [];
658
- let item;
659
- let i;
660
- while ((item = iterator.next()) && !item.done) {
661
- if (Array.isArray(item.value)) {
662
- // @ts-ignore
663
- item.value = parseSyntaxTokens(syntax, item.value[Symbol.iterator]());
664
- }
665
- switch (item.value.typ) {
666
- case ValidationTokenEnum.Star:
667
- case ValidationTokenEnum.HashMark:
668
- case ValidationTokenEnum.AtLeastOnce:
669
- case ValidationTokenEnum.Exclamation:
670
- case ValidationTokenEnum.QuestionMark:
671
- case ValidationTokenEnum.OpenCurlyBrace:
672
- i = items.length;
673
- while (i--) {
674
- if (items[i].typ != ValidationTokenEnum.Whitespace) {
675
- break;
623
+ else if (tokens.at(-2).typ == ValidationTokenEnum.Whitespace &&
624
+ tokens.at(-3)?.isOptional &&
625
+ tokens.at(-3).typ !== ValidationTokenEnum.OptionalGroupToken) {
626
+ sliceIndex = tokens.length - 3;
676
627
  }
677
- }
678
- if (item.value.typ == ValidationTokenEnum.Exclamation) {
679
- items[i].isRepeatableGroup = true;
680
- }
681
- else if (item.value.typ == ValidationTokenEnum.QuestionMark) {
682
- items[i].isOptional = true;
683
- }
684
- else if (item.value.typ == ValidationTokenEnum.Star) {
685
- items[i].isRepeatable = true;
686
- }
687
- else if (item.value.typ == ValidationTokenEnum.AtLeastOnce) {
688
- items[i].atLeastOnce = true;
689
- }
690
- else if (item.value.typ == ValidationTokenEnum.HashMark) {
691
- items[i].isList = true;
692
- }
693
- else if (item.value.typ == ValidationTokenEnum.OpenCurlyBrace) {
694
- items[i].occurence = {
695
- min: 0,
696
- max: null
697
- };
698
- while ((item = iterator.next()) && !item.done) {
699
- if (item.value.typ == ValidationTokenEnum.Number) {
700
- // @ts-ignore
701
- if (items[i].occurence.min == 0) {
702
- // @ts-ignore
703
- items[i].occurence.min = items[i].occurence.max = +item.value.val;
704
- }
705
- else {
706
- // @ts-ignore
707
- items[i].occurence.max = +item.value.val;
708
- }
709
- }
710
- if (item.value.typ == ValidationTokenEnum.CloseCurlyBrace) {
711
- break;
628
+ if (sliceIndex != -1) {
629
+ if (tokens[sliceIndex].isList) {
630
+ tokens.pop();
712
631
  }
632
+ tokens.splice(sliceIndex, tokens.length - sliceIndex, {
633
+ typ: ValidationTokenEnum.OptionalGroupToken,
634
+ chi: trimSyntaxArray(tokens.slice(sliceIndex).map((t) => {
635
+ delete t.isOptional;
636
+ return t;
637
+ })),
638
+ isOptional: true,
639
+ });
713
640
  }
714
641
  }
715
- if ('occurence' in item.value) {
716
- // @ts-ignore
717
- items[i].occurence = { ...item.value.occurence };
718
- }
719
642
  break;
720
- case ValidationTokenEnum.Pipe:
721
- item.value.chi = item.value.chi.map((t) => parseSyntaxTokens(syntax, t[Symbol.iterator]()));
722
- items.push(item.value);
643
+ case ValidationTokenEnum.HashMark:
644
+ tokens.pop();
645
+ tokens.at(-1).isList = true;
723
646
  break;
724
- default:
725
- items.push(item.value);
647
+ case ValidationTokenEnum.Exclamation:
648
+ tokens.pop();
649
+ tokens.at(-1).isMandatatoryGroup = true;
726
650
  break;
727
- }
728
- }
729
- for (i = 0; i < items.length; i++) {
730
- if ('chi' in items[i]) {
731
- // @ts-ignore
732
- items[i].chi = parseSyntaxTokens(syntax, items[i].chi[Symbol.iterator]());
733
- }
734
- else if ('l' in items[i]) {
735
- // @ts-ignore
736
- items[i].l = parseSyntaxTokens(syntax, items[i].l[Symbol.iterator]());
737
- // @ts-ignore
738
- items[i].r = parseSyntaxTokens(syntax, items[i].r[Symbol.iterator]());
739
- }
740
- if (items[i].typ != ValidationTokenEnum.Bracket && (items[i].isOptional || items[i].isRepeatable)) {
741
- let k = i;
742
- while (--k > 0) {
743
- if (items[k].typ == ValidationTokenEnum.Whitespace) {
744
- continue;
745
- }
746
- if (items[k].typ == ValidationTokenEnum.Comma) {
747
- const wrapper = Object.defineProperty({
748
- typ: ValidationTokenEnum.Bracket,
749
- chi: items.slice(k, i + 1)
750
- }, 'pos', { ...objectProperties, value: items[k].pos });
751
- if (items[i].isOptional) {
752
- wrapper.isOptional = true;
753
- delete items[i].isOptional;
754
- }
755
- if (items[i].isRepeatable) {
756
- wrapper.isRepeatable = true;
757
- delete items[i].isRepeatable;
758
- }
759
- items.splice(k, i - k + 1, wrapper);
760
- i = k - 1;
761
- }
651
+ case ValidationTokenEnum.Plus:
652
+ tokens.pop();
653
+ tokens.at(-1).isRepeatableAtLeastOnce = true;
762
654
  break;
763
- }
764
- // }
765
655
  }
766
656
  }
767
- return items;
768
- }
769
- function doParseSyntax(syntax, iterator, context) {
770
- context.chi = matchParens(syntax, iterator);
771
- // @ts-ignore
772
- context.chi = matchAtRule(syntax, context.chi[Symbol.iterator]());
773
- // @ts-ignore
774
- context.chi = matchBrackets(syntax, context.chi[Symbol.iterator]());
775
- // @ts-ignore
776
- context.chi = matchCurlBraces(syntax, context.chi[Symbol.iterator]());
777
- // @ts-ignore
778
- context.chi = matchToken(syntax, context.chi, ValidationTokenEnum.Pipe);
779
- // @ts-ignore
780
- context.chi = matchToken(syntax, context.chi, ValidationTokenEnum.Column);
781
- // @ts-ignore
782
- context.chi = matchToken(syntax, context.chi, ValidationTokenEnum.Ampersand);
783
- // @ts-ignore
784
- context.chi = parseSyntaxTokens(syntax, context.chi[Symbol.iterator]());
785
- return context;
786
- }
787
- function getTokenType(token, position, currentPosition) {
788
- const pos = { ...position };
789
- Object.assign(position, currentPosition);
790
- // '∞'
791
- if (token == '\u221e') {
792
- return Object.defineProperty({
793
- typ: ValidationTokenEnum.InfinityToken,
794
- }, 'pos', { ...objectProperties, value: pos });
795
- }
796
- if (token.charAt(0) == '"' || token.charAt(0) == "'") {
797
- return Object.defineProperty({
798
- typ: ValidationTokenEnum.StringToken,
799
- val: token
800
- }, 'pos', { ...objectProperties, value: pos });
801
- }
802
- if (token == ';') {
803
- return Object.defineProperty({
804
- typ: ValidationTokenEnum.SemiColon
805
- }, 'pos', { ...objectProperties, value: pos });
806
- }
807
- if (token.match(/^\s+$/)) {
808
- return Object.defineProperty({
809
- typ: ValidationTokenEnum.Whitespace,
810
- }, 'pos', { ...objectProperties, value: pos });
811
- }
812
- if (token.match(/^\d+$/)) {
813
- return Object.defineProperty({
814
- typ: ValidationTokenEnum.Number,
815
- val: Number(token)
816
- }, 'pos', { ...objectProperties, value: pos });
817
- }
818
- if (isPseudo(token)) {
819
- return Object.defineProperty({
820
- typ: ValidationTokenEnum.PseudoClassToken,
821
- val: token
822
- }, 'pos', { ...objectProperties, value: pos });
823
- }
824
- if (token == '!') {
825
- return Object.defineProperty({
826
- typ: ValidationTokenEnum.Exclamation
827
- }, 'pos', { ...objectProperties, value: pos });
828
- }
829
- if (token == '#') {
830
- return Object.defineProperty({
831
- typ: ValidationTokenEnum.HashMark
832
- }, 'pos', { ...objectProperties, value: pos });
833
- }
834
- if (token == '/') {
835
- return Object.defineProperty({
836
- typ: ValidationTokenEnum.Separator
837
- }, 'pos', { ...objectProperties, value: pos });
838
- }
839
- if (token == '+') {
840
- return Object.defineProperty({
841
- typ: ValidationTokenEnum.AtLeastOnce
842
- }, 'pos', { ...objectProperties, value: pos });
843
- }
844
- if (token == '|') {
845
- return Object.defineProperty({
846
- typ: ValidationTokenEnum.Pipe
847
- }, 'pos', { ...objectProperties, value: pos });
848
- }
849
- if (token == '&&') {
850
- return Object.defineProperty({
851
- typ: ValidationTokenEnum.Ampersand
852
- }, 'pos', { ...objectProperties, value: pos });
853
- }
854
- if (token == '||') {
855
- return Object.defineProperty({
856
- typ: ValidationTokenEnum.Column
857
- }, 'pos', { ...objectProperties, value: pos });
858
- }
859
- if (token == ',') {
860
- return Object.defineProperty({
861
- typ: ValidationTokenEnum.Comma
862
- }, 'pos', { ...objectProperties, value: pos });
863
- }
864
- if (token == '[') {
865
- return Object.defineProperty({
866
- typ: ValidationTokenEnum.OpenBracket
867
- }, 'pos', { ...objectProperties, value: pos });
868
- }
869
- if (token == ']') {
870
- return Object.defineProperty({
871
- typ: ValidationTokenEnum.CloseBracket
872
- }, 'pos', { ...objectProperties, value: pos });
873
- }
874
- if (token == '(') {
875
- return Object.defineProperty({
876
- typ: ValidationTokenEnum.OpenParenthesis
877
- }, 'pos', { ...objectProperties, value: pos });
878
- }
879
- if (token == ')') {
880
- return Object.defineProperty({
881
- typ: ValidationTokenEnum.CloseParenthesis
882
- }, 'pos', { ...objectProperties, value: pos });
883
- }
884
- if (token == '{') {
885
- return Object.defineProperty({
886
- typ: ValidationTokenEnum.OpenCurlyBrace
887
- }, 'pos', { ...objectProperties, value: pos });
888
- }
889
- if (token == '}') {
890
- return Object.defineProperty({
891
- typ: ValidationTokenEnum.CloseCurlyBrace
892
- }, 'pos', { ...objectProperties, value: pos });
893
- }
894
- if (token == '*') {
895
- return Object.defineProperty({
896
- typ: ValidationTokenEnum.Star
897
- }, 'pos', { ...objectProperties, value: pos });
898
- }
899
- if (token == '?') {
900
- return Object.defineProperty({
901
- typ: ValidationTokenEnum.QuestionMark
902
- }, 'pos', { ...objectProperties, value: pos });
903
- }
904
- if (token.startsWith("<'")) {
905
- return Object.defineProperty({
906
- typ: ValidationTokenEnum.DeclarationType,
907
- val: token.slice(2, -2)
908
- }, 'pos', { ...objectProperties, value: pos });
909
- }
910
- if (token.startsWith('<')) {
911
- // <number [1,1000]>
912
- // <length [0,∞]>
913
- let match = token.match(/<([a-z0-9-]+)(\s+\[([0-9]+[a-zA-Z]*),(([0-9]+[a-zA-Z]*)|∞)\])?>/);
914
- if (match == null) {
915
- let match = token.match(/<([a-zA-Z0-9-]+)\(\)>/);
916
- if (match != null) {
917
- return Object.defineProperty({
918
- typ: ValidationTokenEnum.ValidationFunctionDefinition,
919
- val: match[1]
920
- }, 'pos', { ...objectProperties, value: pos });
921
- }
922
- throw new Error('invalid token at position: ' + position.lin + ':' + position.col + ' ' + token);
923
- }
924
- if (match[2] != null) {
925
- const type = getTokenType$1(match[3]);
926
- return Object.defineProperty({
927
- typ: ValidationTokenEnum.PropertyType,
928
- val: match[1],
929
- unit: EnumToken[type.typ],
930
- range: [+type.val, match[4] == '\u221e' ? null : +match[4]]
931
- }, 'pos', { ...objectProperties, value: pos });
657
+ if (stack.length > 0) {
658
+ if (stack.at(-1)?.typ == ValidationTokenEnum.PipeToken) {
659
+ let index = tokens.lastIndexOf(stack.at(-1));
660
+ stack.at(-1).chi.push(trimSyntaxArray(tokens.splice(index + 1, tokens.length - index - 1)));
661
+ stack.pop();
932
662
  }
933
- return Object.defineProperty({
934
- typ: ValidationTokenEnum.PropertyType,
935
- val: token.slice(1, -1)
936
- }, 'pos', { ...objectProperties, value: pos });
937
- }
938
- if (token.startsWith('@') && isIdent(token.slice(1))) {
939
- return Object.defineProperty({
940
- typ: ValidationTokenEnum.AtRule,
941
- val: token.slice(1)
942
- }, 'pos', { ...objectProperties, value: pos });
943
663
  }
944
- return Object.defineProperty({
945
- typ: ValidationTokenEnum.Keyword,
946
- val: token
947
- }, 'pos', { ...objectProperties, value: pos });
948
- }
949
- function move(position, chr) {
950
- for (const c of chr) {
951
- position.col++;
952
- position.ind += c.length;
664
+ if (stack.length > 0) {
665
+ throw new SyntaxError(`Unexpected token ${ValidationTokenEnum[stack.at(-1)?.typ]} at ${stack.at(-1)?.pos.lin}:${stack.at(-1)?.pos.col}`);
953
666
  }
954
- return position;
667
+ return trimSyntaxArray(tokens);
955
668
  }
956
- function renderSyntax(token, parent) {
957
- let glue;
669
+ function renderSyntax(token, options = { minify: true, indent: 1 }) {
670
+ options.indent ??= 1;
671
+ let glue = options.minify ? "" : " ".repeat(options.indent);
958
672
  switch (token.typ) {
959
673
  case ValidationTokenEnum.InfinityToken:
960
674
  // '∞'
961
- return '\u221e';
675
+ return "\u221e";
962
676
  case ValidationTokenEnum.Root:
963
- return token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '');
677
+ return token.chi.reduce((acc, curr) => acc + renderSyntax(curr, options), "");
964
678
  case ValidationTokenEnum.Whitespace:
965
- return ' ';
966
- case ValidationTokenEnum.ValidationFunctionDefinition:
967
- return '<' + token.val + '()>';
679
+ return " ";
680
+ case ValidationTokenEnum.FunctionDefinition:
681
+ return "<" + token.val + "()>";
968
682
  case ValidationTokenEnum.HashMark:
969
- return '#';
683
+ return "#";
684
+ case ValidationTokenEnum.Colon:
685
+ return ":";
970
686
  case ValidationTokenEnum.Pipe:
971
- return '|';
687
+ return `${glue}|${glue}`;
972
688
  case ValidationTokenEnum.Column:
973
- return '||';
689
+ return `${glue}||${glue}`;
974
690
  case ValidationTokenEnum.PipeToken:
975
- return token.chi.reduce((acc, curr) => acc + (acc.trim().length > 0 ? '|' : '') + curr.reduce((acc, curr) => acc + renderSyntax(curr), ''), '');
691
+ return token.chi.reduce((acc, curr) => acc +
692
+ (acc.trim().length > 0 ? `${glue}|${glue}` : "") +
693
+ curr.reduce((acc, curr) => acc + renderSyntax(curr, options), ""), "");
976
694
  case ValidationTokenEnum.ColumnToken:
695
+ glue = `${glue}||${glue}`;
696
+ return token.chi.reduce((acc, curr) => acc +
697
+ (acc.length > 0 ? glue : "") +
698
+ curr.reduce((acc, curr) => acc + renderSyntax(curr, options), ""), "");
977
699
  case ValidationTokenEnum.AmpersandToken:
978
- glue = token.typ == ValidationTokenEnum.ColumnToken ? '||' : '&&';
979
- return token.l.reduce((acc, curr) => acc + renderSyntax(curr), '') +
700
+ glue = `${glue}&&${glue}`;
701
+ return (token.l.reduce((acc, curr) => acc + renderSyntax(curr, options), "") +
980
702
  glue +
981
- token.r.reduce((acc, curr) => acc + renderSyntax(curr), '');
703
+ token.r.reduce((acc, curr) => acc + renderSyntax(curr, options), ""));
982
704
  case ValidationTokenEnum.Function:
983
705
  case ValidationTokenEnum.PseudoClassFunctionToken:
984
706
  case ValidationTokenEnum.Parens:
985
- return token.val + '(' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '') + ')' + renderAttributes(token);
707
+ return (token.val +
708
+ "(" +
709
+ token.chi.reduce((acc, curr) => acc + renderSyntax(curr, options), "") +
710
+ ")" +
711
+ renderAttributes(token));
986
712
  case ValidationTokenEnum.Comma:
987
- return ',';
713
+ return `,${glue}`;
988
714
  case ValidationTokenEnum.Keyword:
989
715
  return token.val + renderAttributes(token);
990
716
  case ValidationTokenEnum.OpenBracket:
991
- return '[';
717
+ return `[${glue}`;
992
718
  case ValidationTokenEnum.Ampersand:
993
- return '&&';
719
+ return `${glue}&&${glue}`;
720
+ case ValidationTokenEnum.Plus:
721
+ return "+";
994
722
  case ValidationTokenEnum.QuestionMark:
995
- return '?';
723
+ return "?";
996
724
  case ValidationTokenEnum.Separator:
997
- return '/';
725
+ return "/";
998
726
  case ValidationTokenEnum.Bracket:
999
- return '[' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '') + ']' + renderAttributes(token);
727
+ return (`[${glue}` +
728
+ token.chi.reduce((acc, curr) => acc + renderSyntax(curr, options), "") +
729
+ `${glue}]` +
730
+ renderAttributes(token));
1000
731
  case ValidationTokenEnum.PropertyType:
1001
- return '<' + token.val + (Array.isArray(token.range) ? `[${token?.range?.[0]}, ${token?.range?.[1] ?? '\u221e'}]` : '') + '>' + renderAttributes(token);
1002
- case ValidationTokenEnum.DeclarationType:
1003
- return "<'" + token.val + "'>" + renderAttributes(token);
732
+ case ValidationTokenEnum.DeclarationType: {
733
+ const q = token.typ ===
734
+ ValidationTokenEnum.DeclarationType
735
+ ? "'"
736
+ : "";
737
+ return ("<" +
738
+ q +
739
+ token.val +
740
+ q +
741
+ (token.range == null
742
+ ? ""
743
+ : ` [${renderSyntax(token?.range.min)},${token?.range?.max == null
744
+ ? "\u221e"
745
+ : renderSyntax(token?.range.max)}]`) +
746
+ ">" +
747
+ renderAttributes(token));
748
+ }
1004
749
  case ValidationTokenEnum.Number:
1005
750
  case ValidationTokenEnum.PseudoClassToken:
1006
751
  case ValidationTokenEnum.StringToken:
1007
- return token.val + '';
752
+ return token.val + "";
1008
753
  case ValidationTokenEnum.SemiColon:
1009
- return ';';
754
+ return ";";
1010
755
  case ValidationTokenEnum.AtRule:
1011
- return '@' + token.val;
756
+ return "@" + token.val;
1012
757
  case ValidationTokenEnum.AtRuleDefinition:
1013
- return '@' + token.val +
1014
- (token.prelude == null ? '' : ' ' + token.prelude.reduce((acc, curr) => acc + renderSyntax(curr), '')) +
1015
- (token.chi == null ? '' : ' {\n' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '')).slice(1, -1) + '\n}';
758
+ return ("@" +
759
+ token.val +
760
+ (token.prelude == null
761
+ ? ""
762
+ : " " +
763
+ token.prelude.reduce((acc, curr) => acc + renderSyntax(curr, options), "")) +
764
+ (token.chi == null
765
+ ? ""
766
+ : " {\n" +
767
+ token.chi.reduce((acc, curr) => acc + renderSyntax(curr, options), "")).slice(1, -1) +
768
+ "\n}");
1016
769
  case ValidationTokenEnum.Block:
1017
- return '{' + token.chi.reduce((acc, t) => acc + renderSyntax(t), '') + '}';
770
+ return (`{${options.minify ? "" : "\n"}` +
771
+ token.chi.reduce((acc, t) => acc + renderSyntax(t, options), "") +
772
+ `${options.minify ? "" : "\n"}}`);
1018
773
  case ValidationTokenEnum.DeclarationDefinitionToken:
1019
- return token.nam + ': ' + renderSyntax(token.val);
774
+ return (token.nam +
775
+ ": " +
776
+ renderSyntax(token.val, options));
777
+ case ValidationTokenEnum.LessThan:
778
+ return "<";
779
+ case ValidationTokenEnum.GreaterThan:
780
+ return ">";
781
+ case ValidationTokenEnum.CloseParenthesis:
782
+ return ")";
783
+ case ValidationTokenEnum.OpenParenthesis:
784
+ return "(";
785
+ case ValidationTokenEnum.DisallowWhitespace:
786
+ return "† ";
787
+ case ValidationTokenEnum.Dimension:
788
+ return token.val + token.unitText;
789
+ case ValidationTokenEnum.OpenCurlyBrace:
790
+ options.indent++;
791
+ return `{${options.minify ? "" : "\n"}}`;
792
+ case ValidationTokenEnum.CloseCurlyBrace:
793
+ options.indent--;
794
+ return `${options.minify ? "" : "\n"}}`;
795
+ case ValidationTokenEnum.DeclarationNameToken:
796
+ return token.val + ":";
797
+ case ValidationTokenEnum.OptionalGroupToken:
798
+ return token.chi.reduce((acc, curr, index, array) => acc +
799
+ (index == array.length - 1
800
+ ? curr.typ === ValidationTokenEnum.Comma
801
+ ? "?,"
802
+ : renderSyntax(curr, options) + "?"
803
+ : renderSyntax(curr, options)), "");
1020
804
  default:
1021
- throw new Error('Unhandled token: ' + JSON.stringify({ token }, null, 1));
805
+ throw new Error("Unhandled token: " + JSON.stringify({ token }, null, 1));
1022
806
  }
1023
807
  }
1024
808
  function renderAttributes(token) {
1025
- let result = '';
809
+ let result = "";
1026
810
  if (token.isList) {
1027
- result += '#';
811
+ result += "#";
1028
812
  }
1029
813
  if (token.isOptional) {
1030
- result += '?';
814
+ result += "?";
1031
815
  }
1032
- if (token.isRepeatableGroup) {
1033
- result += '!';
816
+ if (token.isMandatatoryGroup) {
817
+ result += "!";
1034
818
  }
1035
819
  if (token.isRepeatable) {
1036
- result += '*';
820
+ result += "*";
1037
821
  }
1038
- if (token.atLeastOnce) {
1039
- result += '+';
822
+ if (token.isRepeatableAtLeastOnce) {
823
+ result += "+";
1040
824
  }
1041
- if (token.occurence != null) {
1042
- if (token.occurence.max == null || token.occurence.max == token.occurence.min || Number.isNaN(token.occurence.max)) {
1043
- result += '{' + token.occurence.min + '}';
825
+ if (token.match != null) {
826
+ if (token.match.max == null ||
827
+ token.match.max.val === token.match.min.val ||
828
+ Number.isNaN(token.match.max.val)) {
829
+ result += "{" + renderSyntax(token.match.min) + "}";
1044
830
  }
1045
831
  else {
1046
- result += '{' + token.occurence.min + ',' + (Number.isFinite(token.occurence.max) ? token.occurence.max : '\u221e') + '}';
832
+ result +=
833
+ "{" +
834
+ renderSyntax(token.match.min) +
835
+ "," +
836
+ (Number.isFinite(token.match.max.val) ? renderSyntax(token.match.max) : "\u221e") +
837
+ "}";
1047
838
  }
1048
839
  }
1049
840
  return result;
1050
841
  }
1051
- function minify(ast) {
1052
- if (Array.isArray(ast)) {
1053
- // @ts-ignore
1054
- while (ast.length > 0 && ast[0].typ == ValidationTokenEnum.Whitespace) {
1055
- // @ts-ignore
1056
- ast.shift();
1057
- }
1058
- while (ast.length > 0 && ast.at(-1).typ == ValidationTokenEnum.Whitespace) {
1059
- ast.pop();
1060
- }
1061
- for (let i = 0; i < ast.length; i++) {
1062
- minify(ast[i]);
1063
- if (ast[i].typ == ValidationTokenEnum.Whitespace && ast[i + 1]?.typ == ValidationTokenEnum.Whitespace) {
1064
- ast.splice(i + 1, 1);
1065
- i--;
1066
- continue;
1067
- }
1068
- if (ast[i].typ == ValidationTokenEnum.Separator) {
1069
- if (ast[i + 1]?.typ == ValidationTokenEnum.Whitespace) {
1070
- ast.splice(i + 1, 1);
1071
- }
1072
- if (ast[i - 1]?.typ == ValidationTokenEnum.Whitespace) {
1073
- ast.splice(--i, 1);
1074
- }
1075
- }
1076
- }
1077
- return ast;
1078
- }
1079
- if ('l' in ast) {
1080
- minify(ast.l);
1081
- }
1082
- if ('r' in ast) {
1083
- minify(ast.r);
1084
- }
1085
- if ('chi' in ast) {
1086
- minify(ast.chi);
1087
- }
1088
- if ('prelude' in ast) {
1089
- minify(ast.prelude);
1090
- }
1091
- return ast;
1092
- }
1093
842
 
1094
- export { ValidationSyntaxGroupEnum, ValidationTokenEnum, parseSyntax, renderSyntax };
843
+ export { parseSyntax, renderSyntax, tokenizeSyntax, trimSyntaxArray };