@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,120 @@
1
+ 'use strict';
2
+
3
+ const types = require('../../tokenizer/types.cjs');
4
+
5
+ const likelyFeatureToken = new Set([types.Colon, types.RightParenthesis, types.EOF]);
6
+
7
+ const name = 'Condition';
8
+ const structure = {
9
+ kind: String,
10
+ children: [[
11
+ 'Identifier',
12
+ 'Feature',
13
+ 'FeatureFunction',
14
+ 'FeatureRange',
15
+ 'SupportsDeclaration'
16
+ ]]
17
+ };
18
+
19
+ function featureOrRange(kind) {
20
+ if (this.lookupTypeNonSC(1) === types.Ident &&
21
+ likelyFeatureToken.has(this.lookupTypeNonSC(2))) {
22
+ return this.Feature(kind);
23
+ }
24
+
25
+ return this.FeatureRange(kind);
26
+ }
27
+
28
+ const parentheses = {
29
+ media: featureOrRange,
30
+ container: featureOrRange,
31
+ supports() {
32
+ return this.SupportsDeclaration();
33
+ }
34
+ };
35
+
36
+ function parse(kind = 'media') {
37
+ const children = this.createList();
38
+
39
+ scan: while (!this.eof) {
40
+ switch (this.tokenType) {
41
+ case types.Comment:
42
+ case types.WhiteSpace:
43
+ this.next();
44
+ continue;
45
+
46
+ case types.Ident:
47
+ children.push(this.Identifier());
48
+ break;
49
+
50
+ case types.LeftParenthesis: {
51
+ let term = this.parseWithFallback(
52
+ () => parentheses[kind].call(this, kind),
53
+ () => null
54
+ );
55
+
56
+ if (!term) {
57
+ term = this.parseWithFallback(
58
+ () => {
59
+ this.eat(types.LeftParenthesis);
60
+ const res = this.Condition(kind);
61
+ this.eat(types.RightParenthesis);
62
+ return res;
63
+ },
64
+ () => {
65
+ return this.GeneralEnclosed(kind);
66
+ }
67
+ );
68
+ }
69
+
70
+ children.push(term);
71
+ break;
72
+ }
73
+
74
+ case types.Function: {
75
+ let term = this.parseWithFallback(
76
+ () => this.FeatureFunction(kind),
77
+ () => null
78
+ );
79
+
80
+ if (!term) {
81
+ term = this.GeneralEnclosed(kind);
82
+ }
83
+
84
+ children.push(term);
85
+ break;
86
+ }
87
+
88
+ default:
89
+ break scan;
90
+ }
91
+ }
92
+
93
+ if (children.isEmpty) {
94
+ this.error('Condition is expected');
95
+ }
96
+
97
+ return {
98
+ type: 'Condition',
99
+ loc: this.getLocationFromList(children),
100
+ kind,
101
+ children
102
+ };
103
+ }
104
+
105
+ function generate(node) {
106
+ node.children.forEach(child => {
107
+ if (child.type === 'Condition') {
108
+ this.token(types.LeftParenthesis, '(');
109
+ this.node(child);
110
+ this.token(types.RightParenthesis, ')');
111
+ } else {
112
+ this.node(child);
113
+ }
114
+ });
115
+ }
116
+
117
+ exports.generate = generate;
118
+ exports.name = name;
119
+ exports.parse = parse;
120
+ exports.structure = structure;
@@ -0,0 +1,166 @@
1
+ 'use strict';
2
+
3
+ const names = require('../../utils/names.cjs');
4
+ const types = require('../../tokenizer/types.cjs');
5
+
6
+ const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
7
+ const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
8
+ const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
9
+ const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)
10
+ const ASTERISK = 0x002A; // U+002A ASTERISK (*)
11
+ const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
12
+ const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
13
+
14
+ function consumeValueRaw() {
15
+ return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, true);
16
+ }
17
+
18
+ function consumeCustomPropertyRaw() {
19
+ return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false);
20
+ }
21
+
22
+ function consumeValue() {
23
+ const startValueToken = this.tokenIndex;
24
+ const value = this.Value();
25
+
26
+ if (value.type !== 'Raw' &&
27
+ this.eof === false &&
28
+ this.tokenType !== types.Semicolon &&
29
+ this.isDelim(EXCLAMATIONMARK) === false &&
30
+ this.isBalanceEdge(startValueToken) === false) {
31
+ this.error();
32
+ }
33
+
34
+ return value;
35
+ }
36
+
37
+ const name = 'Declaration';
38
+ const walkContext = 'declaration';
39
+ const structure = {
40
+ important: [Boolean, String],
41
+ property: String,
42
+ value: ['Value', 'Raw']
43
+ };
44
+
45
+ function parse() {
46
+ const start = this.tokenStart;
47
+ const startToken = this.tokenIndex;
48
+ const property = readProperty.call(this);
49
+ const customProperty = names.isCustomProperty(property);
50
+ const parseValue = customProperty ? this.parseCustomProperty : this.parseValue;
51
+ const consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
52
+ let important = false;
53
+ let value;
54
+
55
+ this.skipSC();
56
+ this.eat(types.Colon);
57
+
58
+ const valueStart = this.tokenIndex;
59
+
60
+ if (!customProperty) {
61
+ this.skipSC();
62
+ }
63
+
64
+ if (parseValue) {
65
+ value = this.parseWithFallback(consumeValue, consumeRaw);
66
+ } else {
67
+ value = consumeRaw.call(this, this.tokenIndex);
68
+ }
69
+
70
+ if (customProperty && value.type === 'Value' && value.children.isEmpty) {
71
+ for (let offset = valueStart - this.tokenIndex; offset <= 0; offset++) {
72
+ if (this.lookupType(offset) === types.WhiteSpace) {
73
+ value.children.appendData({
74
+ type: 'WhiteSpace',
75
+ loc: null,
76
+ value: ' '
77
+ });
78
+ break;
79
+ }
80
+ }
81
+ }
82
+
83
+ if (this.isDelim(EXCLAMATIONMARK)) {
84
+ important = getImportant.call(this);
85
+ this.skipSC();
86
+ }
87
+
88
+ // Do not include semicolon to range per spec
89
+ // https://drafts.csswg.org/css-syntax/#declaration-diagram
90
+
91
+ if (this.eof === false &&
92
+ this.tokenType !== types.Semicolon &&
93
+ this.isBalanceEdge(startToken) === false) {
94
+ this.error();
95
+ }
96
+
97
+ return {
98
+ type: 'Declaration',
99
+ loc: this.getLocation(start, this.tokenStart),
100
+ important,
101
+ property,
102
+ value
103
+ };
104
+ }
105
+
106
+ function generate(node) {
107
+ this.token(types.Ident, node.property);
108
+ this.token(types.Colon, ':');
109
+ this.node(node.value);
110
+
111
+ if (node.important) {
112
+ this.token(types.Delim, '!');
113
+ this.token(types.Ident, node.important === true ? 'important' : node.important);
114
+ }
115
+ }
116
+
117
+ function readProperty() {
118
+ const start = this.tokenStart;
119
+
120
+ // hacks
121
+ if (this.tokenType === types.Delim) {
122
+ switch (this.charCodeAt(this.tokenStart)) {
123
+ case ASTERISK:
124
+ case DOLLARSIGN:
125
+ case PLUSSIGN:
126
+ case NUMBERSIGN:
127
+ case AMPERSAND:
128
+ this.next();
129
+ break;
130
+
131
+ // TODO: not sure we should support this hack
132
+ case SOLIDUS:
133
+ this.next();
134
+ if (this.isDelim(SOLIDUS)) {
135
+ this.next();
136
+ }
137
+ break;
138
+ }
139
+ }
140
+
141
+ if (this.tokenType === types.Hash) {
142
+ this.eat(types.Hash);
143
+ } else {
144
+ this.eat(types.Ident);
145
+ }
146
+
147
+ return this.substrToCursor(start);
148
+ }
149
+
150
+ // ! ws* important
151
+ function getImportant() {
152
+ this.eat(types.Delim);
153
+ this.skipSC();
154
+
155
+ const important = this.consume(types.Ident);
156
+
157
+ // store original value in case it differ from `important`
158
+ // for better original source restoring and hacks like `!ie` support
159
+ return important === 'important' ? true : important;
160
+ }
161
+
162
+ exports.generate = generate;
163
+ exports.name = name;
164
+ exports.parse = parse;
165
+ exports.structure = structure;
166
+ exports.walkContext = walkContext;
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ const types = require('../../tokenizer/types.cjs');
4
+
5
+ const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)
6
+
7
+ function consumeRaw() {
8
+ return this.Raw(this.consumeUntilSemicolonIncluded, true);
9
+ }
10
+
11
+ const name = 'DeclarationList';
12
+ const structure = {
13
+ children: [[
14
+ 'Declaration',
15
+ 'Atrule',
16
+ 'Rule'
17
+ ]]
18
+ };
19
+
20
+ function parse() {
21
+ const children = this.createList();
22
+
23
+ while (!this.eof) {
24
+ switch (this.tokenType) {
25
+ case types.WhiteSpace:
26
+ case types.Comment:
27
+ case types.Semicolon:
28
+ this.next();
29
+ break;
30
+
31
+ case types.AtKeyword:
32
+ children.push(this.parseWithFallback(this.Atrule.bind(this, true), consumeRaw));
33
+ break;
34
+
35
+ default:
36
+ if (this.isDelim(AMPERSAND)) {
37
+ children.push(this.parseWithFallback(this.Rule, consumeRaw));
38
+ } else {
39
+ children.push(this.parseWithFallback(this.Declaration, consumeRaw));
40
+ }
41
+ }
42
+ }
43
+
44
+ return {
45
+ type: 'DeclarationList',
46
+ loc: this.getLocationFromList(children),
47
+ children
48
+ };
49
+ }
50
+
51
+ function generate(node) {
52
+ this.children(node, prev => {
53
+ if (prev.type === 'Declaration') {
54
+ this.token(types.Semicolon, ';');
55
+ }
56
+ });
57
+ }
58
+
59
+ exports.generate = generate;
60
+ exports.name = name;
61
+ exports.parse = parse;
62
+ exports.structure = structure;
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ const types = require('../../tokenizer/types.cjs');
4
+
5
+ const name = 'Dimension';
6
+ const structure = {
7
+ value: String,
8
+ unit: String
9
+ };
10
+
11
+ function parse() {
12
+ const start = this.tokenStart;
13
+ const value = this.consumeNumber(types.Dimension);
14
+
15
+ return {
16
+ type: 'Dimension',
17
+ loc: this.getLocation(start, this.tokenStart),
18
+ value,
19
+ unit: this.substring(start + value.length, this.tokenStart)
20
+ };
21
+ }
22
+
23
+ function generate(node) {
24
+ this.token(types.Dimension, node.value + node.unit);
25
+ }
26
+
27
+ exports.generate = generate;
28
+ exports.name = name;
29
+ exports.parse = parse;
30
+ exports.structure = structure;
@@ -0,0 +1,101 @@
1
+ 'use strict';
2
+
3
+ const types = require('../../tokenizer/types.cjs');
4
+
5
+ const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
6
+
7
+ const name = 'Feature';
8
+ const structure = {
9
+ kind: String,
10
+ name: String,
11
+ value: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null]
12
+ };
13
+
14
+ function parse(kind) {
15
+ const start = this.tokenStart;
16
+ let name;
17
+ let value = null;
18
+
19
+ this.eat(types.LeftParenthesis);
20
+ this.skipSC();
21
+
22
+ name = this.consume(types.Ident);
23
+ this.skipSC();
24
+
25
+ if (this.tokenType !== types.RightParenthesis) {
26
+ this.eat(types.Colon);
27
+ this.skipSC();
28
+
29
+ switch (this.tokenType) {
30
+ case types.Number:
31
+ if (this.lookupNonWSType(1) === types.Delim) {
32
+ value = this.Ratio();
33
+ } else {
34
+ value = this.Number();
35
+ }
36
+
37
+ break;
38
+
39
+ case types.Dimension:
40
+ value = this.Dimension();
41
+ break;
42
+
43
+ case types.Ident:
44
+ value = this.Identifier();
45
+ break;
46
+
47
+ case types.Function:
48
+ value = this.parseWithFallback(
49
+ () => {
50
+ const res = this.Function(this.readSequence, this.scope.Value);
51
+
52
+ this.skipSC();
53
+
54
+ if (this.isDelim(SOLIDUS)) {
55
+ this.error();
56
+ }
57
+
58
+ return res;
59
+ },
60
+ () => {
61
+ return this.Ratio();
62
+ }
63
+ );
64
+ break;
65
+
66
+ default:
67
+ this.error('Number, dimension, ratio or identifier is expected');
68
+ }
69
+
70
+ this.skipSC();
71
+ }
72
+
73
+ if (!this.eof) {
74
+ this.eat(types.RightParenthesis);
75
+ }
76
+
77
+ return {
78
+ type: 'Feature',
79
+ loc: this.getLocation(start, this.tokenStart),
80
+ kind,
81
+ name,
82
+ value
83
+ };
84
+ }
85
+
86
+ function generate(node) {
87
+ this.token(types.LeftParenthesis, '(');
88
+ this.token(types.Ident, node.name);
89
+
90
+ if (node.value !== null) {
91
+ this.token(types.Colon, ':');
92
+ this.node(node.value);
93
+ }
94
+
95
+ this.token(types.RightParenthesis, ')');
96
+ }
97
+
98
+ exports.generate = generate;
99
+ exports.name = name;
100
+ exports.parse = parse;
101
+ exports.structure = structure;
@@ -0,0 +1,67 @@
1
+ 'use strict';
2
+
3
+ const types = require('../../tokenizer/types.cjs');
4
+
5
+ const name = 'FeatureFunction';
6
+ const structure = {
7
+ kind: String,
8
+ feature: String,
9
+ value: ['Declaration', 'Selector']
10
+ };
11
+
12
+ function getFeatureParser(kind, name) {
13
+ const featuresOfKind = this.features[kind] || {};
14
+ const parser = featuresOfKind[name];
15
+
16
+ if (typeof parser !== 'function') {
17
+ this.error(`Unknown feature ${name}()`);
18
+ }
19
+
20
+ return parser;
21
+ }
22
+
23
+ function parse(kind = 'unknown') {
24
+ const start = this.tokenStart;
25
+ const functionName = this.consumeFunctionName();
26
+ const valueParser = getFeatureParser.call(this, kind, functionName.toLowerCase());
27
+
28
+ this.skipSC();
29
+
30
+ const value = this.parseWithFallback(
31
+ () => {
32
+ const startValueToken = this.tokenIndex;
33
+ const value = valueParser.call(this);
34
+
35
+ if (this.eof === false &&
36
+ this.isBalanceEdge(startValueToken) === false) {
37
+ this.error();
38
+ }
39
+
40
+ return value;
41
+ },
42
+ () => this.Raw(null, false)
43
+ );
44
+
45
+ if (!this.eof) {
46
+ this.eat(types.RightParenthesis);
47
+ }
48
+
49
+ return {
50
+ type: 'FeatureFunction',
51
+ loc: this.getLocation(start, this.tokenStart),
52
+ kind,
53
+ feature: functionName,
54
+ value
55
+ };
56
+ }
57
+
58
+ function generate(node) {
59
+ this.token(types.Function, node.feature + '(');
60
+ this.node(node.value);
61
+ this.token(types.RightParenthesis, ')');
62
+ }
63
+
64
+ exports.generate = generate;
65
+ exports.name = name;
66
+ exports.parse = parse;
67
+ exports.structure = structure;
@@ -0,0 +1,133 @@
1
+ 'use strict';
2
+
3
+ const types = require('../../tokenizer/types.cjs');
4
+
5
+ const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
6
+ const LESSTHANSIGN = 0x003C; // U+003C LESS-THAN SIGN (<)
7
+ const EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
8
+ const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
9
+
10
+ const name = 'FeatureRange';
11
+ const structure = {
12
+ kind: String,
13
+ left: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'],
14
+ leftComparison: String,
15
+ middle: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'],
16
+ rightComparison: [String, null],
17
+ right: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null]
18
+ };
19
+
20
+ function readTerm() {
21
+ this.skipSC();
22
+
23
+ switch (this.tokenType) {
24
+ case types.Number:
25
+ if (this.isDelim(SOLIDUS, this.lookupOffsetNonSC(1))) {
26
+ return this.Ratio();
27
+ } else {
28
+ return this.Number();
29
+ }
30
+
31
+ case types.Dimension:
32
+ return this.Dimension();
33
+
34
+ case types.Ident:
35
+ return this.Identifier();
36
+
37
+ case types.Function:
38
+ return this.parseWithFallback(
39
+ () => {
40
+ const res = this.Function(this.readSequence, this.scope.Value);
41
+
42
+ this.skipSC();
43
+
44
+ if (this.isDelim(SOLIDUS)) {
45
+ this.error();
46
+ }
47
+
48
+ return res;
49
+ },
50
+ () => {
51
+ return this.Ratio();
52
+ }
53
+ );
54
+
55
+ default:
56
+ this.error('Number, dimension, ratio or identifier is expected');
57
+ }
58
+ }
59
+
60
+ function readComparison(expectColon) {
61
+ this.skipSC();
62
+
63
+ if (this.isDelim(LESSTHANSIGN) ||
64
+ this.isDelim(GREATERTHANSIGN)) {
65
+ const value = this.source[this.tokenStart];
66
+
67
+ this.next();
68
+
69
+ if (this.isDelim(EQUALSSIGN)) {
70
+ this.next();
71
+ return value + '=';
72
+ }
73
+
74
+ return value;
75
+ }
76
+
77
+ if (this.isDelim(EQUALSSIGN)) {
78
+ return '=';
79
+ }
80
+
81
+ this.error(`Expected ${expectColon ? '":", ' : ''}"<", ">", "=" or ")"`);
82
+ }
83
+
84
+ function parse(kind = 'unknown') {
85
+ const start = this.tokenStart;
86
+
87
+ this.skipSC();
88
+ this.eat(types.LeftParenthesis);
89
+
90
+ const left = readTerm.call(this);
91
+ const leftComparison = readComparison.call(this, left.type === 'Identifier');
92
+ const middle = readTerm.call(this);
93
+ let rightComparison = null;
94
+ let right = null;
95
+
96
+ if (this.lookupNonWSType(0) !== types.RightParenthesis) {
97
+ rightComparison = readComparison.call(this);
98
+ right = readTerm.call(this);
99
+ }
100
+
101
+ this.skipSC();
102
+ this.eat(types.RightParenthesis);
103
+
104
+ return {
105
+ type: 'FeatureRange',
106
+ loc: this.getLocation(start, this.tokenStart),
107
+ kind,
108
+ left,
109
+ leftComparison,
110
+ middle,
111
+ rightComparison,
112
+ right
113
+ };
114
+ }
115
+
116
+ function generate(node) {
117
+ this.token(types.LeftParenthesis, '(');
118
+ this.node(node.left);
119
+ this.tokenize(node.leftComparison);
120
+ this.node(node.middle);
121
+
122
+ if (node.right) {
123
+ this.tokenize(node.rightComparison);
124
+ this.node(node.right);
125
+ }
126
+
127
+ this.token(types.RightParenthesis, ')');
128
+ }
129
+
130
+ exports.generate = generate;
131
+ exports.name = name;
132
+ exports.parse = parse;
133
+ exports.structure = structure;