@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,100 @@
1
+ import {
2
+ AtKeyword,
3
+ Semicolon,
4
+ LeftCurlyBracket,
5
+ RightCurlyBracket
6
+ } from '../../tokenizer/index.js';
7
+
8
+ function consumeRaw() {
9
+ return this.Raw(this.consumeUntilLeftCurlyBracketOrSemicolon, true);
10
+ }
11
+
12
+ function isDeclarationBlockAtrule() {
13
+ for (let offset = 1, type; type = this.lookupType(offset); offset++) {
14
+ if (type === RightCurlyBracket) {
15
+ return true;
16
+ }
17
+
18
+ if (type === LeftCurlyBracket ||
19
+ type === AtKeyword) {
20
+ return false;
21
+ }
22
+ }
23
+
24
+ return false;
25
+ }
26
+
27
+
28
+ export const name = 'Atrule';
29
+ export const walkContext = 'atrule';
30
+ export const structure = {
31
+ name: String,
32
+ prelude: ['AtrulePrelude', 'Raw', null],
33
+ block: ['Block', null]
34
+ };
35
+
36
+ export function parse(isDeclaration = false) {
37
+ const start = this.tokenStart;
38
+ let name;
39
+ let nameLowerCase;
40
+ let prelude = null;
41
+ let block = null;
42
+
43
+ this.eat(AtKeyword);
44
+
45
+ name = this.substrToCursor(start + 1);
46
+ nameLowerCase = name.toLowerCase();
47
+ this.skipSC();
48
+
49
+ // parse prelude
50
+ if (this.eof === false &&
51
+ this.tokenType !== LeftCurlyBracket &&
52
+ this.tokenType !== Semicolon) {
53
+ if (this.parseAtrulePrelude) {
54
+ prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name, isDeclaration), consumeRaw);
55
+ } else {
56
+ prelude = consumeRaw.call(this, this.tokenIndex);
57
+ }
58
+
59
+ this.skipSC();
60
+ }
61
+
62
+ switch (this.tokenType) {
63
+ case Semicolon:
64
+ this.next();
65
+ break;
66
+
67
+ case LeftCurlyBracket:
68
+ if (hasOwnProperty.call(this.atrule, nameLowerCase) &&
69
+ typeof this.atrule[nameLowerCase].block === 'function') {
70
+ block = this.atrule[nameLowerCase].block.call(this, isDeclaration);
71
+ } else {
72
+ // TODO: should consume block content as Raw?
73
+ block = this.Block(isDeclarationBlockAtrule.call(this));
74
+ }
75
+
76
+ break;
77
+ }
78
+
79
+ return {
80
+ type: 'Atrule',
81
+ loc: this.getLocation(start, this.tokenStart),
82
+ name,
83
+ prelude,
84
+ block
85
+ };
86
+ }
87
+
88
+ export function generate(node) {
89
+ this.token(AtKeyword, '@' + node.name);
90
+
91
+ if (node.prelude !== null) {
92
+ this.node(node.prelude);
93
+ }
94
+
95
+ if (node.block) {
96
+ this.node(node.block);
97
+ } else {
98
+ this.token(Semicolon, ';');
99
+ }
100
+ }
@@ -0,0 +1,47 @@
1
+ import {
2
+ Semicolon,
3
+ LeftCurlyBracket
4
+ } from '../../tokenizer/index.js';
5
+
6
+ export const name = 'AtrulePrelude';
7
+ export const walkContext = 'atrulePrelude';
8
+ export const structure = {
9
+ children: [[]]
10
+ };
11
+
12
+ export function parse(name) {
13
+ let children = null;
14
+
15
+ if (name !== null) {
16
+ name = name.toLowerCase();
17
+ }
18
+
19
+ this.skipSC();
20
+
21
+ if (hasOwnProperty.call(this.atrule, name) &&
22
+ typeof this.atrule[name].prelude === 'function') {
23
+ // custom consumer
24
+ children = this.atrule[name].prelude.call(this);
25
+ } else {
26
+ // default consumer
27
+ children = this.readSequence(this.scope.AtrulePrelude);
28
+ }
29
+
30
+ this.skipSC();
31
+
32
+ if (this.eof !== true &&
33
+ this.tokenType !== LeftCurlyBracket &&
34
+ this.tokenType !== Semicolon) {
35
+ this.error('Semicolon or block is expected');
36
+ }
37
+
38
+ return {
39
+ type: 'AtrulePrelude',
40
+ loc: this.getLocationFromList(children),
41
+ children
42
+ };
43
+ }
44
+
45
+ export function generate(node) {
46
+ this.children(node);
47
+ }
@@ -0,0 +1,147 @@
1
+ import {
2
+ Ident,
3
+ String as StringToken,
4
+ Delim,
5
+ LeftSquareBracket,
6
+ RightSquareBracket
7
+ } from '../../tokenizer/index.js';
8
+
9
+ const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
10
+ const ASTERISK = 0x002A; // U+002A ASTERISK (*)
11
+ const EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
12
+ const CIRCUMFLEXACCENT = 0x005E; // U+005E (^)
13
+ const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)
14
+ const TILDE = 0x007E; // U+007E TILDE (~)
15
+
16
+ function getAttributeName() {
17
+ if (this.eof) {
18
+ this.error('Unexpected end of input');
19
+ }
20
+
21
+ const start = this.tokenStart;
22
+ let expectIdent = false;
23
+
24
+ if (this.isDelim(ASTERISK)) {
25
+ expectIdent = true;
26
+ this.next();
27
+ } else if (!this.isDelim(VERTICALLINE)) {
28
+ this.eat(Ident);
29
+ }
30
+
31
+ if (this.isDelim(VERTICALLINE)) {
32
+ if (this.charCodeAt(this.tokenStart + 1) !== EQUALSSIGN) {
33
+ this.next();
34
+ this.eat(Ident);
35
+ } else if (expectIdent) {
36
+ this.error('Identifier is expected', this.tokenEnd);
37
+ }
38
+ } else if (expectIdent) {
39
+ this.error('Vertical line is expected');
40
+ }
41
+
42
+ return {
43
+ type: 'Identifier',
44
+ loc: this.getLocation(start, this.tokenStart),
45
+ name: this.substrToCursor(start)
46
+ };
47
+ }
48
+
49
+ function getOperator() {
50
+ const start = this.tokenStart;
51
+ const code = this.charCodeAt(start);
52
+
53
+ if (code !== EQUALSSIGN && // =
54
+ code !== TILDE && // ~=
55
+ code !== CIRCUMFLEXACCENT && // ^=
56
+ code !== DOLLARSIGN && // $=
57
+ code !== ASTERISK && // *=
58
+ code !== VERTICALLINE // |=
59
+ ) {
60
+ this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
61
+ }
62
+
63
+ this.next();
64
+
65
+ if (code !== EQUALSSIGN) {
66
+ if (!this.isDelim(EQUALSSIGN)) {
67
+ this.error('Equal sign is expected');
68
+ }
69
+
70
+ this.next();
71
+ }
72
+
73
+ return this.substrToCursor(start);
74
+ }
75
+
76
+ // '[' <wq-name> ']'
77
+ // '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
78
+ export const name = 'AttributeSelector';
79
+ export const structure = {
80
+ name: 'Identifier',
81
+ matcher: [String, null],
82
+ value: ['String', 'Identifier', null],
83
+ flags: [String, null]
84
+ };
85
+
86
+ export function parse() {
87
+ const start = this.tokenStart;
88
+ let name;
89
+ let matcher = null;
90
+ let value = null;
91
+ let flags = null;
92
+
93
+ this.eat(LeftSquareBracket);
94
+ this.skipSC();
95
+
96
+ name = getAttributeName.call(this);
97
+ this.skipSC();
98
+
99
+ if (this.tokenType !== RightSquareBracket) {
100
+ // avoid case `[name i]`
101
+ if (this.tokenType !== Ident) {
102
+ matcher = getOperator.call(this);
103
+
104
+ this.skipSC();
105
+
106
+ value = this.tokenType === StringToken
107
+ ? this.String()
108
+ : this.Identifier();
109
+
110
+ this.skipSC();
111
+ }
112
+
113
+ // attribute flags
114
+ if (this.tokenType === Ident) {
115
+ flags = this.consume(Ident);
116
+
117
+ this.skipSC();
118
+ }
119
+ }
120
+
121
+ this.eat(RightSquareBracket);
122
+
123
+ return {
124
+ type: 'AttributeSelector',
125
+ loc: this.getLocation(start, this.tokenStart),
126
+ name,
127
+ matcher,
128
+ value,
129
+ flags
130
+ };
131
+ }
132
+
133
+ export function generate(node) {
134
+ this.token(Delim, '[');
135
+ this.node(node.name);
136
+
137
+ if (node.matcher !== null) {
138
+ this.tokenize(node.matcher);
139
+ this.node(node.value);
140
+ }
141
+
142
+ if (node.flags !== null) {
143
+ this.token(Ident, node.flags);
144
+ }
145
+
146
+ this.token(Delim, ']');
147
+ }
@@ -0,0 +1,95 @@
1
+ import {
2
+ WhiteSpace,
3
+ Comment,
4
+ Semicolon,
5
+ AtKeyword,
6
+ LeftCurlyBracket,
7
+ RightCurlyBracket
8
+ } from '../../tokenizer/index.js';
9
+
10
+ const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)
11
+
12
+ function consumeRaw() {
13
+ return this.Raw(null, true);
14
+ }
15
+ function consumeRule() {
16
+ return this.parseWithFallback(this.Rule, consumeRaw);
17
+ }
18
+ function consumeRawDeclaration() {
19
+ return this.Raw(this.consumeUntilSemicolonIncluded, true);
20
+ }
21
+ function consumeDeclaration() {
22
+ if (this.tokenType === Semicolon) {
23
+ return consumeRawDeclaration.call(this, this.tokenIndex);
24
+ }
25
+
26
+ const node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
27
+
28
+ if (this.tokenType === Semicolon) {
29
+ this.next();
30
+ }
31
+
32
+ return node;
33
+ }
34
+
35
+ export const name = 'Block';
36
+ export const walkContext = 'block';
37
+ export const structure = {
38
+ children: [[
39
+ 'Atrule',
40
+ 'Rule',
41
+ 'Declaration'
42
+ ]]
43
+ };
44
+
45
+ export function parse(isStyleBlock) {
46
+ const consumer = isStyleBlock ? consumeDeclaration : consumeRule;
47
+ const start = this.tokenStart;
48
+ let children = this.createList();
49
+
50
+ this.eat(LeftCurlyBracket);
51
+
52
+ scan:
53
+ while (!this.eof) {
54
+ switch (this.tokenType) {
55
+ case RightCurlyBracket:
56
+ break scan;
57
+
58
+ case WhiteSpace:
59
+ case Comment:
60
+ this.next();
61
+ break;
62
+
63
+ case AtKeyword:
64
+ children.push(this.parseWithFallback(this.Atrule.bind(this, isStyleBlock), consumeRaw));
65
+ break;
66
+
67
+ default:
68
+ if (isStyleBlock && this.isDelim(AMPERSAND)) {
69
+ children.push(consumeRule.call(this));
70
+ } else {
71
+ children.push(consumer.call(this));
72
+ }
73
+ }
74
+ }
75
+
76
+ if (!this.eof) {
77
+ this.eat(RightCurlyBracket);
78
+ }
79
+
80
+ return {
81
+ type: 'Block',
82
+ loc: this.getLocation(start, this.tokenStart),
83
+ children
84
+ };
85
+ }
86
+
87
+ export function generate(node) {
88
+ this.token(LeftCurlyBracket, '{');
89
+ this.children(node, prev => {
90
+ if (prev.type === 'Declaration') {
91
+ this.token(Semicolon, ';');
92
+ }
93
+ });
94
+ this.token(RightCurlyBracket, '}');
95
+ }
@@ -0,0 +1,35 @@
1
+ import {
2
+ Delim,
3
+ LeftSquareBracket,
4
+ RightSquareBracket
5
+ } from '../../tokenizer/index.js';
6
+
7
+ export const name = 'Brackets';
8
+ export const structure = {
9
+ children: [[]]
10
+ };
11
+
12
+ export function parse(readSequence, recognizer) {
13
+ const start = this.tokenStart;
14
+ let children = null;
15
+
16
+ this.eat(LeftSquareBracket);
17
+
18
+ children = readSequence.call(this, recognizer);
19
+
20
+ if (!this.eof) {
21
+ this.eat(RightSquareBracket);
22
+ }
23
+
24
+ return {
25
+ type: 'Brackets',
26
+ loc: this.getLocation(start, this.tokenStart),
27
+ children
28
+ };
29
+ }
30
+
31
+ export function generate(node) {
32
+ this.token(Delim, '[');
33
+ this.children(node);
34
+ this.token(Delim, ']');
35
+ }
@@ -0,0 +1,19 @@
1
+ import { CDC } from '../../tokenizer/index.js';
2
+
3
+ export const name = 'CDC';
4
+ export const structure = [];
5
+
6
+ export function parse() {
7
+ const start = this.tokenStart;
8
+
9
+ this.eat(CDC); // -->
10
+
11
+ return {
12
+ type: 'CDC',
13
+ loc: this.getLocation(start, this.tokenStart)
14
+ };
15
+ }
16
+
17
+ export function generate() {
18
+ this.token(CDC, '-->');
19
+ }
@@ -0,0 +1,19 @@
1
+ import { CDO } from '../../tokenizer/index.js';
2
+
3
+ export const name = 'CDO';
4
+ export const structure = [];
5
+
6
+ export function parse() {
7
+ const start = this.tokenStart;
8
+
9
+ this.eat(CDO); // <!--
10
+
11
+ return {
12
+ type: 'CDO',
13
+ loc: this.getLocation(start, this.tokenStart)
14
+ };
15
+ }
16
+
17
+ export function generate() {
18
+ this.token(CDO, '<!--');
19
+ }
@@ -0,0 +1,24 @@
1
+ import { Delim, Ident } from '../../tokenizer/index.js';
2
+
3
+ const FULLSTOP = 0x002E; // U+002E FULL STOP (.)
4
+
5
+ // '.' ident
6
+ export const name = 'ClassSelector';
7
+ export const structure = {
8
+ name: String
9
+ };
10
+
11
+ export function parse() {
12
+ this.eatDelim(FULLSTOP);
13
+
14
+ return {
15
+ type: 'ClassSelector',
16
+ loc: this.getLocation(this.tokenStart - 1, this.tokenEnd),
17
+ name: this.consume(Ident)
18
+ };
19
+ }
20
+
21
+ export function generate(node) {
22
+ this.token(Delim, '.');
23
+ this.token(Ident, node.name);
24
+ }
@@ -0,0 +1,54 @@
1
+ import { WhiteSpace, Delim } from '../../tokenizer/index.js';
2
+
3
+ const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
4
+ const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
5
+ const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
6
+ const TILDE = 0x007E; // U+007E TILDE (~)
7
+
8
+ export const name = 'Combinator';
9
+ export const structure = {
10
+ name: String
11
+ };
12
+
13
+ // + | > | ~ | /deep/
14
+ export function parse() {
15
+ const start = this.tokenStart;
16
+ let name;
17
+
18
+ switch (this.tokenType) {
19
+ case WhiteSpace:
20
+ name = ' ';
21
+ break;
22
+
23
+ case Delim:
24
+ switch (this.charCodeAt(this.tokenStart)) {
25
+ case GREATERTHANSIGN:
26
+ case PLUSSIGN:
27
+ case TILDE:
28
+ this.next();
29
+ break;
30
+
31
+ case SOLIDUS:
32
+ this.next();
33
+ this.eatIdent('deep');
34
+ this.eatDelim(SOLIDUS);
35
+ break;
36
+
37
+ default:
38
+ this.error('Combinator is expected');
39
+ }
40
+
41
+ name = this.substrToCursor(start);
42
+ break;
43
+ }
44
+
45
+ return {
46
+ type: 'Combinator',
47
+ loc: this.getLocation(start, this.tokenStart),
48
+ name
49
+ };
50
+ }
51
+
52
+ export function generate(node) {
53
+ this.tokenize(node.name);
54
+ }
@@ -0,0 +1,33 @@
1
+ import { Comment } from '../../tokenizer/index.js';
2
+
3
+ const ASTERISK = 0x002A; // U+002A ASTERISK (*)
4
+ const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
5
+
6
+
7
+ export const name = 'Comment';
8
+ export const structure = {
9
+ value: String
10
+ };
11
+
12
+ export function parse() {
13
+ const start = this.tokenStart;
14
+ let end = this.tokenEnd;
15
+
16
+ this.eat(Comment);
17
+
18
+ if ((end - start + 2) >= 2 &&
19
+ this.charCodeAt(end - 2) === ASTERISK &&
20
+ this.charCodeAt(end - 1) === SOLIDUS) {
21
+ end -= 2;
22
+ }
23
+
24
+ return {
25
+ type: 'Comment',
26
+ loc: this.getLocation(start, this.tokenStart),
27
+ value: this.substring(start + 2, end)
28
+ };
29
+ }
30
+
31
+ export function generate(node) {
32
+ this.token(Comment, '/*' + node.value + '*/');
33
+ }
@@ -0,0 +1,123 @@
1
+ import {
2
+ WhiteSpace,
3
+ Comment,
4
+ Ident,
5
+ LeftParenthesis,
6
+ RightParenthesis,
7
+ Function as FunctionToken,
8
+ Colon,
9
+ EOF
10
+ } from '../../tokenizer/index.js';
11
+
12
+ const likelyFeatureToken = new Set([Colon, RightParenthesis, EOF]);
13
+
14
+ export const name = 'Condition';
15
+ export const structure = {
16
+ kind: String,
17
+ children: [[
18
+ 'Identifier',
19
+ 'Feature',
20
+ 'FeatureFunction',
21
+ 'FeatureRange',
22
+ 'SupportsDeclaration'
23
+ ]]
24
+ };
25
+
26
+ function featureOrRange(kind) {
27
+ if (this.lookupTypeNonSC(1) === Ident &&
28
+ likelyFeatureToken.has(this.lookupTypeNonSC(2))) {
29
+ return this.Feature(kind);
30
+ }
31
+
32
+ return this.FeatureRange(kind);
33
+ }
34
+
35
+ const parentheses = {
36
+ media: featureOrRange,
37
+ container: featureOrRange,
38
+ supports() {
39
+ return this.SupportsDeclaration();
40
+ }
41
+ };
42
+
43
+ export function parse(kind = 'media') {
44
+ const children = this.createList();
45
+
46
+ scan: while (!this.eof) {
47
+ switch (this.tokenType) {
48
+ case Comment:
49
+ case WhiteSpace:
50
+ this.next();
51
+ continue;
52
+
53
+ case Ident:
54
+ children.push(this.Identifier());
55
+ break;
56
+
57
+ case LeftParenthesis: {
58
+ let term = this.parseWithFallback(
59
+ () => parentheses[kind].call(this, kind),
60
+ () => null
61
+ );
62
+
63
+ if (!term) {
64
+ term = this.parseWithFallback(
65
+ () => {
66
+ this.eat(LeftParenthesis);
67
+ const res = this.Condition(kind);
68
+ this.eat(RightParenthesis);
69
+ return res;
70
+ },
71
+ () => {
72
+ return this.GeneralEnclosed(kind);
73
+ }
74
+ );
75
+ }
76
+
77
+ children.push(term);
78
+ break;
79
+ }
80
+
81
+ case FunctionToken: {
82
+ let term = this.parseWithFallback(
83
+ () => this.FeatureFunction(kind),
84
+ () => null
85
+ );
86
+
87
+ if (!term) {
88
+ term = this.GeneralEnclosed(kind);
89
+ }
90
+
91
+ children.push(term);
92
+ break;
93
+ }
94
+
95
+ default:
96
+ break scan;
97
+ }
98
+ }
99
+
100
+ if (children.isEmpty) {
101
+ this.error('Condition is expected');
102
+ }
103
+
104
+ return {
105
+ type: 'Condition',
106
+ loc: this.getLocationFromList(children),
107
+ kind,
108
+ children
109
+ };
110
+ }
111
+
112
+ export function generate(node) {
113
+ node.children.forEach(child => {
114
+ if (child.type === 'Condition') {
115
+ this.token(LeftParenthesis, '(');
116
+ this.node(child);
117
+ this.token(RightParenthesis, ')');
118
+ } else {
119
+ this.node(child);
120
+ }
121
+ });
122
+ }
123
+