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