@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,113 @@
1
+ 'use strict';
2
+
3
+ const keywords = new Map();
4
+ const properties = new Map();
5
+ const HYPHENMINUS = 45; // '-'.charCodeAt()
6
+
7
+ const keyword = getKeywordDescriptor;
8
+ const property = getPropertyDescriptor;
9
+ const vendorPrefix = getVendorPrefix;
10
+ function isCustomProperty(str, offset) {
11
+ offset = offset || 0;
12
+
13
+ return str.length - offset >= 2 &&
14
+ str.charCodeAt(offset) === HYPHENMINUS &&
15
+ str.charCodeAt(offset + 1) === HYPHENMINUS;
16
+ }
17
+
18
+ function getVendorPrefix(str, offset) {
19
+ offset = offset || 0;
20
+
21
+ // verdor prefix should be at least 3 chars length
22
+ if (str.length - offset >= 3) {
23
+ // vendor prefix starts with hyper minus following non-hyper minus
24
+ if (str.charCodeAt(offset) === HYPHENMINUS &&
25
+ str.charCodeAt(offset + 1) !== HYPHENMINUS) {
26
+ // vendor prefix should contain a hyper minus at the ending
27
+ const secondDashIndex = str.indexOf('-', offset + 2);
28
+
29
+ if (secondDashIndex !== -1) {
30
+ return str.substring(offset, secondDashIndex + 1);
31
+ }
32
+ }
33
+ }
34
+
35
+ return '';
36
+ }
37
+
38
+ function getKeywordDescriptor(keyword) {
39
+ if (keywords.has(keyword)) {
40
+ return keywords.get(keyword);
41
+ }
42
+
43
+ const name = keyword.toLowerCase();
44
+ let descriptor = keywords.get(name);
45
+
46
+ if (descriptor === undefined) {
47
+ const custom = isCustomProperty(name, 0);
48
+ const vendor = !custom ? getVendorPrefix(name, 0) : '';
49
+ descriptor = Object.freeze({
50
+ basename: name.substr(vendor.length),
51
+ name,
52
+ prefix: vendor,
53
+ vendor,
54
+ custom
55
+ });
56
+ }
57
+
58
+ keywords.set(keyword, descriptor);
59
+
60
+ return descriptor;
61
+ }
62
+
63
+ function getPropertyDescriptor(property) {
64
+ if (properties.has(property)) {
65
+ return properties.get(property);
66
+ }
67
+
68
+ let name = property;
69
+ let hack = property[0];
70
+
71
+ if (hack === '/') {
72
+ hack = property[1] === '/' ? '//' : '/';
73
+ } else if (hack !== '_' &&
74
+ hack !== '*' &&
75
+ hack !== '$' &&
76
+ hack !== '#' &&
77
+ hack !== '+' &&
78
+ hack !== '&') {
79
+ hack = '';
80
+ }
81
+
82
+ const custom = isCustomProperty(name, hack.length);
83
+
84
+ // re-use result when possible (the same as for lower case)
85
+ if (!custom) {
86
+ name = name.toLowerCase();
87
+ if (properties.has(name)) {
88
+ const descriptor = properties.get(name);
89
+ properties.set(property, descriptor);
90
+ return descriptor;
91
+ }
92
+ }
93
+
94
+ const vendor = !custom ? getVendorPrefix(name, hack.length) : '';
95
+ const prefix = name.substr(0, hack.length + vendor.length);
96
+ const descriptor = Object.freeze({
97
+ basename: name.substr(prefix.length),
98
+ name: name.substr(hack.length),
99
+ hack,
100
+ vendor,
101
+ prefix,
102
+ custom
103
+ });
104
+
105
+ properties.set(property, descriptor);
106
+
107
+ return descriptor;
108
+ }
109
+
110
+ exports.isCustomProperty = isCustomProperty;
111
+ exports.keyword = keyword;
112
+ exports.property = property;
113
+ exports.vendorPrefix = vendorPrefix;
@@ -0,0 +1,99 @@
1
+ 'use strict';
2
+
3
+ const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs');
4
+ const utils = require('../tokenizer/utils.cjs');
5
+
6
+ const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\)
7
+ const QUOTATION_MARK = 0x0022; // "
8
+ const APOSTROPHE = 0x0027; // '
9
+
10
+ function decode(str) {
11
+ const len = str.length;
12
+ const firstChar = str.charCodeAt(0);
13
+ const start = firstChar === QUOTATION_MARK || firstChar === APOSTROPHE ? 1 : 0;
14
+ const end = start === 1 && len > 1 && str.charCodeAt(len - 1) === firstChar ? len - 2 : len - 1;
15
+ let decoded = '';
16
+
17
+ for (let i = start; i <= end; i++) {
18
+ let code = str.charCodeAt(i);
19
+
20
+ if (code === REVERSE_SOLIDUS) {
21
+ // special case at the ending
22
+ if (i === end) {
23
+ // if the next input code point is EOF, do nothing
24
+ // otherwise include last quote as escaped
25
+ if (i !== len - 1) {
26
+ decoded = str.substr(i + 1);
27
+ }
28
+ break;
29
+ }
30
+
31
+ code = str.charCodeAt(++i);
32
+
33
+ // consume escaped
34
+ if (charCodeDefinitions.isValidEscape(REVERSE_SOLIDUS, code)) {
35
+ const escapeStart = i - 1;
36
+ const escapeEnd = utils.consumeEscaped(str, escapeStart);
37
+
38
+ i = escapeEnd - 1;
39
+ decoded += utils.decodeEscaped(str.substring(escapeStart + 1, escapeEnd));
40
+ } else {
41
+ // \r\n
42
+ if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {
43
+ i++;
44
+ }
45
+ }
46
+ } else {
47
+ decoded += str[i];
48
+ }
49
+ }
50
+
51
+ return decoded;
52
+ }
53
+
54
+ // https://drafts.csswg.org/cssom/#serialize-a-string
55
+ // § 2.1. Common Serializing Idioms
56
+ function encode(str, apostrophe) {
57
+ const quote = apostrophe ? '\'' : '"';
58
+ const quoteCode = apostrophe ? APOSTROPHE : QUOTATION_MARK;
59
+ let encoded = '';
60
+ let wsBeforeHexIsNeeded = false;
61
+
62
+ for (let i = 0; i < str.length; i++) {
63
+ const code = str.charCodeAt(i);
64
+
65
+ // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).
66
+ if (code === 0x0000) {
67
+ encoded += '\uFFFD';
68
+ continue;
69
+ }
70
+
71
+ // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F,
72
+ // the character escaped as code point.
73
+ // Note: Do not compare with 0x0001 since 0x0000 is precessed before
74
+ if (code <= 0x001f || code === 0x007F) {
75
+ encoded += '\\' + code.toString(16);
76
+ wsBeforeHexIsNeeded = true;
77
+ continue;
78
+ }
79
+
80
+ // If the character is '"' (U+0022) or "\" (U+005C), the escaped character.
81
+ if (code === quoteCode || code === REVERSE_SOLIDUS) {
82
+ encoded += '\\' + str.charAt(i);
83
+ wsBeforeHexIsNeeded = false;
84
+ } else {
85
+ if (wsBeforeHexIsNeeded && (charCodeDefinitions.isHexDigit(code) || charCodeDefinitions.isWhiteSpace(code))) {
86
+ encoded += ' ';
87
+ }
88
+
89
+ // Otherwise, the character itself.
90
+ encoded += str.charAt(i);
91
+ wsBeforeHexIsNeeded = false;
92
+ }
93
+ }
94
+
95
+ return quote + encoded + quote;
96
+ }
97
+
98
+ exports.decode = decode;
99
+ exports.encode = encode;
@@ -0,0 +1,108 @@
1
+ 'use strict';
2
+
3
+ const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs');
4
+ const utils = require('../tokenizer/utils.cjs');
5
+
6
+ const SPACE = 0x0020; // U+0020 SPACE
7
+ const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\)
8
+ const QUOTATION_MARK = 0x0022; // "
9
+ const APOSTROPHE = 0x0027; // '
10
+ const LEFTPARENTHESIS = 0x0028; // U+0028 LEFT PARENTHESIS (()
11
+ const RIGHTPARENTHESIS = 0x0029; // U+0029 RIGHT PARENTHESIS ())
12
+
13
+ function decode(str) {
14
+ const len = str.length;
15
+ let start = 4; // length of "url("
16
+ let end = str.charCodeAt(len - 1) === RIGHTPARENTHESIS ? len - 2 : len - 1;
17
+ let decoded = '';
18
+
19
+ while (start < end && charCodeDefinitions.isWhiteSpace(str.charCodeAt(start))) {
20
+ start++;
21
+ }
22
+
23
+ while (start < end && charCodeDefinitions.isWhiteSpace(str.charCodeAt(end))) {
24
+ end--;
25
+ }
26
+
27
+ for (let i = start; i <= end; i++) {
28
+ let code = str.charCodeAt(i);
29
+
30
+ if (code === REVERSE_SOLIDUS) {
31
+ // special case at the ending
32
+ if (i === end) {
33
+ // if the next input code point is EOF, do nothing
34
+ // otherwise include last left parenthesis as escaped
35
+ if (i !== len - 1) {
36
+ decoded = str.substr(i + 1);
37
+ }
38
+ break;
39
+ }
40
+
41
+ code = str.charCodeAt(++i);
42
+
43
+ // consume escaped
44
+ if (charCodeDefinitions.isValidEscape(REVERSE_SOLIDUS, code)) {
45
+ const escapeStart = i - 1;
46
+ const escapeEnd = utils.consumeEscaped(str, escapeStart);
47
+
48
+ i = escapeEnd - 1;
49
+ decoded += utils.decodeEscaped(str.substring(escapeStart + 1, escapeEnd));
50
+ } else {
51
+ // \r\n
52
+ if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {
53
+ i++;
54
+ }
55
+ }
56
+ } else {
57
+ decoded += str[i];
58
+ }
59
+ }
60
+
61
+ return decoded;
62
+ }
63
+
64
+ function encode(str) {
65
+ let encoded = '';
66
+ let wsBeforeHexIsNeeded = false;
67
+
68
+ for (let i = 0; i < str.length; i++) {
69
+ const code = str.charCodeAt(i);
70
+
71
+ // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).
72
+ if (code === 0x0000) {
73
+ encoded += '\uFFFD';
74
+ continue;
75
+ }
76
+
77
+ // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F,
78
+ // the character escaped as code point.
79
+ // Note: Do not compare with 0x0001 since 0x0000 is precessed before
80
+ if (code <= 0x001f || code === 0x007F) {
81
+ encoded += '\\' + code.toString(16);
82
+ wsBeforeHexIsNeeded = true;
83
+ continue;
84
+ }
85
+
86
+ if (code === SPACE ||
87
+ code === REVERSE_SOLIDUS ||
88
+ code === QUOTATION_MARK ||
89
+ code === APOSTROPHE ||
90
+ code === LEFTPARENTHESIS ||
91
+ code === RIGHTPARENTHESIS) {
92
+ encoded += '\\' + str.charAt(i);
93
+ wsBeforeHexIsNeeded = false;
94
+ } else {
95
+ if (wsBeforeHexIsNeeded && charCodeDefinitions.isHexDigit(code)) {
96
+ encoded += ' ';
97
+ }
98
+
99
+ encoded += str.charAt(i);
100
+ wsBeforeHexIsNeeded = false;
101
+ }
102
+ }
103
+
104
+ return 'url(' + encoded + ')';
105
+ }
106
+
107
+ exports.decode = decode;
108
+ exports.encode = encode;
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ const { version } = require('../package.json');
4
+
5
+ exports.version = version;
@@ -0,0 +1,291 @@
1
+ 'use strict';
2
+
3
+ const { hasOwnProperty } = Object.prototype;
4
+ const noop = function() {};
5
+
6
+ function ensureFunction(value) {
7
+ return typeof value === 'function' ? value : noop;
8
+ }
9
+
10
+ function invokeForType(fn, type) {
11
+ return function(node, item, list) {
12
+ if (node.type === type) {
13
+ fn.call(this, node, item, list);
14
+ }
15
+ };
16
+ }
17
+
18
+ function getWalkersFromStructure(name, nodeType) {
19
+ const structure = nodeType.structure;
20
+ const walkers = [];
21
+
22
+ for (const key in structure) {
23
+ if (hasOwnProperty.call(structure, key) === false) {
24
+ continue;
25
+ }
26
+
27
+ let fieldTypes = structure[key];
28
+ const walker = {
29
+ name: key,
30
+ type: false,
31
+ nullable: false
32
+ };
33
+
34
+ if (!Array.isArray(fieldTypes)) {
35
+ fieldTypes = [fieldTypes];
36
+ }
37
+
38
+ for (const fieldType of fieldTypes) {
39
+ if (fieldType === null) {
40
+ walker.nullable = true;
41
+ } else if (typeof fieldType === 'string') {
42
+ walker.type = 'node';
43
+ } else if (Array.isArray(fieldType)) {
44
+ walker.type = 'list';
45
+ }
46
+ }
47
+
48
+ if (walker.type) {
49
+ walkers.push(walker);
50
+ }
51
+ }
52
+
53
+ if (walkers.length) {
54
+ return {
55
+ context: nodeType.walkContext,
56
+ fields: walkers
57
+ };
58
+ }
59
+
60
+ return null;
61
+ }
62
+
63
+ function getTypesFromConfig(config) {
64
+ const types = {};
65
+
66
+ for (const name in config.node) {
67
+ if (hasOwnProperty.call(config.node, name)) {
68
+ const nodeType = config.node[name];
69
+
70
+ if (!nodeType.structure) {
71
+ throw new Error('Missed `structure` field in `' + name + '` node type definition');
72
+ }
73
+
74
+ types[name] = getWalkersFromStructure(name, nodeType);
75
+ }
76
+ }
77
+
78
+ return types;
79
+ }
80
+
81
+ function createTypeIterator(config, reverse) {
82
+ const fields = config.fields.slice();
83
+ const contextName = config.context;
84
+ const useContext = typeof contextName === 'string';
85
+
86
+ if (reverse) {
87
+ fields.reverse();
88
+ }
89
+
90
+ return function(node, context, walk, walkReducer) {
91
+ let prevContextValue;
92
+
93
+ if (useContext) {
94
+ prevContextValue = context[contextName];
95
+ context[contextName] = node;
96
+ }
97
+
98
+ for (const field of fields) {
99
+ const ref = node[field.name];
100
+
101
+ if (!field.nullable || ref) {
102
+ if (field.type === 'list') {
103
+ const breakWalk = reverse
104
+ ? ref.reduceRight(walkReducer, false)
105
+ : ref.reduce(walkReducer, false);
106
+
107
+ if (breakWalk) {
108
+ return true;
109
+ }
110
+ } else if (walk(ref)) {
111
+ return true;
112
+ }
113
+ }
114
+ }
115
+
116
+ if (useContext) {
117
+ context[contextName] = prevContextValue;
118
+ }
119
+ };
120
+ }
121
+
122
+ function createFastTraveralMap({
123
+ StyleSheet,
124
+ Atrule,
125
+ Rule,
126
+ Block,
127
+ DeclarationList
128
+ }) {
129
+ return {
130
+ Atrule: {
131
+ StyleSheet,
132
+ Atrule,
133
+ Rule,
134
+ Block
135
+ },
136
+ Rule: {
137
+ StyleSheet,
138
+ Atrule,
139
+ Rule,
140
+ Block
141
+ },
142
+ Declaration: {
143
+ StyleSheet,
144
+ Atrule,
145
+ Rule,
146
+ Block,
147
+ DeclarationList
148
+ }
149
+ };
150
+ }
151
+
152
+ function createWalker(config) {
153
+ const types = getTypesFromConfig(config);
154
+ const iteratorsNatural = {};
155
+ const iteratorsReverse = {};
156
+ const breakWalk = Symbol('break-walk');
157
+ const skipNode = Symbol('skip-node');
158
+
159
+ for (const name in types) {
160
+ if (hasOwnProperty.call(types, name) && types[name] !== null) {
161
+ iteratorsNatural[name] = createTypeIterator(types[name], false);
162
+ iteratorsReverse[name] = createTypeIterator(types[name], true);
163
+ }
164
+ }
165
+
166
+ const fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
167
+ const fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
168
+
169
+ const walk = function(root, options) {
170
+ function walkNode(node, item, list) {
171
+ const enterRet = enter.call(context, node, item, list);
172
+
173
+ if (enterRet === breakWalk) {
174
+ return true;
175
+ }
176
+
177
+ if (enterRet === skipNode) {
178
+ return false;
179
+ }
180
+
181
+ if (iterators.hasOwnProperty(node.type)) {
182
+ if (iterators[node.type](node, context, walkNode, walkReducer)) {
183
+ return true;
184
+ }
185
+ }
186
+
187
+ if (leave.call(context, node, item, list) === breakWalk) {
188
+ return true;
189
+ }
190
+
191
+ return false;
192
+ }
193
+
194
+ let enter = noop;
195
+ let leave = noop;
196
+ let iterators = iteratorsNatural;
197
+ let walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list);
198
+ const context = {
199
+ break: breakWalk,
200
+ skip: skipNode,
201
+
202
+ root,
203
+ stylesheet: null,
204
+ atrule: null,
205
+ atrulePrelude: null,
206
+ rule: null,
207
+ selector: null,
208
+ block: null,
209
+ declaration: null,
210
+ function: null
211
+ };
212
+
213
+ if (typeof options === 'function') {
214
+ enter = options;
215
+ } else if (options) {
216
+ enter = ensureFunction(options.enter);
217
+ leave = ensureFunction(options.leave);
218
+
219
+ if (options.reverse) {
220
+ iterators = iteratorsReverse;
221
+ }
222
+
223
+ if (options.visit) {
224
+ if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
225
+ iterators = options.reverse
226
+ ? fastTraversalIteratorsReverse[options.visit]
227
+ : fastTraversalIteratorsNatural[options.visit];
228
+ } else if (!types.hasOwnProperty(options.visit)) {
229
+ throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).sort().join(', ') + ')');
230
+ }
231
+
232
+ enter = invokeForType(enter, options.visit);
233
+ leave = invokeForType(leave, options.visit);
234
+ }
235
+ }
236
+
237
+ if (enter === noop && leave === noop) {
238
+ throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
239
+ }
240
+
241
+ walkNode(root);
242
+ };
243
+
244
+ walk.break = breakWalk;
245
+ walk.skip = skipNode;
246
+
247
+ walk.find = function(ast, fn) {
248
+ let found = null;
249
+
250
+ walk(ast, function(node, item, list) {
251
+ if (fn.call(this, node, item, list)) {
252
+ found = node;
253
+ return breakWalk;
254
+ }
255
+ });
256
+
257
+ return found;
258
+ };
259
+
260
+ walk.findLast = function(ast, fn) {
261
+ let found = null;
262
+
263
+ walk(ast, {
264
+ reverse: true,
265
+ enter(node, item, list) {
266
+ if (fn.call(this, node, item, list)) {
267
+ found = node;
268
+ return breakWalk;
269
+ }
270
+ }
271
+ });
272
+
273
+ return found;
274
+ };
275
+
276
+ walk.findAll = function(ast, fn) {
277
+ const found = [];
278
+
279
+ walk(ast, function(node, item, list) {
280
+ if (fn.call(this, node, item, list)) {
281
+ found.push(node);
282
+ }
283
+ });
284
+
285
+ return found;
286
+ };
287
+
288
+ return walk;
289
+ }
290
+
291
+ exports.createWalker = createWalker;
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ const create = require('./create.cjs');
4
+ const walker$1 = require('../syntax/config/walker.cjs');
5
+
6
+ const walker = create.createWalker(walker$1);
7
+
8
+ module.exports = walker;