@eslint/css-tree 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +194 -0
  3. package/cjs/convertor/create.cjs +32 -0
  4. package/cjs/convertor/index.cjs +8 -0
  5. package/cjs/data-patch.cjs +7 -0
  6. package/cjs/data.cjs +120 -0
  7. package/cjs/definition-syntax/SyntaxError.cjs +16 -0
  8. package/cjs/definition-syntax/generate.cjs +139 -0
  9. package/cjs/definition-syntax/index.cjs +13 -0
  10. package/cjs/definition-syntax/parse.cjs +556 -0
  11. package/cjs/definition-syntax/scanner.cjs +113 -0
  12. package/cjs/definition-syntax/walk.cjs +57 -0
  13. package/cjs/generator/create.cjs +102 -0
  14. package/cjs/generator/index.cjs +8 -0
  15. package/cjs/generator/sourceMap.cjs +96 -0
  16. package/cjs/generator/token-before.cjs +170 -0
  17. package/cjs/index.cjs +65 -0
  18. package/cjs/lexer/Lexer.cjs +517 -0
  19. package/cjs/lexer/error.cjs +128 -0
  20. package/cjs/lexer/generic-an-plus-b.cjs +235 -0
  21. package/cjs/lexer/generic-const.cjs +12 -0
  22. package/cjs/lexer/generic-urange.cjs +149 -0
  23. package/cjs/lexer/generic.cjs +589 -0
  24. package/cjs/lexer/index.cjs +7 -0
  25. package/cjs/lexer/match-graph.cjs +530 -0
  26. package/cjs/lexer/match.cjs +632 -0
  27. package/cjs/lexer/prepare-tokens.cjs +54 -0
  28. package/cjs/lexer/search.cjs +65 -0
  29. package/cjs/lexer/structure.cjs +173 -0
  30. package/cjs/lexer/trace.cjs +73 -0
  31. package/cjs/lexer/units.cjs +38 -0
  32. package/cjs/parser/SyntaxError.cjs +74 -0
  33. package/cjs/parser/create.cjs +378 -0
  34. package/cjs/parser/index.cjs +8 -0
  35. package/cjs/parser/parse-selector.cjs +8 -0
  36. package/cjs/parser/sequence.cjs +47 -0
  37. package/cjs/syntax/atrule/container.cjs +32 -0
  38. package/cjs/syntax/atrule/font-face.cjs +12 -0
  39. package/cjs/syntax/atrule/import.cjs +101 -0
  40. package/cjs/syntax/atrule/index.cjs +27 -0
  41. package/cjs/syntax/atrule/layer.cjs +16 -0
  42. package/cjs/syntax/atrule/media.cjs +16 -0
  43. package/cjs/syntax/atrule/nest.cjs +16 -0
  44. package/cjs/syntax/atrule/page.cjs +16 -0
  45. package/cjs/syntax/atrule/scope.cjs +16 -0
  46. package/cjs/syntax/atrule/starting-style.cjs +12 -0
  47. package/cjs/syntax/atrule/supports.cjs +16 -0
  48. package/cjs/syntax/config/generator.cjs +9 -0
  49. package/cjs/syntax/config/lexer.cjs +14 -0
  50. package/cjs/syntax/config/mix.cjs +126 -0
  51. package/cjs/syntax/config/parser-selector.cjs +19 -0
  52. package/cjs/syntax/config/parser.cjs +49 -0
  53. package/cjs/syntax/config/walker.cjs +9 -0
  54. package/cjs/syntax/create.cjs +58 -0
  55. package/cjs/syntax/function/expression.cjs +11 -0
  56. package/cjs/syntax/function/var.cjs +43 -0
  57. package/cjs/syntax/index.cjs +14 -0
  58. package/cjs/syntax/node/AnPlusB.cjs +293 -0
  59. package/cjs/syntax/node/Atrule.cjs +103 -0
  60. package/cjs/syntax/node/AtrulePrelude.cjs +52 -0
  61. package/cjs/syntax/node/AttributeSelector.cjs +148 -0
  62. package/cjs/syntax/node/Block.cjs +96 -0
  63. package/cjs/syntax/node/Brackets.cjs +38 -0
  64. package/cjs/syntax/node/CDC.cjs +26 -0
  65. package/cjs/syntax/node/CDO.cjs +26 -0
  66. package/cjs/syntax/node/ClassSelector.cjs +31 -0
  67. package/cjs/syntax/node/Combinator.cjs +61 -0
  68. package/cjs/syntax/node/Comment.cjs +40 -0
  69. package/cjs/syntax/node/Condition.cjs +120 -0
  70. package/cjs/syntax/node/Declaration.cjs +166 -0
  71. package/cjs/syntax/node/DeclarationList.cjs +62 -0
  72. package/cjs/syntax/node/Dimension.cjs +30 -0
  73. package/cjs/syntax/node/Feature.cjs +101 -0
  74. package/cjs/syntax/node/FeatureFunction.cjs +67 -0
  75. package/cjs/syntax/node/FeatureRange.cjs +133 -0
  76. package/cjs/syntax/node/Function.cjs +45 -0
  77. package/cjs/syntax/node/GeneralEnclosed.cjs +68 -0
  78. package/cjs/syntax/node/Hash.cjs +30 -0
  79. package/cjs/syntax/node/IdSelector.cjs +33 -0
  80. package/cjs/syntax/node/Identifier.cjs +25 -0
  81. package/cjs/syntax/node/Layer.cjs +35 -0
  82. package/cjs/syntax/node/LayerList.cjs +43 -0
  83. package/cjs/syntax/node/MediaQuery.cjs +100 -0
  84. package/cjs/syntax/node/MediaQueryList.cjs +41 -0
  85. package/cjs/syntax/node/NestingSelector.cjs +29 -0
  86. package/cjs/syntax/node/Nth.cjs +54 -0
  87. package/cjs/syntax/node/Number.cjs +25 -0
  88. package/cjs/syntax/node/Operator.cjs +28 -0
  89. package/cjs/syntax/node/Parentheses.cjs +38 -0
  90. package/cjs/syntax/node/Percentage.cjs +25 -0
  91. package/cjs/syntax/node/PseudoClassSelector.cjs +67 -0
  92. package/cjs/syntax/node/PseudoElementSelector.cjs +69 -0
  93. package/cjs/syntax/node/Ratio.cjs +71 -0
  94. package/cjs/syntax/node/Raw.cjs +48 -0
  95. package/cjs/syntax/node/Rule.cjs +58 -0
  96. package/cjs/syntax/node/Scope.cjs +69 -0
  97. package/cjs/syntax/node/Selector.cjs +38 -0
  98. package/cjs/syntax/node/SelectorList.cjs +43 -0
  99. package/cjs/syntax/node/String.cjs +26 -0
  100. package/cjs/syntax/node/StyleSheet.cjs +83 -0
  101. package/cjs/syntax/node/SupportsDeclaration.cjs +38 -0
  102. package/cjs/syntax/node/TypeSelector.cjs +59 -0
  103. package/cjs/syntax/node/UnicodeRange.cjs +158 -0
  104. package/cjs/syntax/node/Url.cjs +54 -0
  105. package/cjs/syntax/node/Value.cjs +26 -0
  106. package/cjs/syntax/node/WhiteSpace.cjs +34 -0
  107. package/cjs/syntax/node/index-generate.cjs +103 -0
  108. package/cjs/syntax/node/index-parse-selector.cjs +39 -0
  109. package/cjs/syntax/node/index-parse.cjs +103 -0
  110. package/cjs/syntax/node/index.cjs +103 -0
  111. package/cjs/syntax/pseudo/index.cjs +60 -0
  112. package/cjs/syntax/pseudo/lang.cjs +37 -0
  113. package/cjs/syntax/scope/atrulePrelude.cjs +9 -0
  114. package/cjs/syntax/scope/default.cjs +76 -0
  115. package/cjs/syntax/scope/index.cjs +11 -0
  116. package/cjs/syntax/scope/selector.cjs +88 -0
  117. package/cjs/syntax/scope/value.cjs +29 -0
  118. package/cjs/tokenizer/OffsetToLocation.cjs +91 -0
  119. package/cjs/tokenizer/TokenStream.cjs +358 -0
  120. package/cjs/tokenizer/adopt-buffer.cjs +13 -0
  121. package/cjs/tokenizer/char-code-definitions.cjs +236 -0
  122. package/cjs/tokenizer/index.cjs +554 -0
  123. package/cjs/tokenizer/names.cjs +32 -0
  124. package/cjs/tokenizer/types.cjs +57 -0
  125. package/cjs/tokenizer/utils.cjs +261 -0
  126. package/cjs/utils/List.cjs +473 -0
  127. package/cjs/utils/clone.cjs +25 -0
  128. package/cjs/utils/create-custom-error.cjs +18 -0
  129. package/cjs/utils/ident.cjs +102 -0
  130. package/cjs/utils/index.cjs +20 -0
  131. package/cjs/utils/names.cjs +113 -0
  132. package/cjs/utils/string.cjs +99 -0
  133. package/cjs/utils/url.cjs +108 -0
  134. package/cjs/version.cjs +5 -0
  135. package/cjs/walker/create.cjs +291 -0
  136. package/cjs/walker/index.cjs +8 -0
  137. package/data/patch.json +874 -0
  138. package/dist/csstree.esm.js +12 -0
  139. package/dist/csstree.js +12 -0
  140. package/dist/data.cjs +1341 -0
  141. package/dist/data.js +1341 -0
  142. package/dist/version.cjs +1 -0
  143. package/dist/version.js +1 -0
  144. package/lib/convertor/create.js +28 -0
  145. package/lib/convertor/index.js +4 -0
  146. package/lib/data-patch.js +6 -0
  147. package/lib/data.js +118 -0
  148. package/lib/definition-syntax/SyntaxError.js +12 -0
  149. package/lib/definition-syntax/generate.js +135 -0
  150. package/lib/definition-syntax/index.js +4 -0
  151. package/lib/definition-syntax/parse.js +552 -0
  152. package/lib/definition-syntax/scanner.js +109 -0
  153. package/lib/definition-syntax/walk.js +53 -0
  154. package/lib/generator/create.js +97 -0
  155. package/lib/generator/index.js +4 -0
  156. package/lib/generator/sourceMap.js +92 -0
  157. package/lib/generator/token-before.js +182 -0
  158. package/lib/index.d.ts +3016 -0
  159. package/lib/index.js +30 -0
  160. package/lib/lexer/Lexer.js +511 -0
  161. package/lib/lexer/error.js +123 -0
  162. package/lib/lexer/generic-an-plus-b.js +238 -0
  163. package/lib/lexer/generic-const.js +8 -0
  164. package/lib/lexer/generic-urange.js +151 -0
  165. package/lib/lexer/generic.js +622 -0
  166. package/lib/lexer/index.js +1 -0
  167. package/lib/lexer/match-graph.js +527 -0
  168. package/lib/lexer/match.js +630 -0
  169. package/lib/lexer/prepare-tokens.js +50 -0
  170. package/lib/lexer/search.js +61 -0
  171. package/lib/lexer/structure.js +169 -0
  172. package/lib/lexer/trace.js +66 -0
  173. package/lib/lexer/units.js +27 -0
  174. package/lib/parser/SyntaxError.js +70 -0
  175. package/lib/parser/create.js +388 -0
  176. package/lib/parser/index.js +4 -0
  177. package/lib/parser/parse-selector.js +4 -0
  178. package/lib/parser/sequence.js +43 -0
  179. package/lib/syntax/atrule/container.js +28 -0
  180. package/lib/syntax/atrule/font-face.js +8 -0
  181. package/lib/syntax/atrule/import.js +104 -0
  182. package/lib/syntax/atrule/index.js +23 -0
  183. package/lib/syntax/atrule/layer.js +12 -0
  184. package/lib/syntax/atrule/media.js +12 -0
  185. package/lib/syntax/atrule/nest.js +12 -0
  186. package/lib/syntax/atrule/page.js +12 -0
  187. package/lib/syntax/atrule/scope.js +12 -0
  188. package/lib/syntax/atrule/starting-style.js +8 -0
  189. package/lib/syntax/atrule/supports.js +12 -0
  190. package/lib/syntax/config/generator.js +5 -0
  191. package/lib/syntax/config/lexer.js +10 -0
  192. package/lib/syntax/config/mix.js +122 -0
  193. package/lib/syntax/config/parser-selector.js +15 -0
  194. package/lib/syntax/config/parser.js +45 -0
  195. package/lib/syntax/config/walker.js +5 -0
  196. package/lib/syntax/create.js +55 -0
  197. package/lib/syntax/function/expression.js +7 -0
  198. package/lib/syntax/function/var.js +39 -0
  199. package/lib/syntax/index.js +10 -0
  200. package/lib/syntax/node/AnPlusB.js +292 -0
  201. package/lib/syntax/node/Atrule.js +100 -0
  202. package/lib/syntax/node/AtrulePrelude.js +47 -0
  203. package/lib/syntax/node/AttributeSelector.js +147 -0
  204. package/lib/syntax/node/Block.js +95 -0
  205. package/lib/syntax/node/Brackets.js +35 -0
  206. package/lib/syntax/node/CDC.js +19 -0
  207. package/lib/syntax/node/CDO.js +19 -0
  208. package/lib/syntax/node/ClassSelector.js +24 -0
  209. package/lib/syntax/node/Combinator.js +54 -0
  210. package/lib/syntax/node/Comment.js +33 -0
  211. package/lib/syntax/node/Condition.js +123 -0
  212. package/lib/syntax/node/Declaration.js +165 -0
  213. package/lib/syntax/node/DeclarationList.js +62 -0
  214. package/lib/syntax/node/Dimension.js +23 -0
  215. package/lib/syntax/node/Feature.js +103 -0
  216. package/lib/syntax/node/FeatureFunction.js +63 -0
  217. package/lib/syntax/node/FeatureRange.js +133 -0
  218. package/lib/syntax/node/Function.js +41 -0
  219. package/lib/syntax/node/GeneralEnclosed.js +66 -0
  220. package/lib/syntax/node/Hash.js +23 -0
  221. package/lib/syntax/node/IdSelector.js +26 -0
  222. package/lib/syntax/node/Identifier.js +18 -0
  223. package/lib/syntax/node/Layer.js +28 -0
  224. package/lib/syntax/node/LayerList.js +36 -0
  225. package/lib/syntax/node/MediaQuery.js +102 -0
  226. package/lib/syntax/node/MediaQueryList.js +34 -0
  227. package/lib/syntax/node/NestingSelector.js +22 -0
  228. package/lib/syntax/node/Nth.js +47 -0
  229. package/lib/syntax/node/Number.js +18 -0
  230. package/lib/syntax/node/Operator.js +21 -0
  231. package/lib/syntax/node/Parentheses.js +34 -0
  232. package/lib/syntax/node/Percentage.js +18 -0
  233. package/lib/syntax/node/PseudoClassSelector.js +65 -0
  234. package/lib/syntax/node/PseudoElementSelector.js +66 -0
  235. package/lib/syntax/node/Ratio.js +68 -0
  236. package/lib/syntax/node/Raw.js +41 -0
  237. package/lib/syntax/node/Rule.js +51 -0
  238. package/lib/syntax/node/Scope.js +66 -0
  239. package/lib/syntax/node/Selector.js +31 -0
  240. package/lib/syntax/node/SelectorList.js +35 -0
  241. package/lib/syntax/node/String.js +19 -0
  242. package/lib/syntax/node/StyleSheet.js +82 -0
  243. package/lib/syntax/node/SupportsDeclaration.js +34 -0
  244. package/lib/syntax/node/TypeSelector.js +52 -0
  245. package/lib/syntax/node/UnicodeRange.js +156 -0
  246. package/lib/syntax/node/Url.js +52 -0
  247. package/lib/syntax/node/Value.js +19 -0
  248. package/lib/syntax/node/WhiteSpace.js +27 -0
  249. package/lib/syntax/node/index-generate.js +49 -0
  250. package/lib/syntax/node/index-parse-selector.js +17 -0
  251. package/lib/syntax/node/index-parse.js +49 -0
  252. package/lib/syntax/node/index.js +49 -0
  253. package/lib/syntax/pseudo/index.js +56 -0
  254. package/lib/syntax/pseudo/lang.js +33 -0
  255. package/lib/syntax/scope/atrulePrelude.js +5 -0
  256. package/lib/syntax/scope/default.js +85 -0
  257. package/lib/syntax/scope/index.js +3 -0
  258. package/lib/syntax/scope/selector.js +94 -0
  259. package/lib/syntax/scope/value.js +25 -0
  260. package/lib/tokenizer/OffsetToLocation.js +87 -0
  261. package/lib/tokenizer/TokenStream.js +366 -0
  262. package/lib/tokenizer/adopt-buffer.js +9 -0
  263. package/lib/tokenizer/char-code-definitions.js +212 -0
  264. package/lib/tokenizer/index.js +513 -0
  265. package/lib/tokenizer/names.js +28 -0
  266. package/lib/tokenizer/types.js +28 -0
  267. package/lib/tokenizer/utils.js +254 -0
  268. package/lib/utils/List.js +469 -0
  269. package/lib/utils/clone.js +21 -0
  270. package/lib/utils/create-custom-error.js +14 -0
  271. package/lib/utils/ident.js +101 -0
  272. package/lib/utils/index.js +6 -0
  273. package/lib/utils/names.js +106 -0
  274. package/lib/utils/string.js +99 -0
  275. package/lib/utils/url.js +108 -0
  276. package/lib/version.js +5 -0
  277. package/lib/walker/create.js +287 -0
  278. package/lib/walker/index.js +4 -0
  279. package/package.json +133 -0
@@ -0,0 +1,622 @@
1
+ import { cssWideKeywords } from './generic-const.js';
2
+ import anPlusB from './generic-an-plus-b.js';
3
+ import urange from './generic-urange.js';
4
+ import {
5
+ isIdentifierStart,
6
+ isHexDigit,
7
+ isDigit,
8
+ cmpStr,
9
+ consumeNumber,
10
+
11
+ Ident,
12
+ Function as FunctionToken,
13
+ AtKeyword,
14
+ Hash,
15
+ String as StringToken,
16
+ BadString,
17
+ Url,
18
+ BadUrl,
19
+ Delim,
20
+ Number as NumberToken,
21
+ Percentage,
22
+ Dimension,
23
+ WhiteSpace,
24
+ CDO,
25
+ CDC,
26
+ Colon,
27
+ Semicolon,
28
+ Comma,
29
+ LeftSquareBracket,
30
+ RightSquareBracket,
31
+ LeftParenthesis,
32
+ RightParenthesis,
33
+ LeftCurlyBracket,
34
+ RightCurlyBracket
35
+ } from '../tokenizer/index.js';
36
+
37
+ const calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
38
+ const balancePair = new Map([
39
+ [FunctionToken, RightParenthesis],
40
+ [LeftParenthesis, RightParenthesis],
41
+ [LeftSquareBracket, RightSquareBracket],
42
+ [LeftCurlyBracket, RightCurlyBracket]
43
+ ]);
44
+
45
+ // safe char code getter
46
+ function charCodeAt(str, index) {
47
+ return index < str.length ? str.charCodeAt(index) : 0;
48
+ }
49
+
50
+ function eqStr(actual, expected) {
51
+ return cmpStr(actual, 0, actual.length, expected);
52
+ }
53
+
54
+ function eqStrAny(actual, expected) {
55
+ for (let i = 0; i < expected.length; i++) {
56
+ if (eqStr(actual, expected[i])) {
57
+ return true;
58
+ }
59
+ }
60
+
61
+ return false;
62
+ }
63
+
64
+ // IE postfix hack, i.e. 123\0 or 123px\9
65
+ function isPostfixIeHack(str, offset) {
66
+ if (offset !== str.length - 2) {
67
+ return false;
68
+ }
69
+
70
+ return (
71
+ charCodeAt(str, offset) === 0x005C && // U+005C REVERSE SOLIDUS (\)
72
+ isDigit(charCodeAt(str, offset + 1))
73
+ );
74
+ }
75
+
76
+ function outOfRange(opts, value, numEnd) {
77
+ if (opts && opts.type === 'Range') {
78
+ const num = Number(
79
+ numEnd !== undefined && numEnd !== value.length
80
+ ? value.substr(0, numEnd)
81
+ : value
82
+ );
83
+
84
+ if (isNaN(num)) {
85
+ return true;
86
+ }
87
+
88
+ // FIXME: when opts.min is a string it's a dimension, skip a range validation
89
+ // for now since it requires a type covertation which is not implmented yet
90
+ if (opts.min !== null && num < opts.min && typeof opts.min !== 'string') {
91
+ return true;
92
+ }
93
+
94
+ // FIXME: when opts.max is a string it's a dimension, skip a range validation
95
+ // for now since it requires a type covertation which is not implmented yet
96
+ if (opts.max !== null && num > opts.max && typeof opts.max !== 'string') {
97
+ return true;
98
+ }
99
+ }
100
+
101
+ return false;
102
+ }
103
+
104
+ function consumeFunction(token, getNextToken) {
105
+ let balanceCloseType = 0;
106
+ let balanceStash = [];
107
+ let length = 0;
108
+
109
+ // balanced token consuming
110
+ scan:
111
+ do {
112
+ switch (token.type) {
113
+ case RightCurlyBracket:
114
+ case RightParenthesis:
115
+ case RightSquareBracket:
116
+ if (token.type !== balanceCloseType) {
117
+ break scan;
118
+ }
119
+
120
+ balanceCloseType = balanceStash.pop();
121
+
122
+ if (balanceStash.length === 0) {
123
+ length++;
124
+ break scan;
125
+ }
126
+
127
+ break;
128
+
129
+ case FunctionToken:
130
+ case LeftParenthesis:
131
+ case LeftSquareBracket:
132
+ case LeftCurlyBracket:
133
+ balanceStash.push(balanceCloseType);
134
+ balanceCloseType = balancePair.get(token.type);
135
+ break;
136
+ }
137
+
138
+ length++;
139
+ } while (token = getNextToken(length));
140
+
141
+ return length;
142
+ }
143
+
144
+ // TODO: implement
145
+ // can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
146
+ // https://drafts.csswg.org/css-values/#calc-notation
147
+ function calc(next) {
148
+ return function(token, getNextToken, opts) {
149
+ if (token === null) {
150
+ return 0;
151
+ }
152
+
153
+ if (token.type === FunctionToken && eqStrAny(token.value, calcFunctionNames)) {
154
+ return consumeFunction(token, getNextToken);
155
+ }
156
+
157
+ return next(token, getNextToken, opts);
158
+ };
159
+ }
160
+
161
+ function tokenType(expectedTokenType) {
162
+ return function(token) {
163
+ if (token === null || token.type !== expectedTokenType) {
164
+ return 0;
165
+ }
166
+
167
+ return 1;
168
+ };
169
+ }
170
+
171
+ // =========================
172
+ // Complex types
173
+ //
174
+
175
+ // https://drafts.csswg.org/css-values-4/#custom-idents
176
+ // 4.2. Author-defined Identifiers: the <custom-ident> type
177
+ // Some properties accept arbitrary author-defined identifiers as a component value.
178
+ // This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier
179
+ // that would not be misinterpreted as a pre-defined keyword in that property’s value definition.
180
+ //
181
+ // See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
182
+ function customIdent(token) {
183
+ if (token === null || token.type !== Ident) {
184
+ return 0;
185
+ }
186
+
187
+ const name = token.value.toLowerCase();
188
+
189
+ // The CSS-wide keywords are not valid <custom-ident>s
190
+ if (eqStrAny(name, cssWideKeywords)) {
191
+ return 0;
192
+ }
193
+
194
+ // The default keyword is reserved and is also not a valid <custom-ident>
195
+ if (eqStr(name, 'default')) {
196
+ return 0;
197
+ }
198
+
199
+ // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
200
+ // Specifications using <custom-ident> must specify clearly what other keywords
201
+ // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords
202
+ // in that property’s value definition are excluded. Excluded keywords are excluded
203
+ // in all ASCII case permutations.
204
+
205
+ return 1;
206
+ }
207
+
208
+ // https://drafts.csswg.org/css-values-4/#dashed-idents
209
+ // The <dashed-ident> production is a <custom-ident>, with all the case-sensitivity that implies,
210
+ // with the additional restriction that it must start with two dashes (U+002D HYPHEN-MINUS).
211
+ function dashedIdent(token) {
212
+ if (token === null || token.type !== Ident) {
213
+ return 0;
214
+ }
215
+
216
+ // ... must start with two dashes (U+002D HYPHEN-MINUS)
217
+ if (charCodeAt(token.value, 0) !== 0x002D || charCodeAt(token.value, 1) !== 0x002D) {
218
+ return 0;
219
+ }
220
+
221
+ return 1;
222
+ }
223
+
224
+ // https://drafts.csswg.org/css-variables/#typedef-custom-property-name
225
+ // A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
226
+ // The <custom-property-name> production corresponds to this: it’s defined as any <dashed-ident>
227
+ // (a valid identifier that starts with two dashes), except -- itself, which is reserved for future use by CSS.
228
+ function customPropertyName(token) {
229
+ // ... it’s defined as any <dashed-ident>
230
+ if (!dashedIdent(token)) {
231
+ return 0;
232
+ }
233
+
234
+ // ... except -- itself, which is reserved for future use by CSS
235
+ if (token.value === '--') {
236
+ return 0;
237
+ }
238
+
239
+ return 1;
240
+ }
241
+
242
+ // https://drafts.csswg.org/css-color-4/#hex-notation
243
+ // The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
244
+ // In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or
245
+ // letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).
246
+ function hexColor(token) {
247
+ if (token === null || token.type !== Hash) {
248
+ return 0;
249
+ }
250
+
251
+ const length = token.value.length;
252
+
253
+ // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9)
254
+ if (length !== 4 && length !== 5 && length !== 7 && length !== 9) {
255
+ return 0;
256
+ }
257
+
258
+ for (let i = 1; i < length; i++) {
259
+ if (!isHexDigit(charCodeAt(token.value, i))) {
260
+ return 0;
261
+ }
262
+ }
263
+
264
+ return 1;
265
+ }
266
+
267
+ function idSelector(token) {
268
+ if (token === null || token.type !== Hash) {
269
+ return 0;
270
+ }
271
+
272
+ if (!isIdentifierStart(charCodeAt(token.value, 1), charCodeAt(token.value, 2), charCodeAt(token.value, 3))) {
273
+ return 0;
274
+ }
275
+
276
+ return 1;
277
+ }
278
+
279
+ // https://drafts.csswg.org/css-syntax/#any-value
280
+ // It represents the entirety of what a valid declaration can have as its value.
281
+ function declarationValue(token, getNextToken) {
282
+ if (!token) {
283
+ return 0;
284
+ }
285
+
286
+ let balanceCloseType = 0;
287
+ let balanceStash = [];
288
+ let length = 0;
289
+
290
+ // The <declaration-value> production matches any sequence of one or more tokens,
291
+ // so long as the sequence does not contain ...
292
+ scan:
293
+ do {
294
+ switch (token.type) {
295
+ // ... <bad-string-token>, <bad-url-token>,
296
+ case BadString:
297
+ case BadUrl:
298
+ break scan;
299
+
300
+ // ... unmatched <)-token>, <]-token>, or <}-token>,
301
+ case RightCurlyBracket:
302
+ case RightParenthesis:
303
+ case RightSquareBracket:
304
+ if (token.type !== balanceCloseType) {
305
+ break scan;
306
+ }
307
+
308
+ balanceCloseType = balanceStash.pop();
309
+ break;
310
+
311
+ // ... or top-level <semicolon-token> tokens
312
+ case Semicolon:
313
+ if (balanceCloseType === 0) {
314
+ break scan;
315
+ }
316
+
317
+ break;
318
+
319
+ // ... or <delim-token> tokens with a value of "!"
320
+ case Delim:
321
+ if (balanceCloseType === 0 && token.value === '!') {
322
+ break scan;
323
+ }
324
+
325
+ break;
326
+
327
+ case FunctionToken:
328
+ case LeftParenthesis:
329
+ case LeftSquareBracket:
330
+ case LeftCurlyBracket:
331
+ balanceStash.push(balanceCloseType);
332
+ balanceCloseType = balancePair.get(token.type);
333
+ break;
334
+ }
335
+
336
+ length++;
337
+ } while (token = getNextToken(length));
338
+
339
+ return length;
340
+ }
341
+
342
+ // https://drafts.csswg.org/css-syntax/#any-value
343
+ // The <any-value> production is identical to <declaration-value>, but also
344
+ // allows top-level <semicolon-token> tokens and <delim-token> tokens
345
+ // with a value of "!". It represents the entirety of what valid CSS can be in any context.
346
+ function anyValue(token, getNextToken) {
347
+ if (!token) {
348
+ return 0;
349
+ }
350
+
351
+ let balanceCloseType = 0;
352
+ let balanceStash = [];
353
+ let length = 0;
354
+
355
+ // The <any-value> production matches any sequence of one or more tokens,
356
+ // so long as the sequence ...
357
+ scan:
358
+ do {
359
+ switch (token.type) {
360
+ // ... does not contain <bad-string-token>, <bad-url-token>,
361
+ case BadString:
362
+ case BadUrl:
363
+ break scan;
364
+
365
+ // ... unmatched <)-token>, <]-token>, or <}-token>,
366
+ case RightCurlyBracket:
367
+ case RightParenthesis:
368
+ case RightSquareBracket:
369
+ if (token.type !== balanceCloseType) {
370
+ break scan;
371
+ }
372
+
373
+ balanceCloseType = balanceStash.pop();
374
+ break;
375
+
376
+ case FunctionToken:
377
+ case LeftParenthesis:
378
+ case LeftSquareBracket:
379
+ case LeftCurlyBracket:
380
+ balanceStash.push(balanceCloseType);
381
+ balanceCloseType = balancePair.get(token.type);
382
+ break;
383
+ }
384
+
385
+ length++;
386
+ } while (token = getNextToken(length));
387
+
388
+ return length;
389
+ }
390
+
391
+ // =========================
392
+ // Dimensions
393
+ //
394
+
395
+ function dimension(type) {
396
+ if (type) {
397
+ type = new Set(type);
398
+ }
399
+
400
+ return function(token, getNextToken, opts) {
401
+ if (token === null || token.type !== Dimension) {
402
+ return 0;
403
+ }
404
+
405
+ const numberEnd = consumeNumber(token.value, 0);
406
+
407
+ // check unit
408
+ if (type !== null) {
409
+ // check for IE postfix hack, i.e. 123px\0 or 123px\9
410
+ const reverseSolidusOffset = token.value.indexOf('\\', numberEnd);
411
+ const unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset)
412
+ ? token.value.substr(numberEnd)
413
+ : token.value.substring(numberEnd, reverseSolidusOffset);
414
+
415
+ if (type.has(unit.toLowerCase()) === false) {
416
+ return 0;
417
+ }
418
+ }
419
+
420
+ // check range if specified
421
+ if (outOfRange(opts, token.value, numberEnd)) {
422
+ return 0;
423
+ }
424
+
425
+ return 1;
426
+ };
427
+ }
428
+
429
+ // =========================
430
+ // Percentage
431
+ //
432
+
433
+ // §5.5. Percentages: the <percentage> type
434
+ // https://drafts.csswg.org/css-values-4/#percentages
435
+ function percentage(token, getNextToken, opts) {
436
+ // ... corresponds to the <percentage-token> production
437
+ if (token === null || token.type !== Percentage) {
438
+ return 0;
439
+ }
440
+
441
+ // check range if specified
442
+ if (outOfRange(opts, token.value, token.value.length - 1)) {
443
+ return 0;
444
+ }
445
+
446
+ return 1;
447
+ }
448
+
449
+ // =========================
450
+ // Numeric
451
+ //
452
+
453
+ // https://drafts.csswg.org/css-values-4/#numbers
454
+ // The value <zero> represents a literal number with the value 0. Expressions that merely
455
+ // evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>;
456
+ // only literal <number-token>s do.
457
+ function zero(next) {
458
+ if (typeof next !== 'function') {
459
+ next = function() {
460
+ return 0;
461
+ };
462
+ }
463
+
464
+ return function(token, getNextToken, opts) {
465
+ if (token !== null && token.type === NumberToken) {
466
+ if (Number(token.value) === 0) {
467
+ return 1;
468
+ }
469
+ }
470
+
471
+ return next(token, getNextToken, opts);
472
+ };
473
+ }
474
+
475
+ // § 5.3. Real Numbers: the <number> type
476
+ // https://drafts.csswg.org/css-values-4/#numbers
477
+ // Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.
478
+ // ... It corresponds to the <number-token> production
479
+ function number(token, getNextToken, opts) {
480
+ if (token === null) {
481
+ return 0;
482
+ }
483
+
484
+ const numberEnd = consumeNumber(token.value, 0);
485
+ const isNumber = numberEnd === token.value.length;
486
+ if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) {
487
+ return 0;
488
+ }
489
+
490
+ // check range if specified
491
+ if (outOfRange(opts, token.value, numberEnd)) {
492
+ return 0;
493
+ }
494
+
495
+ return 1;
496
+ }
497
+
498
+ // §5.2. Integers: the <integer> type
499
+ // https://drafts.csswg.org/css-values-4/#integers
500
+ function integer(token, getNextToken, opts) {
501
+ // ... corresponds to a subset of the <number-token> production
502
+ if (token === null || token.type !== NumberToken) {
503
+ return 0;
504
+ }
505
+
506
+ // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign.
507
+ let i = charCodeAt(token.value, 0) === 0x002B || // U+002B PLUS SIGN (+)
508
+ charCodeAt(token.value, 0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-)
509
+
510
+ // When written literally, an integer is one or more decimal digits 0 through 9 ...
511
+ for (; i < token.value.length; i++) {
512
+ if (!isDigit(charCodeAt(token.value, i))) {
513
+ return 0;
514
+ }
515
+ }
516
+
517
+ // check range if specified
518
+ if (outOfRange(opts, token.value, i)) {
519
+ return 0;
520
+ }
521
+
522
+ return 1;
523
+ }
524
+
525
+ // token types
526
+ export const tokenTypes = {
527
+ 'ident-token': tokenType(Ident),
528
+ 'function-token': tokenType(FunctionToken),
529
+ 'at-keyword-token': tokenType(AtKeyword),
530
+ 'hash-token': tokenType(Hash),
531
+ 'string-token': tokenType(StringToken),
532
+ 'bad-string-token': tokenType(BadString),
533
+ 'url-token': tokenType(Url),
534
+ 'bad-url-token': tokenType(BadUrl),
535
+ 'delim-token': tokenType(Delim),
536
+ 'number-token': tokenType(NumberToken),
537
+ 'percentage-token': tokenType(Percentage),
538
+ 'dimension-token': tokenType(Dimension),
539
+ 'whitespace-token': tokenType(WhiteSpace),
540
+ 'CDO-token': tokenType(CDO),
541
+ 'CDC-token': tokenType(CDC),
542
+ 'colon-token': tokenType(Colon),
543
+ 'semicolon-token': tokenType(Semicolon),
544
+ 'comma-token': tokenType(Comma),
545
+ '[-token': tokenType(LeftSquareBracket),
546
+ ']-token': tokenType(RightSquareBracket),
547
+ '(-token': tokenType(LeftParenthesis),
548
+ ')-token': tokenType(RightParenthesis),
549
+ '{-token': tokenType(LeftCurlyBracket),
550
+ '}-token': tokenType(RightCurlyBracket)
551
+ };
552
+
553
+ // token production types
554
+ export const productionTypes = {
555
+ // token type aliases
556
+ 'string': tokenType(StringToken),
557
+ 'ident': tokenType(Ident),
558
+
559
+ // percentage
560
+ 'percentage': calc(percentage),
561
+
562
+ // numeric
563
+ 'zero': zero(),
564
+ 'number': calc(number),
565
+ 'integer': calc(integer),
566
+
567
+ // complex types
568
+ 'custom-ident': customIdent,
569
+ 'dashed-ident': dashedIdent,
570
+ 'custom-property-name': customPropertyName,
571
+ 'hex-color': hexColor,
572
+ 'id-selector': idSelector, // element( <id-selector> )
573
+ 'an-plus-b': anPlusB,
574
+ 'urange': urange,
575
+ 'declaration-value': declarationValue,
576
+ 'any-value': anyValue
577
+ };
578
+
579
+ export const unitGroups = [
580
+ 'length',
581
+ 'angle',
582
+ 'time',
583
+ 'frequency',
584
+ 'resolution',
585
+ 'flex',
586
+ 'decibel',
587
+ 'semitones'
588
+ ];
589
+
590
+ // dimensions types depend on units set
591
+ export function createDemensionTypes(units) {
592
+ const {
593
+ angle,
594
+ decibel,
595
+ frequency,
596
+ flex,
597
+ length,
598
+ resolution,
599
+ semitones,
600
+ time
601
+ } = units || {};
602
+
603
+ return {
604
+ 'dimension': calc(dimension(null)),
605
+ 'angle': calc(dimension(angle)),
606
+ 'decibel': calc(dimension(decibel)),
607
+ 'frequency': calc(dimension(frequency)),
608
+ 'flex': calc(dimension(flex)),
609
+ 'length': calc(zero(dimension(length))),
610
+ 'resolution': calc(dimension(resolution)),
611
+ 'semitones': calc(dimension(semitones)),
612
+ 'time': calc(dimension(time))
613
+ };
614
+ }
615
+
616
+ export function createGenericTypes(units) {
617
+ return {
618
+ ...tokenTypes,
619
+ ...productionTypes,
620
+ ...createDemensionTypes(units)
621
+ };
622
+ };
@@ -0,0 +1 @@
1
+ export { Lexer } from './Lexer.js';