@jesscss/core 2.0.0-alpha.5 → 2.0.0-alpha.6

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 (637) hide show
  1. package/lib/index.cjs +20159 -0
  2. package/lib/index.d.cts +5993 -0
  3. package/lib/index.d.cts.map +1 -0
  4. package/lib/index.d.ts +5992 -21
  5. package/lib/index.d.ts.map +1 -1
  6. package/lib/index.js +19926 -22
  7. package/lib/index.js.map +1 -1
  8. package/package.json +15 -14
  9. package/src/__tests__/define-function-record.test.ts +58 -0
  10. package/src/__tests__/define-function-simple.test.ts +55 -0
  11. package/src/__tests__/define-function-split-sequence.test.ts +547 -0
  12. package/src/__tests__/define-function-type-parity.test.ts +9 -0
  13. package/src/__tests__/define-function.test.ts +763 -0
  14. package/src/__tests__/num-operations.test.ts +91 -0
  15. package/src/__tests__/safe-parse.test.ts +374 -0
  16. package/src/context.ts +896 -0
  17. package/src/conversions.ts +282 -0
  18. package/src/debug-log.ts +29 -0
  19. package/src/define-function.ts +1006 -0
  20. package/src/deprecation.ts +67 -0
  21. package/src/globals.d.ts +26 -0
  22. package/src/index.ts +31 -0
  23. package/src/jess-error.ts +773 -0
  24. package/src/logger/deprecation-processing.ts +109 -0
  25. package/src/logger.ts +31 -0
  26. package/src/plugin.ts +292 -0
  27. package/src/tree/LOOKUP_CHAINS.md +35 -0
  28. package/src/tree/README.md +18 -0
  29. package/src/tree/__tests__/__snapshots__/extend-eval-integration.test.ts.snap +1455 -0
  30. package/src/tree/__tests__/ampersand.test.ts +382 -0
  31. package/src/tree/__tests__/at-rule.test.ts +2047 -0
  32. package/src/tree/__tests__/basic-render.test.ts +212 -0
  33. package/src/tree/__tests__/block.test.ts +40 -0
  34. package/src/tree/__tests__/call.test.ts +346 -0
  35. package/src/tree/__tests__/color.test.ts +537 -0
  36. package/src/tree/__tests__/condition.test.ts +186 -0
  37. package/src/tree/__tests__/control.test.ts +564 -0
  38. package/src/tree/__tests__/declaration.test.ts +253 -0
  39. package/src/tree/__tests__/dependency-graph.test.ts +177 -0
  40. package/src/tree/__tests__/detached-rulesets.test.ts +213 -0
  41. package/src/tree/__tests__/dimension.test.ts +236 -0
  42. package/src/tree/__tests__/expression.test.ts +73 -0
  43. package/src/tree/__tests__/ext-node.test.ts +31 -0
  44. package/src/tree/__tests__/extend-eval-integration.test.ts +1033 -0
  45. package/src/tree/__tests__/extend-import-style.test.ts +929 -0
  46. package/src/tree/__tests__/extend-less-fixtures.test.ts +851 -0
  47. package/src/tree/__tests__/extend-list.test.ts +31 -0
  48. package/src/tree/__tests__/extend-roots.test.ts +1045 -0
  49. package/src/tree/__tests__/extend-rules.test.ts +740 -0
  50. package/src/tree/__tests__/func.test.ts +171 -0
  51. package/src/tree/__tests__/import-js.test.ts +33 -0
  52. package/src/tree/__tests__/import-style-test-helpers.ts +56 -0
  53. package/src/tree/__tests__/import-style.test.ts +1967 -0
  54. package/src/tree/__tests__/interpolated-reference.test.ts +44 -0
  55. package/src/tree/__tests__/interpolated.test.ts +41 -0
  56. package/src/tree/__tests__/list.test.ts +177 -0
  57. package/src/tree/__tests__/log.test.ts +83 -0
  58. package/src/tree/__tests__/mixin-recursion.test.ts +639 -0
  59. package/src/tree/__tests__/mixin.test.ts +2171 -0
  60. package/src/tree/__tests__/negative.test.ts +45 -0
  61. package/src/tree/__tests__/nesting-collapse.test.ts +519 -0
  62. package/src/tree/__tests__/node-flags-perf.test.ts +195 -0
  63. package/src/tree/__tests__/node-flags.test.ts +410 -0
  64. package/src/tree/__tests__/node-graph.test.ts +598 -0
  65. package/src/tree/__tests__/node-mutation.test.ts +182 -0
  66. package/src/tree/__tests__/operation.test.ts +18 -0
  67. package/src/tree/__tests__/paren.test.ts +90 -0
  68. package/src/tree/__tests__/preserve-mode-output.test.ts +50 -0
  69. package/src/tree/__tests__/quoted.test.ts +72 -0
  70. package/src/tree/__tests__/range.test.ts +59 -0
  71. package/src/tree/__tests__/reference.test.ts +743 -0
  72. package/src/tree/__tests__/rest.test.ts +29 -0
  73. package/src/tree/__tests__/rules-raw.test.ts +14 -0
  74. package/src/tree/__tests__/rules.test.ts +1271 -0
  75. package/src/tree/__tests__/ruleset.test.ts +597 -0
  76. package/src/tree/__tests__/selector-attr.test.ts +50 -0
  77. package/src/tree/__tests__/selector-basic.test.ts +44 -0
  78. package/src/tree/__tests__/selector-capture.test.ts +22 -0
  79. package/src/tree/__tests__/selector-complex.test.ts +120 -0
  80. package/src/tree/__tests__/selector-compound.test.ts +74 -0
  81. package/src/tree/__tests__/selector-interpolated.test.ts +50 -0
  82. package/src/tree/__tests__/selector-list.test.ts +59 -0
  83. package/src/tree/__tests__/selector-pseudo.test.ts +23 -0
  84. package/src/tree/__tests__/selector.test.ts +182 -0
  85. package/src/tree/__tests__/sequence.test.ts +226 -0
  86. package/src/tree/__tests__/serialize-types.test.ts +529 -0
  87. package/src/tree/__tests__/spaced.test.ts +8 -0
  88. package/src/tree/__tests__/url.test.ts +72 -0
  89. package/src/tree/__tests__/var-declaration.test.ts +90 -0
  90. package/src/tree/ampersand.ts +538 -0
  91. package/src/tree/any.ts +169 -0
  92. package/src/tree/at-rule.ts +760 -0
  93. package/src/tree/block.ts +72 -0
  94. package/src/tree/bool.ts +46 -0
  95. package/src/tree/call.ts +593 -0
  96. package/src/tree/collection.ts +52 -0
  97. package/src/tree/color.ts +629 -0
  98. package/src/tree/combinator.ts +30 -0
  99. package/src/tree/comment.ts +36 -0
  100. package/src/tree/condition.ts +194 -0
  101. package/src/tree/control.ts +452 -0
  102. package/src/tree/declaration-custom.ts +56 -0
  103. package/src/tree/declaration-var.ts +87 -0
  104. package/src/tree/declaration.ts +742 -0
  105. package/src/tree/default-guard.ts +35 -0
  106. package/src/tree/dimension.ts +392 -0
  107. package/src/tree/expression.ts +97 -0
  108. package/src/tree/extend-list.ts +51 -0
  109. package/src/tree/extend.ts +391 -0
  110. package/src/tree/function.ts +254 -0
  111. package/src/tree/import-js.ts +130 -0
  112. package/src/tree/import-style.ts +875 -0
  113. package/{lib/tree/index.js → src/tree/index.ts} +49 -22
  114. package/src/tree/interpolated.ts +346 -0
  115. package/src/tree/js-array.ts +21 -0
  116. package/src/tree/js-expr.ts +50 -0
  117. package/src/tree/js-function.ts +31 -0
  118. package/src/tree/js-object.ts +22 -0
  119. package/src/tree/list.ts +415 -0
  120. package/src/tree/log.ts +89 -0
  121. package/src/tree/mixin.ts +331 -0
  122. package/src/tree/negative.ts +58 -0
  123. package/src/tree/nil.ts +57 -0
  124. package/src/tree/node-base.ts +1716 -0
  125. package/src/tree/node-type.ts +122 -0
  126. package/src/tree/node.ts +118 -0
  127. package/src/tree/number.ts +54 -0
  128. package/src/tree/operation.ts +187 -0
  129. package/src/tree/paren.ts +132 -0
  130. package/src/tree/query-condition.ts +47 -0
  131. package/src/tree/quoted.ts +119 -0
  132. package/src/tree/range.ts +101 -0
  133. package/src/tree/reference.ts +1099 -0
  134. package/src/tree/rest.ts +55 -0
  135. package/src/tree/rules-raw.ts +52 -0
  136. package/src/tree/rules.ts +2896 -0
  137. package/src/tree/ruleset.ts +1217 -0
  138. package/src/tree/selector-attr.ts +172 -0
  139. package/src/tree/selector-basic.ts +75 -0
  140. package/src/tree/selector-capture.ts +85 -0
  141. package/src/tree/selector-complex.ts +189 -0
  142. package/src/tree/selector-compound.ts +205 -0
  143. package/src/tree/selector-interpolated.ts +95 -0
  144. package/src/tree/selector-list.ts +245 -0
  145. package/src/tree/selector-pseudo.ts +173 -0
  146. package/src/tree/selector-simple.ts +10 -0
  147. package/src/tree/selector.ts +152 -0
  148. package/src/tree/sequence.ts +463 -0
  149. package/src/tree/tree.ts +130 -0
  150. package/src/tree/url.ts +95 -0
  151. package/src/tree/util/EXTEND_ARCHITECTURE_ANALYSIS.md +215 -0
  152. package/src/tree/util/EXTEND_AUDIT.md +233 -0
  153. package/src/tree/util/EXTEND_BASELINE.md +64 -0
  154. package/src/tree/util/EXTEND_CALL_GRAPH_ANALYSIS.md +244 -0
  155. package/src/tree/util/EXTEND_DOCS.md +24 -0
  156. package/src/tree/util/EXTEND_FINAL_SUMMARY.md +95 -0
  157. package/src/tree/util/EXTEND_FUNCTION_AUDIT.md +1433 -0
  158. package/src/tree/util/EXTEND_OPTIMIZATION_PLAN.md +114 -0
  159. package/src/tree/util/EXTEND_REFACTORING_SUMMARY.md +152 -0
  160. package/src/tree/util/EXTEND_RULES.md +74 -0
  161. package/src/tree/util/EXTEND_UNUSED_FUNCTIONS.md +127 -0
  162. package/src/tree/util/EXTEND_UNUSED_FUNCTIONS_ANALYSIS.md +227 -0
  163. package/src/tree/util/NODE_COPY_REDUCTION_PLAN.md +12 -0
  164. package/src/tree/util/__tests__/EXTEND_TEST_INDEX.md +59 -0
  165. package/src/tree/util/__tests__/OPTIMIZATION-ANALYSIS.md +130 -0
  166. package/src/tree/util/__tests__/WALK_AND_CONSUME_DESIGN.md +138 -0
  167. package/src/tree/util/__tests__/_archive/2026-02-09__OPTIMIZATION-ANALYSIS.md +9 -0
  168. package/src/tree/util/__tests__/_archive/README.md +4 -0
  169. package/src/tree/util/__tests__/bitset.test.ts +142 -0
  170. package/src/tree/util/__tests__/debug-log.ts +50 -0
  171. package/src/tree/util/__tests__/extend-comment-handling.test.ts +187 -0
  172. package/src/tree/util/__tests__/extend-core-unit.test.ts +941 -0
  173. package/src/tree/util/__tests__/extend-pipeline-bench.test.ts +154 -0
  174. package/src/tree/util/__tests__/extend-pipeline-bench.ts +190 -0
  175. package/src/tree/util/__tests__/fast-reject.test.ts +377 -0
  176. package/src/tree/util/__tests__/is-node.test.ts +63 -0
  177. package/src/tree/util/__tests__/list-like.test.ts +63 -0
  178. package/src/tree/util/__tests__/outputwriter.test.ts +523 -0
  179. package/src/tree/util/__tests__/print.test.ts +183 -0
  180. package/src/tree/util/__tests__/process-extends.test.ts +226 -0
  181. package/src/tree/util/__tests__/process-leading-is.test.ts +205 -0
  182. package/src/tree/util/__tests__/recursion-helper.test.ts +184 -0
  183. package/src/tree/util/__tests__/selector-match-unit.test.ts +1427 -0
  184. package/src/tree/util/__tests__/sourcemap.test.ts +117 -0
  185. package/src/tree/util/ampersand-template.ts +9 -0
  186. package/src/tree/util/bitset.ts +194 -0
  187. package/src/tree/util/calculate.ts +11 -0
  188. package/src/tree/util/cast.ts +89 -0
  189. package/src/tree/util/cloning.ts +8 -0
  190. package/src/tree/util/collections.ts +299 -0
  191. package/src/tree/util/compare.ts +90 -0
  192. package/src/tree/util/cursor.ts +171 -0
  193. package/src/tree/util/extend-core.ts +2139 -0
  194. package/src/tree/util/extend-roots.ts +1108 -0
  195. package/src/tree/util/field-helpers.ts +354 -0
  196. package/src/tree/util/is-node.ts +43 -0
  197. package/src/tree/util/list-like.ts +93 -0
  198. package/src/tree/util/mixin-instance-primitives.ts +2020 -0
  199. package/src/tree/util/print.ts +303 -0
  200. package/src/tree/util/process-leading-is.ts +421 -0
  201. package/src/tree/util/recursion-helper.ts +54 -0
  202. package/src/tree/util/regex.ts +2 -0
  203. package/src/tree/util/registry-utils.ts +1953 -0
  204. package/src/tree/util/ruleset-trace.ts +17 -0
  205. package/src/tree/util/scoped-body-eval.ts +320 -0
  206. package/src/tree/util/selector-match-core.ts +2005 -0
  207. package/src/tree/util/selector-utils.ts +757 -0
  208. package/src/tree/util/serialize-helper.ts +535 -0
  209. package/src/tree/util/serialize-types.ts +318 -0
  210. package/src/tree/util/should-operate.ts +78 -0
  211. package/src/tree/util/sourcemap.ts +37 -0
  212. package/src/types/config.ts +247 -0
  213. package/src/types/index.ts +12 -0
  214. package/{lib/types/modes.d.ts → src/types/modes.ts} +2 -1
  215. package/src/types.d.ts +9 -0
  216. package/src/types.ts +68 -0
  217. package/src/use-webpack-resolver.ts +56 -0
  218. package/src/visitor/__tests__/visitor.test.ts +136 -0
  219. package/src/visitor/index.ts +263 -0
  220. package/{lib/visitor/less-visitor.js → src/visitor/less-visitor.ts} +3 -2
  221. package/lib/context.d.ts +0 -352
  222. package/lib/context.d.ts.map +0 -1
  223. package/lib/context.js +0 -636
  224. package/lib/context.js.map +0 -1
  225. package/lib/conversions.d.ts +0 -73
  226. package/lib/conversions.d.ts.map +0 -1
  227. package/lib/conversions.js +0 -253
  228. package/lib/conversions.js.map +0 -1
  229. package/lib/debug-log.d.ts +0 -2
  230. package/lib/debug-log.d.ts.map +0 -1
  231. package/lib/debug-log.js +0 -27
  232. package/lib/debug-log.js.map +0 -1
  233. package/lib/define-function.d.ts +0 -587
  234. package/lib/define-function.d.ts.map +0 -1
  235. package/lib/define-function.js +0 -726
  236. package/lib/define-function.js.map +0 -1
  237. package/lib/deprecation.d.ts +0 -34
  238. package/lib/deprecation.d.ts.map +0 -1
  239. package/lib/deprecation.js +0 -57
  240. package/lib/deprecation.js.map +0 -1
  241. package/lib/jess-error.d.ts +0 -343
  242. package/lib/jess-error.d.ts.map +0 -1
  243. package/lib/jess-error.js +0 -508
  244. package/lib/jess-error.js.map +0 -1
  245. package/lib/logger/deprecation-processing.d.ts +0 -41
  246. package/lib/logger/deprecation-processing.d.ts.map +0 -1
  247. package/lib/logger/deprecation-processing.js +0 -81
  248. package/lib/logger/deprecation-processing.js.map +0 -1
  249. package/lib/logger.d.ts +0 -10
  250. package/lib/logger.d.ts.map +0 -1
  251. package/lib/logger.js +0 -20
  252. package/lib/logger.js.map +0 -1
  253. package/lib/plugin.d.ts +0 -94
  254. package/lib/plugin.d.ts.map +0 -1
  255. package/lib/plugin.js +0 -174
  256. package/lib/plugin.js.map +0 -1
  257. package/lib/tree/ampersand.d.ts +0 -98
  258. package/lib/tree/ampersand.d.ts.map +0 -1
  259. package/lib/tree/ampersand.js +0 -319
  260. package/lib/tree/ampersand.js.map +0 -1
  261. package/lib/tree/any.d.ts +0 -58
  262. package/lib/tree/any.d.ts.map +0 -1
  263. package/lib/tree/any.js +0 -104
  264. package/lib/tree/any.js.map +0 -1
  265. package/lib/tree/at-rule.d.ts +0 -53
  266. package/lib/tree/at-rule.d.ts.map +0 -1
  267. package/lib/tree/at-rule.js +0 -503
  268. package/lib/tree/at-rule.js.map +0 -1
  269. package/lib/tree/block.d.ts +0 -22
  270. package/lib/tree/block.d.ts.map +0 -1
  271. package/lib/tree/block.js +0 -24
  272. package/lib/tree/block.js.map +0 -1
  273. package/lib/tree/bool.d.ts +0 -18
  274. package/lib/tree/bool.d.ts.map +0 -1
  275. package/lib/tree/bool.js +0 -28
  276. package/lib/tree/bool.js.map +0 -1
  277. package/lib/tree/call.d.ts +0 -66
  278. package/lib/tree/call.d.ts.map +0 -1
  279. package/lib/tree/call.js +0 -306
  280. package/lib/tree/call.js.map +0 -1
  281. package/lib/tree/collection.d.ts +0 -30
  282. package/lib/tree/collection.d.ts.map +0 -1
  283. package/lib/tree/collection.js +0 -37
  284. package/lib/tree/collection.js.map +0 -1
  285. package/lib/tree/color.d.ts +0 -101
  286. package/lib/tree/color.d.ts.map +0 -1
  287. package/lib/tree/color.js +0 -513
  288. package/lib/tree/color.js.map +0 -1
  289. package/lib/tree/combinator.d.ts +0 -13
  290. package/lib/tree/combinator.d.ts.map +0 -1
  291. package/lib/tree/combinator.js +0 -12
  292. package/lib/tree/combinator.js.map +0 -1
  293. package/lib/tree/comment.d.ts +0 -20
  294. package/lib/tree/comment.d.ts.map +0 -1
  295. package/lib/tree/comment.js +0 -19
  296. package/lib/tree/comment.js.map +0 -1
  297. package/lib/tree/condition.d.ts +0 -31
  298. package/lib/tree/condition.d.ts.map +0 -1
  299. package/lib/tree/condition.js +0 -103
  300. package/lib/tree/condition.js.map +0 -1
  301. package/lib/tree/control.d.ts +0 -104
  302. package/lib/tree/control.d.ts.map +0 -1
  303. package/lib/tree/control.js +0 -430
  304. package/lib/tree/control.js.map +0 -1
  305. package/lib/tree/declaration-custom.d.ts +0 -18
  306. package/lib/tree/declaration-custom.d.ts.map +0 -1
  307. package/lib/tree/declaration-custom.js +0 -24
  308. package/lib/tree/declaration-custom.js.map +0 -1
  309. package/lib/tree/declaration-var.d.ts +0 -35
  310. package/lib/tree/declaration-var.d.ts.map +0 -1
  311. package/lib/tree/declaration-var.js +0 -63
  312. package/lib/tree/declaration-var.js.map +0 -1
  313. package/lib/tree/declaration.d.ts +0 -78
  314. package/lib/tree/declaration.d.ts.map +0 -1
  315. package/lib/tree/declaration.js +0 -286
  316. package/lib/tree/declaration.js.map +0 -1
  317. package/lib/tree/default-guard.d.ts +0 -15
  318. package/lib/tree/default-guard.d.ts.map +0 -1
  319. package/lib/tree/default-guard.js +0 -19
  320. package/lib/tree/default-guard.js.map +0 -1
  321. package/lib/tree/dimension.d.ts +0 -34
  322. package/lib/tree/dimension.d.ts.map +0 -1
  323. package/lib/tree/dimension.js +0 -294
  324. package/lib/tree/dimension.js.map +0 -1
  325. package/lib/tree/expression.d.ts +0 -25
  326. package/lib/tree/expression.d.ts.map +0 -1
  327. package/lib/tree/expression.js +0 -32
  328. package/lib/tree/expression.js.map +0 -1
  329. package/lib/tree/extend-list.d.ts +0 -23
  330. package/lib/tree/extend-list.d.ts.map +0 -1
  331. package/lib/tree/extend-list.js +0 -23
  332. package/lib/tree/extend-list.js.map +0 -1
  333. package/lib/tree/extend.d.ts +0 -47
  334. package/lib/tree/extend.d.ts.map +0 -1
  335. package/lib/tree/extend.js +0 -296
  336. package/lib/tree/extend.js.map +0 -1
  337. package/lib/tree/function.d.ts +0 -48
  338. package/lib/tree/function.d.ts.map +0 -1
  339. package/lib/tree/function.js +0 -74
  340. package/lib/tree/function.js.map +0 -1
  341. package/lib/tree/import-js.d.ts +0 -35
  342. package/lib/tree/import-js.d.ts.map +0 -1
  343. package/lib/tree/import-js.js +0 -45
  344. package/lib/tree/import-js.js.map +0 -1
  345. package/lib/tree/import-style.d.ts +0 -156
  346. package/lib/tree/import-style.d.ts.map +0 -1
  347. package/lib/tree/import-style.js +0 -566
  348. package/lib/tree/import-style.js.map +0 -1
  349. package/lib/tree/index.d.ts +0 -71
  350. package/lib/tree/index.d.ts.map +0 -1
  351. package/lib/tree/index.js.map +0 -1
  352. package/lib/tree/interpolated-reference.d.ts +0 -24
  353. package/lib/tree/interpolated-reference.d.ts.map +0 -1
  354. package/lib/tree/interpolated-reference.js +0 -37
  355. package/lib/tree/interpolated-reference.js.map +0 -1
  356. package/lib/tree/interpolated.d.ts +0 -62
  357. package/lib/tree/interpolated.d.ts.map +0 -1
  358. package/lib/tree/interpolated.js +0 -204
  359. package/lib/tree/interpolated.js.map +0 -1
  360. package/lib/tree/js-array.d.ts +0 -10
  361. package/lib/tree/js-array.d.ts.map +0 -1
  362. package/lib/tree/js-array.js +0 -10
  363. package/lib/tree/js-array.js.map +0 -1
  364. package/lib/tree/js-expr.d.ts +0 -23
  365. package/lib/tree/js-expr.d.ts.map +0 -1
  366. package/lib/tree/js-expr.js +0 -28
  367. package/lib/tree/js-expr.js.map +0 -1
  368. package/lib/tree/js-function.d.ts +0 -20
  369. package/lib/tree/js-function.d.ts.map +0 -1
  370. package/lib/tree/js-function.js +0 -16
  371. package/lib/tree/js-function.js.map +0 -1
  372. package/lib/tree/js-object.d.ts +0 -10
  373. package/lib/tree/js-object.d.ts.map +0 -1
  374. package/lib/tree/js-object.js +0 -10
  375. package/lib/tree/js-object.js.map +0 -1
  376. package/lib/tree/list.d.ts +0 -38
  377. package/lib/tree/list.d.ts.map +0 -1
  378. package/lib/tree/list.js +0 -83
  379. package/lib/tree/list.js.map +0 -1
  380. package/lib/tree/log.d.ts +0 -29
  381. package/lib/tree/log.d.ts.map +0 -1
  382. package/lib/tree/log.js +0 -56
  383. package/lib/tree/log.js.map +0 -1
  384. package/lib/tree/mixin.d.ts +0 -87
  385. package/lib/tree/mixin.d.ts.map +0 -1
  386. package/lib/tree/mixin.js +0 -112
  387. package/lib/tree/mixin.js.map +0 -1
  388. package/lib/tree/negative.d.ts +0 -17
  389. package/lib/tree/negative.d.ts.map +0 -1
  390. package/lib/tree/negative.js +0 -22
  391. package/lib/tree/negative.js.map +0 -1
  392. package/lib/tree/nil.d.ts +0 -30
  393. package/lib/tree/nil.d.ts.map +0 -1
  394. package/lib/tree/nil.js +0 -35
  395. package/lib/tree/nil.js.map +0 -1
  396. package/lib/tree/node-base.d.ts +0 -361
  397. package/lib/tree/node-base.d.ts.map +0 -1
  398. package/lib/tree/node-base.js +0 -930
  399. package/lib/tree/node-base.js.map +0 -1
  400. package/lib/tree/node.d.ts +0 -10
  401. package/lib/tree/node.d.ts.map +0 -1
  402. package/lib/tree/node.js +0 -45
  403. package/lib/tree/node.js.map +0 -1
  404. package/lib/tree/number.d.ts +0 -21
  405. package/lib/tree/number.d.ts.map +0 -1
  406. package/lib/tree/number.js +0 -27
  407. package/lib/tree/number.js.map +0 -1
  408. package/lib/tree/operation.d.ts +0 -26
  409. package/lib/tree/operation.d.ts.map +0 -1
  410. package/lib/tree/operation.js +0 -103
  411. package/lib/tree/operation.js.map +0 -1
  412. package/lib/tree/paren.d.ts +0 -19
  413. package/lib/tree/paren.d.ts.map +0 -1
  414. package/lib/tree/paren.js +0 -92
  415. package/lib/tree/paren.js.map +0 -1
  416. package/lib/tree/query-condition.d.ts +0 -17
  417. package/lib/tree/query-condition.d.ts.map +0 -1
  418. package/lib/tree/query-condition.js +0 -39
  419. package/lib/tree/query-condition.js.map +0 -1
  420. package/lib/tree/quoted.d.ts +0 -28
  421. package/lib/tree/quoted.d.ts.map +0 -1
  422. package/lib/tree/quoted.js +0 -75
  423. package/lib/tree/quoted.js.map +0 -1
  424. package/lib/tree/range.d.ts +0 -33
  425. package/lib/tree/range.d.ts.map +0 -1
  426. package/lib/tree/range.js +0 -47
  427. package/lib/tree/range.js.map +0 -1
  428. package/lib/tree/reference.d.ts +0 -76
  429. package/lib/tree/reference.d.ts.map +0 -1
  430. package/lib/tree/reference.js +0 -521
  431. package/lib/tree/reference.js.map +0 -1
  432. package/lib/tree/rest.d.ts +0 -15
  433. package/lib/tree/rest.d.ts.map +0 -1
  434. package/lib/tree/rest.js +0 -32
  435. package/lib/tree/rest.js.map +0 -1
  436. package/lib/tree/rules-raw.d.ts +0 -17
  437. package/lib/tree/rules-raw.d.ts.map +0 -1
  438. package/lib/tree/rules-raw.js +0 -37
  439. package/lib/tree/rules-raw.js.map +0 -1
  440. package/lib/tree/rules.d.ts +0 -262
  441. package/lib/tree/rules.d.ts.map +0 -1
  442. package/lib/tree/rules.js +0 -2359
  443. package/lib/tree/rules.js.map +0 -1
  444. package/lib/tree/ruleset.d.ts +0 -92
  445. package/lib/tree/ruleset.d.ts.map +0 -1
  446. package/lib/tree/ruleset.js +0 -528
  447. package/lib/tree/ruleset.js.map +0 -1
  448. package/lib/tree/selector-attr.d.ts +0 -31
  449. package/lib/tree/selector-attr.d.ts.map +0 -1
  450. package/lib/tree/selector-attr.js +0 -99
  451. package/lib/tree/selector-attr.js.map +0 -1
  452. package/lib/tree/selector-basic.d.ts +0 -24
  453. package/lib/tree/selector-basic.d.ts.map +0 -1
  454. package/lib/tree/selector-basic.js +0 -38
  455. package/lib/tree/selector-basic.js.map +0 -1
  456. package/lib/tree/selector-capture.d.ts +0 -23
  457. package/lib/tree/selector-capture.d.ts.map +0 -1
  458. package/lib/tree/selector-capture.js +0 -34
  459. package/lib/tree/selector-capture.js.map +0 -1
  460. package/lib/tree/selector-complex.d.ts +0 -40
  461. package/lib/tree/selector-complex.d.ts.map +0 -1
  462. package/lib/tree/selector-complex.js +0 -143
  463. package/lib/tree/selector-complex.js.map +0 -1
  464. package/lib/tree/selector-compound.d.ts +0 -16
  465. package/lib/tree/selector-compound.d.ts.map +0 -1
  466. package/lib/tree/selector-compound.js +0 -114
  467. package/lib/tree/selector-compound.js.map +0 -1
  468. package/lib/tree/selector-interpolated.d.ts +0 -23
  469. package/lib/tree/selector-interpolated.d.ts.map +0 -1
  470. package/lib/tree/selector-interpolated.js +0 -27
  471. package/lib/tree/selector-interpolated.js.map +0 -1
  472. package/lib/tree/selector-list.d.ts +0 -17
  473. package/lib/tree/selector-list.d.ts.map +0 -1
  474. package/lib/tree/selector-list.js +0 -174
  475. package/lib/tree/selector-list.js.map +0 -1
  476. package/lib/tree/selector-pseudo.d.ts +0 -42
  477. package/lib/tree/selector-pseudo.d.ts.map +0 -1
  478. package/lib/tree/selector-pseudo.js +0 -204
  479. package/lib/tree/selector-pseudo.js.map +0 -1
  480. package/lib/tree/selector-simple.d.ts +0 -5
  481. package/lib/tree/selector-simple.d.ts.map +0 -1
  482. package/lib/tree/selector-simple.js +0 -6
  483. package/lib/tree/selector-simple.js.map +0 -1
  484. package/lib/tree/selector.d.ts +0 -43
  485. package/lib/tree/selector.d.ts.map +0 -1
  486. package/lib/tree/selector.js +0 -56
  487. package/lib/tree/selector.js.map +0 -1
  488. package/lib/tree/sequence.d.ts +0 -43
  489. package/lib/tree/sequence.d.ts.map +0 -1
  490. package/lib/tree/sequence.js +0 -151
  491. package/lib/tree/sequence.js.map +0 -1
  492. package/lib/tree/tree.d.ts +0 -87
  493. package/lib/tree/tree.d.ts.map +0 -1
  494. package/lib/tree/tree.js +0 -2
  495. package/lib/tree/tree.js.map +0 -1
  496. package/lib/tree/url.d.ts +0 -18
  497. package/lib/tree/url.d.ts.map +0 -1
  498. package/lib/tree/url.js +0 -35
  499. package/lib/tree/url.js.map +0 -1
  500. package/lib/tree/util/__tests__/debug-log.d.ts +0 -1
  501. package/lib/tree/util/__tests__/debug-log.d.ts.map +0 -1
  502. package/lib/tree/util/__tests__/debug-log.js +0 -36
  503. package/lib/tree/util/__tests__/debug-log.js.map +0 -1
  504. package/lib/tree/util/calculate.d.ts +0 -3
  505. package/lib/tree/util/calculate.d.ts.map +0 -1
  506. package/lib/tree/util/calculate.js +0 -10
  507. package/lib/tree/util/calculate.js.map +0 -1
  508. package/lib/tree/util/cast.d.ts +0 -10
  509. package/lib/tree/util/cast.d.ts.map +0 -1
  510. package/lib/tree/util/cast.js +0 -87
  511. package/lib/tree/util/cast.js.map +0 -1
  512. package/lib/tree/util/cloning.d.ts +0 -4
  513. package/lib/tree/util/cloning.d.ts.map +0 -1
  514. package/lib/tree/util/cloning.js +0 -8
  515. package/lib/tree/util/cloning.js.map +0 -1
  516. package/lib/tree/util/collections.d.ts +0 -57
  517. package/lib/tree/util/collections.d.ts.map +0 -1
  518. package/lib/tree/util/collections.js +0 -136
  519. package/lib/tree/util/collections.js.map +0 -1
  520. package/lib/tree/util/compare.d.ts +0 -11
  521. package/lib/tree/util/compare.d.ts.map +0 -1
  522. package/lib/tree/util/compare.js +0 -89
  523. package/lib/tree/util/compare.js.map +0 -1
  524. package/lib/tree/util/extend-helpers.d.ts +0 -2
  525. package/lib/tree/util/extend-helpers.d.ts.map +0 -1
  526. package/lib/tree/util/extend-helpers.js +0 -2
  527. package/lib/tree/util/extend-helpers.js.map +0 -1
  528. package/lib/tree/util/extend-roots.d.ts +0 -37
  529. package/lib/tree/util/extend-roots.d.ts.map +0 -1
  530. package/lib/tree/util/extend-roots.js +0 -700
  531. package/lib/tree/util/extend-roots.js.map +0 -1
  532. package/lib/tree/util/extend-roots.old.d.ts +0 -132
  533. package/lib/tree/util/extend-roots.old.d.ts.map +0 -1
  534. package/lib/tree/util/extend-roots.old.js +0 -2272
  535. package/lib/tree/util/extend-roots.old.js.map +0 -1
  536. package/lib/tree/util/extend-trace-debug.d.ts +0 -13
  537. package/lib/tree/util/extend-trace-debug.d.ts.map +0 -1
  538. package/lib/tree/util/extend-trace-debug.js +0 -34
  539. package/lib/tree/util/extend-trace-debug.js.map +0 -1
  540. package/lib/tree/util/extend-walk.d.ts +0 -53
  541. package/lib/tree/util/extend-walk.d.ts.map +0 -1
  542. package/lib/tree/util/extend-walk.js +0 -881
  543. package/lib/tree/util/extend-walk.js.map +0 -1
  544. package/lib/tree/util/extend.d.ts +0 -218
  545. package/lib/tree/util/extend.d.ts.map +0 -1
  546. package/lib/tree/util/extend.js +0 -3182
  547. package/lib/tree/util/extend.js.map +0 -1
  548. package/lib/tree/util/find-extendable-locations.d.ts +0 -2
  549. package/lib/tree/util/find-extendable-locations.d.ts.map +0 -1
  550. package/lib/tree/util/find-extendable-locations.js +0 -2
  551. package/lib/tree/util/find-extendable-locations.js.map +0 -1
  552. package/lib/tree/util/format.d.ts +0 -20
  553. package/lib/tree/util/format.d.ts.map +0 -1
  554. package/lib/tree/util/format.js +0 -67
  555. package/lib/tree/util/format.js.map +0 -1
  556. package/lib/tree/util/is-node.d.ts +0 -13
  557. package/lib/tree/util/is-node.d.ts.map +0 -1
  558. package/lib/tree/util/is-node.js +0 -43
  559. package/lib/tree/util/is-node.js.map +0 -1
  560. package/lib/tree/util/print.d.ts +0 -80
  561. package/lib/tree/util/print.d.ts.map +0 -1
  562. package/lib/tree/util/print.js +0 -205
  563. package/lib/tree/util/print.js.map +0 -1
  564. package/lib/tree/util/process-leading-is.d.ts +0 -25
  565. package/lib/tree/util/process-leading-is.d.ts.map +0 -1
  566. package/lib/tree/util/process-leading-is.js +0 -364
  567. package/lib/tree/util/process-leading-is.js.map +0 -1
  568. package/lib/tree/util/recursion-helper.d.ts +0 -15
  569. package/lib/tree/util/recursion-helper.d.ts.map +0 -1
  570. package/lib/tree/util/recursion-helper.js +0 -43
  571. package/lib/tree/util/recursion-helper.js.map +0 -1
  572. package/lib/tree/util/regex.d.ts +0 -4
  573. package/lib/tree/util/regex.d.ts.map +0 -1
  574. package/lib/tree/util/regex.js +0 -4
  575. package/lib/tree/util/regex.js.map +0 -1
  576. package/lib/tree/util/registry-utils.d.ts +0 -192
  577. package/lib/tree/util/registry-utils.d.ts.map +0 -1
  578. package/lib/tree/util/registry-utils.js +0 -1214
  579. package/lib/tree/util/registry-utils.js.map +0 -1
  580. package/lib/tree/util/ruleset-trace.d.ts +0 -4
  581. package/lib/tree/util/ruleset-trace.d.ts.map +0 -1
  582. package/lib/tree/util/ruleset-trace.js +0 -14
  583. package/lib/tree/util/ruleset-trace.js.map +0 -1
  584. package/lib/tree/util/selector-compare.d.ts +0 -2
  585. package/lib/tree/util/selector-compare.d.ts.map +0 -1
  586. package/lib/tree/util/selector-compare.js +0 -2
  587. package/lib/tree/util/selector-compare.js.map +0 -1
  588. package/lib/tree/util/selector-match-core.d.ts +0 -184
  589. package/lib/tree/util/selector-match-core.d.ts.map +0 -1
  590. package/lib/tree/util/selector-match-core.js +0 -1603
  591. package/lib/tree/util/selector-match-core.js.map +0 -1
  592. package/lib/tree/util/selector-utils.d.ts +0 -30
  593. package/lib/tree/util/selector-utils.d.ts.map +0 -1
  594. package/lib/tree/util/selector-utils.js +0 -100
  595. package/lib/tree/util/selector-utils.js.map +0 -1
  596. package/lib/tree/util/serialize-helper.d.ts +0 -13
  597. package/lib/tree/util/serialize-helper.d.ts.map +0 -1
  598. package/lib/tree/util/serialize-helper.js +0 -387
  599. package/lib/tree/util/serialize-helper.js.map +0 -1
  600. package/lib/tree/util/serialize-types.d.ts +0 -9
  601. package/lib/tree/util/serialize-types.d.ts.map +0 -1
  602. package/lib/tree/util/serialize-types.js +0 -216
  603. package/lib/tree/util/serialize-types.js.map +0 -1
  604. package/lib/tree/util/should-operate.d.ts +0 -23
  605. package/lib/tree/util/should-operate.d.ts.map +0 -1
  606. package/lib/tree/util/should-operate.js +0 -46
  607. package/lib/tree/util/should-operate.js.map +0 -1
  608. package/lib/tree/util/sourcemap.d.ts +0 -7
  609. package/lib/tree/util/sourcemap.d.ts.map +0 -1
  610. package/lib/tree/util/sourcemap.js +0 -25
  611. package/lib/tree/util/sourcemap.js.map +0 -1
  612. package/lib/types/config.d.ts +0 -205
  613. package/lib/types/config.d.ts.map +0 -1
  614. package/lib/types/config.js +0 -2
  615. package/lib/types/config.js.map +0 -1
  616. package/lib/types/index.d.ts +0 -15
  617. package/lib/types/index.d.ts.map +0 -1
  618. package/lib/types/index.js +0 -3
  619. package/lib/types/index.js.map +0 -1
  620. package/lib/types/modes.d.ts.map +0 -1
  621. package/lib/types/modes.js +0 -2
  622. package/lib/types/modes.js.map +0 -1
  623. package/lib/types.d.ts +0 -61
  624. package/lib/types.d.ts.map +0 -1
  625. package/lib/types.js +0 -2
  626. package/lib/types.js.map +0 -1
  627. package/lib/use-webpack-resolver.d.ts +0 -9
  628. package/lib/use-webpack-resolver.d.ts.map +0 -1
  629. package/lib/use-webpack-resolver.js +0 -41
  630. package/lib/use-webpack-resolver.js.map +0 -1
  631. package/lib/visitor/index.d.ts +0 -136
  632. package/lib/visitor/index.d.ts.map +0 -1
  633. package/lib/visitor/index.js +0 -135
  634. package/lib/visitor/index.js.map +0 -1
  635. package/lib/visitor/less-visitor.d.ts +0 -7
  636. package/lib/visitor/less-visitor.d.ts.map +0 -1
  637. package/lib/visitor/less-visitor.js.map +0 -1
@@ -0,0 +1,2047 @@
1
+ import {
2
+ rules, sel, el, spaced, any, sellist, ruleset, decl, atrule,
3
+ vardecl, ref, mixin, call, list, op,
4
+ num, dimension, amp, expr,
5
+ paren, seq, comment, nil, quoted, color, co, interpolated
6
+ } from '../index.js';
7
+ import { Context } from '../../context.js';
8
+ import { AtRule } from '../at-rule.js';
9
+ import { Rules } from '../rules.js';
10
+ import { Node } from '../node.js';
11
+ import { serializeTypes } from '../util/serialize-types.js';
12
+ import * as path from 'path';
13
+ import * as fs from 'fs';
14
+
15
+ let context: Context;
16
+
17
+ describe('AtRule', () => {
18
+ beforeEach(() => {
19
+ context = new Context();
20
+ });
21
+
22
+ describe('nested @media rules', () => {
23
+ it('should handle nested @media rules inside rulesets', async () => {
24
+ // Represents: .body { @media print { padding: 20px; } }
25
+ const node = rules([
26
+ ruleset({
27
+ selector: sel([el('.body')]) as any,
28
+ rules: rules([
29
+ atrule({
30
+ name: any('@media', { role: 'atkeyword' }),
31
+ prelude: seq([any('print', { role: 'keyword' })]),
32
+ rules: rules([
33
+ decl({ name: 'padding', value: dimension([20, 'px']) })
34
+ ])
35
+ })
36
+ ])
37
+ })
38
+ ]);
39
+
40
+ const evald = await node.eval(context);
41
+ const css = evald.render(context);
42
+
43
+ expect(css).toBeString(`
44
+ .body {
45
+ @media print {
46
+ padding: 20px;
47
+ }
48
+ }
49
+ `);
50
+ });
51
+
52
+ /**
53
+ * We need to hoist rulesets that have Less-style ampersands
54
+ * that add to the inherited selector.
55
+ */
56
+ it('should collapse ampersands when we need to', async () => {
57
+ // Represents:
58
+ // .body {
59
+ // @media print {
60
+ // padding: 20px;
61
+ // &-1 {
62
+ // color: black;
63
+ // }
64
+ // }
65
+ // }
66
+ const node = rules([
67
+ ruleset({
68
+ selector: sel([el('.body')]) as any,
69
+ rules: rules([
70
+ atrule({
71
+ name: any('@media', { role: 'atkeyword' }),
72
+ prelude: seq([any('print', { role: 'keyword' })]),
73
+ rules: rules([
74
+ decl({ name: 'padding', value: dimension([20, 'px']) }),
75
+ ruleset({
76
+ selector: sel([amp('-1')]) as any,
77
+ rules: rules([
78
+ decl({ name: 'color', value: any('black') })
79
+ ])
80
+ })
81
+ ])
82
+ })
83
+ ])
84
+ })
85
+ ]);
86
+
87
+ const evald = await node.eval(context);
88
+ const css = evald.render(context);
89
+ expect(css).toBeString(`
90
+ .body {
91
+ @media print {
92
+ padding: 20px;
93
+ }
94
+ }
95
+ @media print {
96
+ .body-1 {
97
+ color: black;
98
+ }
99
+ }
100
+ `);
101
+ });
102
+
103
+ it('should collapse ampersands when we need to #2', async () => {
104
+ // Represents:
105
+ // .body {
106
+ // @media print {
107
+ // padding: 20px;
108
+ // &-1 {
109
+ // color: black;
110
+ // }
111
+ // background-color: white;
112
+ // &-2 {
113
+ // color: blue;
114
+ // }
115
+ // }
116
+ // }
117
+ const node = rules([
118
+ ruleset({
119
+ selector: sel([el('.body')]) as any,
120
+ rules: rules([
121
+ atrule({
122
+ name: any('@media', { role: 'atkeyword' }),
123
+ prelude: seq([any('print', { role: 'keyword' })]),
124
+ rules: rules([
125
+ decl({ name: 'padding', value: dimension([20, 'px']) }),
126
+ ruleset({
127
+ selector: sel([amp('-1')]) as any,
128
+ rules: rules([
129
+ decl({ name: 'color', value: any('black') })
130
+ ])
131
+ }),
132
+ decl({ name: 'background-color', value: any('white') }),
133
+ ruleset({
134
+ selector: sel([amp('-2')]) as any,
135
+ rules: rules([
136
+ decl({ name: 'color', value: any('blue') })
137
+ ])
138
+ }),
139
+ ruleset({
140
+ selector: sel([amp('-3')]) as any,
141
+ rules: rules([
142
+ decl({ name: 'color', value: any('red') })
143
+ ])
144
+ })
145
+ ])
146
+ }),
147
+ decl({ name: 'zoom', value: num(1) })
148
+ ])
149
+ })
150
+ ]);
151
+
152
+ const evald = await node.eval(context);
153
+ const css = evald.render(context);
154
+
155
+ expect(css).toBeString(`
156
+ .body {
157
+ @media print {
158
+ padding: 20px;
159
+ }
160
+ }
161
+ @media print {
162
+ .body-1 {
163
+ color: black;
164
+ }
165
+ }
166
+ .body {
167
+ @media print {
168
+ background-color: white;
169
+ }
170
+ }
171
+ @media print {
172
+ .body-2 {
173
+ color: blue;
174
+ }
175
+ .body-3 {
176
+ color: red;
177
+ }
178
+ }
179
+ .body {
180
+ zoom: 1;
181
+ }
182
+ `);
183
+ });
184
+
185
+ it('should handle deeply nested @media rules', async () => {
186
+ // Represents: .body { @media print { header { background-color: red; @media (orientation:landscape) { margin-left: 20px; } } } }
187
+ const node = rules([
188
+ ruleset({
189
+ selector: sel([el('.body')]) as any,
190
+ rules: rules([
191
+ atrule({
192
+ name: any('@media', { role: 'atkeyword' }),
193
+ prelude: seq([any('print', { role: 'keyword' })]),
194
+ rules: rules([
195
+ decl({ name: 'padding', value: dimension([20, 'px']) }),
196
+ ruleset({
197
+ selector: sel([el('header')]) as any,
198
+ rules: rules([
199
+ decl({ name: 'background-color', value: color({ node: 'red', format: 0, rgb: [255, 0, 0], alpha: 1 }) }),
200
+ atrule({
201
+ name: any('@media', { role: 'atkeyword' }),
202
+ prelude: seq([paren(decl({
203
+ name: 'orientation',
204
+ value: any('landscape')
205
+ }))]),
206
+ rules: rules([
207
+ decl({ name: 'margin-left', value: dimension([20, 'px']) })
208
+ ])
209
+ })
210
+ ])
211
+ })
212
+ ])
213
+ })
214
+ ])
215
+ })
216
+ ]);
217
+
218
+ const evald = await node.eval(context);
219
+ const css = evald.render(context);
220
+
221
+ expect(css).toBeString(`
222
+ .body {
223
+ @media print {
224
+ padding: 20px;
225
+ header {
226
+ background-color: red;
227
+ @media (orientation: landscape) {
228
+ margin-left: 20px;
229
+ }
230
+ }
231
+ }
232
+ }
233
+ `);
234
+ });
235
+ });
236
+
237
+ describe('top-level @import preludes', () => {
238
+ it('evaluates hoisted @import preludes against root vars before serialization', async () => {
239
+ const node = rules([
240
+ vardecl({ name: 'var', value: dimension([100, 'px']) }),
241
+ atrule({
242
+ name: any('@import', { role: 'atkeyword' }),
243
+ prelude: seq([
244
+ any('url("//ha.com/file.css")'),
245
+ paren(decl({
246
+ name: 'min-width',
247
+ value: ref('var', { type: 'variable' })
248
+ }))
249
+ ])
250
+ })
251
+ ]);
252
+
253
+ const evald = await node.eval(context);
254
+ const css = evald.render(context);
255
+
256
+ expect(css.trim()).toBe('@import url("//ha.com/file.css") (min-width: 100px);');
257
+ });
258
+ });
259
+
260
+ describe('root-only at-rules', () => {
261
+ it('hoists nested @property rules to the stylesheet root', async () => {
262
+ context = new Context({ bubbleRootAtRules: true });
263
+
264
+ const node = rules([
265
+ ruleset({
266
+ selector: sel([el('.card')]) as any,
267
+ rules: rules([
268
+ atrule({
269
+ name: any('@property', { role: 'atkeyword' }),
270
+ prelude: any('--accent', { role: 'ident' }),
271
+ rules: rules([
272
+ decl({
273
+ name: 'syntax',
274
+ value: quoted(any('<color>', { role: 'any' }))
275
+ }),
276
+ decl({
277
+ name: 'inherits',
278
+ value: any('false', { role: 'keyword' })
279
+ }),
280
+ decl({
281
+ name: 'initial-value',
282
+ value: any('rebeccapurple', { role: 'keyword' })
283
+ })
284
+ ])
285
+ }),
286
+ decl({
287
+ name: 'color',
288
+ value: any('var(--accent)', { role: 'any' })
289
+ })
290
+ ])
291
+ })
292
+ ]);
293
+
294
+ const evald = await node.eval(context);
295
+ const css = evald.render(context);
296
+
297
+ expect(css).toBeString(`
298
+ @property --accent {
299
+ syntax: "<color>";
300
+ inherits: false;
301
+ initial-value: rebeccapurple;
302
+ }
303
+ .card {
304
+ color: var(--accent);
305
+ }
306
+ `);
307
+ });
308
+ });
309
+
310
+ describe('@media with mixins and parameters', () => {
311
+ it.only('should handle mixin with nested @media using parameter', async () => {
312
+ // Represents:
313
+ // .mediaMixin(@fallback: 200px) {
314
+ // background: black;
315
+ // @media handheld {
316
+ // background: white;
317
+ // @media (max-width: @fallback) {
318
+ // background: red;
319
+ // }
320
+ // }
321
+ // }
322
+ // .a {
323
+ // .mediaMixin(100px);
324
+ // }
325
+ const mixinDef = mixin({
326
+ name: any('.mediaMixin'),
327
+ params: list([
328
+ vardecl({ name: 'fallback', value: dimension([200, 'px']) }, { paramVar: true })
329
+ ]),
330
+ rules: rules([
331
+ decl({ name: 'background', value: color({ node: 'black', format: 0, rgb: [0, 0, 0], alpha: 1 }) }),
332
+ atrule({
333
+ name: any('@media', { role: 'atkeyword' }),
334
+ prelude: seq([any('handheld', { role: 'keyword' })]),
335
+ rules: rules([
336
+ decl({ name: 'background', value: color({ node: 'white', format: 0, rgb: [255, 255, 255], alpha: 1 }) }),
337
+ atrule({
338
+ name: any('@media', { role: 'atkeyword' }),
339
+ prelude: seq([paren(decl({
340
+ name: 'max-width',
341
+ value: ref({ key: 'fallback' }, { type: 'variable' })
342
+ }))]),
343
+ rules: rules([
344
+ decl({ name: 'background', value: color({ node: 'red', format: 0, rgb: [255, 0, 0], alpha: 1 }) })
345
+ ])
346
+ })
347
+ ])
348
+ })
349
+ ])
350
+ });
351
+
352
+ const callSite = ruleset({
353
+ selector: sel([el('.a')]) as any,
354
+ rules: rules([
355
+ call({
356
+ name: ref({ key: '.mediaMixin' }, { type: 'mixin-ruleset' }),
357
+ args: list([dimension([100, 'px'])])
358
+ })
359
+ ])
360
+ });
361
+
362
+ const rootRules = rules([mixinDef, callSite]);
363
+ context.root = rootRules;
364
+ const evald = await rootRules.eval(context);
365
+ const css = evald.render(context);
366
+
367
+ expect(css).toBeString(`
368
+ .a {
369
+ background: black;
370
+ @media handheld {
371
+ background: white;
372
+ @media (max-width: 100px) {
373
+ background: red;
374
+ }
375
+ }
376
+ }
377
+ `);
378
+ });
379
+ });
380
+
381
+ describe('multiple @media rules', () => {
382
+ it('should handle multiple @media rules at root level', async () => {
383
+ // Represents: @media print { ... } @media screen { ... }
384
+ const node = rules([
385
+ atrule({
386
+ name: any('@media', { role: 'atkeyword' }),
387
+ prelude: seq([any('print', { role: 'keyword' })]),
388
+ rules: rules([
389
+ ruleset({
390
+ selector: sel([el('.class')]) as any,
391
+ rules: rules([
392
+ decl({ name: 'color', value: color({ node: 'blue', format: 0, rgb: [0, 0, 255], alpha: 1 }) })
393
+ ])
394
+ })
395
+ ])
396
+ }),
397
+ atrule({
398
+ name: any('@media', { role: 'atkeyword' }),
399
+ prelude: seq([any('screen', { role: 'keyword' })]),
400
+ rules: rules([
401
+ vardecl({ name: any('base', { role: 'ident' }), value: num(8) }),
402
+ ruleset({
403
+ selector: sel([el('.body')]) as any,
404
+ rules: rules([
405
+ decl({ name: 'max-width', value: op([ref('base', { type: 'variable' }), '*', num(60)]) })
406
+ ])
407
+ })
408
+ ])
409
+ })
410
+ ]);
411
+
412
+ context.root = node;
413
+ const evald = await node.eval(context);
414
+ const css = evald.render(context);
415
+
416
+ expect(css).toBeString(`
417
+ @media print {
418
+ .class {
419
+ color: blue;
420
+ }
421
+ }
422
+ @media screen {
423
+ .body {
424
+ max-width: 480;
425
+ }
426
+ }
427
+ `);
428
+ });
429
+ });
430
+
431
+ describe('@media with variables in prelude', () => {
432
+ it('should handle @media with variable references in prelude', async () => {
433
+ // Represents: @all: ~"all"; @tv: ~"(tv)"; @media @all and @tv { ... }
434
+ const node = rules([
435
+ vardecl({ name: any('all', { role: 'ident' }), value: quoted(any('all', { role: 'any' }), { escaped: true }) }),
436
+ vardecl({ name: any('tv', { role: 'ident' }), value: quoted(any('(tv)', { role: 'any' }), { escaped: true }) }),
437
+ atrule({
438
+ name: any('@media', { role: 'atkeyword' }),
439
+ prelude: seq([ref('all', { type: 'variable' }), any('and', { role: 'keyword' }), ref('tv', { type: 'variable' })]),
440
+ rules: rules([
441
+ ruleset({
442
+ selector: sel([el('.all-and-tv-variables')]) as any,
443
+ rules: rules([
444
+ decl({ name: 'var', value: spaced([any('all-and-tv')]) })
445
+ ])
446
+ })
447
+ ])
448
+ })
449
+ ]);
450
+
451
+ const evald = await node.eval(context);
452
+ const css = evald.render(context);
453
+
454
+ expect(css).toBeString(`
455
+ @media all and (tv) {
456
+ .all-and-tv-variables {
457
+ var: all-and-tv;
458
+ }
459
+ }
460
+ `);
461
+ });
462
+ });
463
+
464
+ describe('@media with expressions in prelude', () => {
465
+ it('should handle @media with expressions in prelude', async () => {
466
+ // Represents: @some-var: 60px; @media screen and (min-width: (@some-var + 1)) { ... }
467
+ const node = rules([
468
+ vardecl({ name: any('some-var', { role: 'ident' }), value: dimension([60, 'px']) }),
469
+ atrule({
470
+ name: any('@media', { role: 'atkeyword' }),
471
+ prelude: seq([
472
+ any('screen', { role: 'keyword' }),
473
+ any('and', { role: 'keyword' }),
474
+ paren(decl({
475
+ name: 'min-width',
476
+ value: op([ref('some-var', { type: 'variable' }), '+', num(1)])
477
+ }))
478
+ ]),
479
+ rules: rules([
480
+ ruleset({
481
+ selector: sel([el('.selector')]) as any,
482
+ rules: rules([
483
+ decl({ name: 'foo', value: spaced([any('bar')]) })
484
+ ])
485
+ })
486
+ ])
487
+ })
488
+ ]);
489
+
490
+ const evald = await node.eval(context);
491
+ const css = evald.render(context);
492
+
493
+ expect(css).toBeString(`
494
+ @media screen and (min-width: 61px) {
495
+ .selector {
496
+ foo: bar;
497
+ }
498
+ }
499
+ `);
500
+ });
501
+ });
502
+
503
+ describe('@media with multiple conditions', () => {
504
+ it('should handle @media with comma-separated conditions', async () => {
505
+ // Represents: @media screen and (color), projection and (color) { ... }
506
+ const node = rules([
507
+ atrule({
508
+ name: any('@media', { role: 'atkeyword' }),
509
+ prelude: list([
510
+ seq([
511
+ any('screen', { role: 'keyword' }),
512
+ any('and', { role: 'keyword' }),
513
+ paren(any('color', { role: 'keyword' }))
514
+ ]),
515
+ seq([
516
+ any('projection', { role: 'keyword' }),
517
+ any('and', { role: 'keyword' }),
518
+ paren(any('color', { role: 'keyword' }))
519
+ ])
520
+ ]),
521
+ rules: rules([
522
+ ruleset({
523
+ selector: sel([el('.selector')]) as any,
524
+ rules: rules([
525
+ decl({ name: 'color', value: color({ node: '#eee', format: 0 }) })
526
+ ])
527
+ })
528
+ ])
529
+ })
530
+ ]);
531
+
532
+ const evald = await node.eval(context);
533
+ const css = evald.render(context);
534
+
535
+ expect(css).toBeString(`
536
+ @media screen and (color), projection and (color) {
537
+ .selector {
538
+ color: #eee;
539
+ }
540
+ }
541
+ `);
542
+ });
543
+ });
544
+
545
+ describe('nested @media in mixin calls', () => {
546
+ it('should handle mixin call with nested @media', async () => {
547
+ // Represents:
548
+ // .nav-justified() {
549
+ // @media (min-width: 480px) {
550
+ // > li {
551
+ // display: table-cell;
552
+ // }
553
+ // }
554
+ // }
555
+ // .menu {
556
+ // @media (min-width: 768px) {
557
+ // .nav-justified();
558
+ // }
559
+ // }
560
+ const navJustifiedMixin = mixin({
561
+ name: any('.nav-justified'),
562
+ rules: rules([
563
+ atrule({
564
+ name: any('@media', { role: 'atkeyword' }),
565
+ prelude: seq([paren(decl({
566
+ name: 'min-width',
567
+ value: dimension([480, 'px'])
568
+ }))]),
569
+ rules: rules([
570
+ ruleset({
571
+ selector: sel([el('> li')]) as any,
572
+ rules: rules([
573
+ decl({ name: 'display', value: spaced([any('table-cell')]) })
574
+ ])
575
+ })
576
+ ])
577
+ })
578
+ ])
579
+ });
580
+
581
+ const callSite = ruleset({
582
+ selector: sel([el('.menu')]) as any,
583
+ rules: rules([
584
+ atrule({
585
+ name: any('@media', { role: 'atkeyword' }),
586
+ prelude: seq([paren(decl({
587
+ name: 'min-width',
588
+ value: dimension([768, 'px'])
589
+ }))]),
590
+ rules: rules([
591
+ call({
592
+ name: ref({ key: '.nav-justified' }, { type: 'mixin-ruleset' })
593
+ })
594
+ ])
595
+ })
596
+ ])
597
+ });
598
+
599
+ const rootRules = rules([navJustifiedMixin, callSite]);
600
+ context.root = rootRules;
601
+ const evald = await rootRules.eval(context);
602
+ const css = evald.render(context);
603
+
604
+ expect(css).toBeString(`
605
+ .menu {
606
+ @media (min-width: 768px) {
607
+ @media (min-width: 480px) {
608
+ > li {
609
+ display: table-cell;
610
+ }
611
+ }
612
+ }
613
+ }
614
+ `);
615
+ });
616
+ });
617
+
618
+ describe('serialization test for media.less AST', () => {
619
+ it('should serialize the exact AST structure from media.less.s-expr.txt', async () => {
620
+ context.opts.collapseNesting = true;
621
+ // Build the AST exactly as represented in media.less.s-expr.txt
622
+ const node = rules([
623
+ comment('// For now, variables can\'t be declared…', { lineComment: true }),
624
+ vardecl({ name: any('var', { role: 'ident' }), value: num(42) }),
625
+ atrule({
626
+ name: any('@media', { role: 'atkeyword' }),
627
+ prelude: seq([any('print', { role: 'keyword' })]),
628
+ rules: rules([
629
+ ruleset({
630
+ selector: el('.class'),
631
+ rules: rules([
632
+ decl({
633
+ name: 'color',
634
+ value: color({ node: 'blue', format: 0, rgb: [0, 0, 255], alpha: 1 })
635
+ }),
636
+ ruleset({
637
+ selector: el('.sub'),
638
+ rules: rules([
639
+ decl({
640
+ name: 'width',
641
+ value: ref({ key: 'var' }, { type: 'variable' })
642
+ })
643
+ ])
644
+ })
645
+ ])
646
+ }),
647
+ ruleset({
648
+ selector: sellist([
649
+ el('.top'),
650
+ sel([
651
+ el('header'),
652
+ co('>'),
653
+ el('h1')
654
+ ])
655
+ ]),
656
+ rules: rules([
657
+ decl({
658
+ name: 'color',
659
+ value: paren(op([
660
+ color({ node: '#222', format: 0 }),
661
+ '*',
662
+ num(2)
663
+ ]))
664
+ })
665
+ ])
666
+ })
667
+ ])
668
+ }),
669
+ atrule({
670
+ name: any('@media', { role: 'atkeyword' }),
671
+ prelude: seq([any('screen', { role: 'keyword' })]),
672
+ rules: rules([
673
+ vardecl({ name: any('base', { role: 'ident' }), value: num(8) }),
674
+ ruleset({
675
+ selector: el('.body'),
676
+ rules: rules([
677
+ decl({
678
+ name: 'max-width',
679
+ value: paren(op([
680
+ ref({ key: 'base' }, { type: 'variable' }),
681
+ '*',
682
+ num(60)
683
+ ]))
684
+ })
685
+ ])
686
+ })
687
+ ])
688
+ }),
689
+ vardecl({ name: any('ratio_large', { role: 'ident' }), value: num(16) }),
690
+ vardecl({ name: any('ratio_small', { role: 'ident' }), value: num(9) }),
691
+ atrule({
692
+ name: any('@media', { role: 'atkeyword' }),
693
+ prelude: seq([
694
+ any('all', { role: 'keyword' }),
695
+ any('and', { role: 'keyword' }),
696
+ seq([
697
+ paren(decl({
698
+ name: 'device-aspect-ratio',
699
+ value: quoted(interpolated({
700
+ source: '%% / %%',
701
+ replacements: [
702
+ ref({ key: 'ratio_large' }, { type: 'variable' }),
703
+ ref({ key: 'ratio_small' }, { type: 'variable' })
704
+ ]
705
+ }, { role: 'ident' }), { escaped: true })
706
+ }))
707
+ ])
708
+ ]),
709
+ rules: rules([
710
+ ruleset({
711
+ selector: el('.body'),
712
+ rules: rules([
713
+ decl({
714
+ name: 'max-width',
715
+ value: dimension([800, 'px'])
716
+ })
717
+ ])
718
+ })
719
+ ])
720
+ }),
721
+ atrule({
722
+ name: any('@media', { role: 'atkeyword' }),
723
+ prelude: seq([
724
+ any('all', { role: 'keyword' }),
725
+ any('and', { role: 'keyword' }),
726
+ seq([
727
+ paren(decl({
728
+ name: 'orientation',
729
+ value: any('portrait')
730
+ }))
731
+ ])
732
+ ]),
733
+ rules: rules([
734
+ ruleset({
735
+ selector: el('aside'),
736
+ rules: rules([
737
+ decl({
738
+ name: 'float',
739
+ value: any('none')
740
+ })
741
+ ])
742
+ })
743
+ ])
744
+ }),
745
+ atrule({
746
+ name: any('@media', { role: 'atkeyword' }),
747
+ prelude: list([
748
+ seq([
749
+ any('handheld', { role: 'keyword' }),
750
+ any('and', { role: 'keyword' }),
751
+ seq([
752
+ paren(decl({
753
+ name: 'min-width',
754
+ value: ref({ key: 'var' }, { type: 'variable' })
755
+ }))
756
+ ])
757
+ ]),
758
+ seq([
759
+ any('screen', { role: 'keyword' }),
760
+ any('and', { role: 'keyword' }),
761
+ seq([
762
+ paren(decl({
763
+ name: 'min-width',
764
+ value: dimension([20, 'em'])
765
+ }))
766
+ ])
767
+ ])
768
+ ]),
769
+ rules: rules([
770
+ ruleset({
771
+ selector: el('.body'),
772
+ rules: rules([
773
+ decl({
774
+ name: 'max-width',
775
+ value: dimension([480, 'px'])
776
+ })
777
+ ])
778
+ })
779
+ ])
780
+ }),
781
+ ruleset({
782
+ selector: el('.body'),
783
+ rules: rules([
784
+ atrule({
785
+ name: any('@media', { role: 'atkeyword' }),
786
+ prelude: seq([any('print', { role: 'keyword' })]),
787
+ rules: rules([
788
+ decl({
789
+ name: 'padding',
790
+ value: dimension([20, 'px'])
791
+ }),
792
+ ruleset({
793
+ selector: el('header'),
794
+ rules: rules([
795
+ decl({
796
+ name: 'background-color',
797
+ value: color({ node: 'red', format: 0, rgb: [255, 0, 0], alpha: 1 })
798
+ })
799
+ ])
800
+ }),
801
+ atrule({
802
+ name: any('@media', { role: 'atkeyword' }),
803
+ prelude: seq([
804
+ paren(decl({
805
+ name: 'orientation',
806
+ value: any('landscape')
807
+ }))
808
+ ]),
809
+ rules: rules([
810
+ decl({
811
+ name: 'margin-left',
812
+ value: dimension([20, 'px'])
813
+ })
814
+ ])
815
+ })
816
+ ])
817
+ })
818
+ ])
819
+ }),
820
+ atrule({
821
+ name: any('@media', { role: 'atkeyword' }),
822
+ prelude: seq([any('screen', { role: 'keyword' })]),
823
+ rules: rules([
824
+ ruleset({
825
+ selector: el('.sidebar'),
826
+ rules: rules([
827
+ decl({
828
+ name: 'width',
829
+ value: dimension([300, 'px'])
830
+ }),
831
+ atrule({
832
+ name: any('@media', { role: 'atkeyword' }),
833
+ prelude: seq([
834
+ paren(decl({
835
+ name: 'orientation',
836
+ value: any('landscape')
837
+ }))
838
+ ]),
839
+ rules: rules([
840
+ decl({
841
+ name: 'width',
842
+ value: dimension([500, 'px'])
843
+ })
844
+ ])
845
+ })
846
+ ])
847
+ })
848
+ ])
849
+ }),
850
+ atrule({
851
+ name: any('@media', { role: 'atkeyword' }),
852
+ prelude: seq([any('a', { role: 'keyword' })]),
853
+ rules: rules([
854
+ ruleset({
855
+ selector: el('.first'),
856
+ rules: rules([
857
+ atrule({
858
+ name: any('@media', { role: 'atkeyword' }),
859
+ prelude: seq([
860
+ paren(any('b', { role: 'keyword' }))
861
+ ]),
862
+ rules: rules([
863
+ ruleset({
864
+ selector: el('.second'),
865
+ rules: rules([
866
+ ruleset({
867
+ selector: el('.third'),
868
+ rules: rules([
869
+ decl({
870
+ name: 'width',
871
+ value: dimension([300, 'px'])
872
+ }),
873
+ atrule({
874
+ name: any('@media', { role: 'atkeyword' }),
875
+ prelude: seq([
876
+ paren(any('c', { role: 'keyword' }))
877
+ ]),
878
+ rules: rules([
879
+ decl({
880
+ name: 'width',
881
+ value: dimension([500, 'px'])
882
+ })
883
+ ])
884
+ })
885
+ ])
886
+ }),
887
+ ruleset({
888
+ selector: el('.fourth'),
889
+ rules: rules([
890
+ decl({
891
+ name: 'width',
892
+ value: num(3)
893
+ })
894
+ ])
895
+ })
896
+ ])
897
+ })
898
+ ])
899
+ })
900
+ ])
901
+ })
902
+ ])
903
+ }),
904
+ ruleset({
905
+ selector: el('.body'),
906
+ rules: rules([
907
+ atrule({
908
+ name: any('@media', { role: 'atkeyword' }),
909
+ prelude: list([
910
+ seq([any('a', { role: 'keyword' })]),
911
+ seq([
912
+ paren(any('b', { role: 'keyword' })),
913
+ any('and', { role: 'keyword' }),
914
+ paren(any('c', { role: 'keyword' }))
915
+ ])
916
+ ]),
917
+ rules: rules([
918
+ decl({
919
+ name: 'width',
920
+ value: dimension([95, '%'])
921
+ }),
922
+ atrule({
923
+ name: any('@media', { role: 'atkeyword' }),
924
+ prelude: list([
925
+ seq([paren(any('x', { role: 'keyword' }))]),
926
+ seq([paren(any('y', { role: 'keyword' }))])
927
+ ]),
928
+ rules: rules([
929
+ decl({
930
+ name: 'width',
931
+ value: dimension([100, '%'])
932
+ })
933
+ ])
934
+ })
935
+ ])
936
+ })
937
+ ])
938
+ }),
939
+ mixin({
940
+ name: any('.mediaMixin'),
941
+ params: list([
942
+ vardecl({
943
+ name: any('fallback', { role: 'property' }),
944
+ value: dimension([200, 'px'])
945
+ })
946
+ ]),
947
+ rules: rules([
948
+ decl({
949
+ name: 'background',
950
+ value: color({ node: 'black', format: 0, rgb: [0, 0, 0], alpha: 1 })
951
+ }),
952
+ atrule({
953
+ name: any('@media', { role: 'atkeyword' }),
954
+ prelude: seq([any('handheld', { role: 'keyword' })]),
955
+ rules: rules([
956
+ decl({
957
+ name: 'background',
958
+ value: color({ node: 'white', format: 0, rgb: [255, 255, 255], alpha: 1 })
959
+ }),
960
+ atrule({
961
+ name: any('@media', { role: 'atkeyword' }),
962
+ prelude: seq([
963
+ paren(decl({
964
+ name: 'max-width',
965
+ value: ref({ key: 'fallback' }, { type: 'variable' })
966
+ }))
967
+ ]),
968
+ rules: rules([
969
+ decl({
970
+ name: 'background',
971
+ value: color({ node: 'red', format: 0, rgb: [255, 0, 0], alpha: 1 })
972
+ })
973
+ ])
974
+ })
975
+ ])
976
+ })
977
+ ])
978
+ }),
979
+ ruleset({
980
+ selector: el('.a'),
981
+ rules: rules([
982
+ call({
983
+ name: ref({ key: '.mediaMixin' }, { type: 'mixin-ruleset' }),
984
+ args: list([
985
+ dimension([100, 'px'])
986
+ ])
987
+ })
988
+ ])
989
+ }),
990
+ ruleset({
991
+ selector: el('.b'),
992
+ rules: rules([
993
+ call({
994
+ name: ref({ key: '.mediaMixin' }, { type: 'mixin-ruleset' })
995
+ })
996
+ ])
997
+ }),
998
+ vardecl({
999
+ name: any('smartphone', { role: 'ident' }),
1000
+ value: quoted(any('only screen and (max-width: 200px)', { role: 'any' }), { escaped: true })
1001
+ }),
1002
+ atrule({
1003
+ name: any('@media', { role: 'atkeyword' }),
1004
+ prelude: seq([
1005
+ ref({ key: 'smartphone' }, { type: 'variable' })
1006
+ ]),
1007
+ rules: rules([
1008
+ ruleset({
1009
+ selector: el('.body'),
1010
+ rules: rules([
1011
+ decl({
1012
+ name: 'width',
1013
+ value: dimension([480, 'px'])
1014
+ })
1015
+ ])
1016
+ })
1017
+ ])
1018
+ }),
1019
+ atrule({
1020
+ name: any('@media', { role: 'atkeyword' }),
1021
+ prelude: seq([any('print', { role: 'keyword' })]),
1022
+ rules: rules([
1023
+ atrule({
1024
+ name: any('@page', { role: 'atkeyword' }),
1025
+ prelude: list([el(':left')]),
1026
+ rules: rules([
1027
+ decl({
1028
+ name: 'margin',
1029
+ value: dimension([0.5, 'cm'])
1030
+ })
1031
+ ])
1032
+ }),
1033
+ atrule({
1034
+ name: any('@page', { role: 'atkeyword' }),
1035
+ prelude: list([el(':right')]),
1036
+ rules: rules([
1037
+ decl({
1038
+ name: 'margin',
1039
+ value: dimension([0.5, 'cm'])
1040
+ })
1041
+ ])
1042
+ }),
1043
+ atrule({
1044
+ name: any('@page', { role: 'atkeyword' }),
1045
+ prelude: list([el('Test:first')]),
1046
+ rules: rules([
1047
+ decl({
1048
+ name: 'margin',
1049
+ value: dimension([1, 'cm'])
1050
+ })
1051
+ ])
1052
+ }),
1053
+ atrule({
1054
+ name: any('@page', { role: 'atkeyword' }),
1055
+ prelude: list([el(':first')]),
1056
+ rules: rules([
1057
+ decl({
1058
+ name: 'margin',
1059
+ value: dimension([0.5, 'cm'])
1060
+ }),
1061
+ decl({
1062
+ name: 'size',
1063
+ value: seq([
1064
+ dimension([8.5, 'in']),
1065
+ dimension([11, 'in'])
1066
+ ])
1067
+ }),
1068
+ atrule({
1069
+ name: any('@top-left', { role: 'atkeyword' }),
1070
+ rules: rules([
1071
+ decl({
1072
+ name: 'margin',
1073
+ value: dimension([1, 'cm'])
1074
+ })
1075
+ ])
1076
+ }),
1077
+ atrule({
1078
+ name: any('@top-left-corner', { role: 'atkeyword' }),
1079
+ rules: rules([
1080
+ decl({
1081
+ name: 'margin',
1082
+ value: dimension([1, 'cm'])
1083
+ })
1084
+ ])
1085
+ }),
1086
+ atrule({
1087
+ name: any('@top-center', { role: 'atkeyword' }),
1088
+ rules: rules([
1089
+ decl({
1090
+ name: 'margin',
1091
+ value: dimension([1, 'cm'])
1092
+ })
1093
+ ])
1094
+ }),
1095
+ atrule({
1096
+ name: any('@top-right', { role: 'atkeyword' }),
1097
+ rules: rules([
1098
+ decl({
1099
+ name: 'margin',
1100
+ value: dimension([1, 'cm'])
1101
+ })
1102
+ ])
1103
+ }),
1104
+ atrule({
1105
+ name: any('@top-right-corner', { role: 'atkeyword' }),
1106
+ rules: rules([
1107
+ decl({
1108
+ name: 'margin',
1109
+ value: dimension([1, 'cm'])
1110
+ })
1111
+ ])
1112
+ }),
1113
+ atrule({
1114
+ name: any('@bottom-left', { role: 'atkeyword' }),
1115
+ rules: rules([
1116
+ decl({
1117
+ name: 'margin',
1118
+ value: dimension([1, 'cm'])
1119
+ })
1120
+ ])
1121
+ }),
1122
+ atrule({
1123
+ name: any('@bottom-left-corner', { role: 'atkeyword' }),
1124
+ rules: rules([
1125
+ decl({
1126
+ name: 'margin',
1127
+ value: dimension([1, 'cm'])
1128
+ })
1129
+ ])
1130
+ }),
1131
+ atrule({
1132
+ name: any('@bottom-center', { role: 'atkeyword' }),
1133
+ rules: rules([
1134
+ decl({
1135
+ name: 'margin',
1136
+ value: dimension([1, 'cm'])
1137
+ })
1138
+ ])
1139
+ }),
1140
+ atrule({
1141
+ name: any('@bottom-right', { role: 'atkeyword' }),
1142
+ rules: rules([
1143
+ decl({
1144
+ name: 'margin',
1145
+ value: dimension([1, 'cm'])
1146
+ })
1147
+ ])
1148
+ }),
1149
+ atrule({
1150
+ name: any('@bottom-right-corner', { role: 'atkeyword' }),
1151
+ rules: rules([
1152
+ decl({
1153
+ name: 'margin',
1154
+ value: dimension([1, 'cm'])
1155
+ })
1156
+ ])
1157
+ }),
1158
+ atrule({
1159
+ name: any('@left-top', { role: 'atkeyword' }),
1160
+ rules: rules([
1161
+ decl({
1162
+ name: 'margin',
1163
+ value: dimension([1, 'cm'])
1164
+ })
1165
+ ])
1166
+ }),
1167
+ atrule({
1168
+ name: any('@left-middle', { role: 'atkeyword' }),
1169
+ rules: rules([
1170
+ decl({
1171
+ name: 'margin',
1172
+ value: dimension([1, 'cm'])
1173
+ })
1174
+ ])
1175
+ }),
1176
+ atrule({
1177
+ name: any('@left-bottom', { role: 'atkeyword' }),
1178
+ rules: rules([
1179
+ decl({
1180
+ name: 'margin',
1181
+ value: dimension([1, 'cm'])
1182
+ })
1183
+ ])
1184
+ }),
1185
+ atrule({
1186
+ name: any('@right-top', { role: 'atkeyword' }),
1187
+ rules: rules([
1188
+ decl({
1189
+ name: 'margin',
1190
+ value: dimension([1, 'cm'])
1191
+ })
1192
+ ])
1193
+ }),
1194
+ atrule({
1195
+ name: any('@right-middle', { role: 'atkeyword' }),
1196
+ rules: rules([
1197
+ decl({
1198
+ name: 'content',
1199
+ value: seq([
1200
+ quoted(any('Page ', { role: 'any' })),
1201
+ call({
1202
+ name: any('counter', { role: 'ident' }),
1203
+ args: list([
1204
+ any('page')
1205
+ ])
1206
+ })
1207
+ ])
1208
+ })
1209
+ ])
1210
+ }),
1211
+ atrule({
1212
+ name: any('@right-bottom', { role: 'atkeyword' }),
1213
+ rules: rules([
1214
+ decl({
1215
+ name: 'margin',
1216
+ value: dimension([1, 'cm'])
1217
+ })
1218
+ ])
1219
+ })
1220
+ ])
1221
+ })
1222
+ ])
1223
+ }),
1224
+ atrule({
1225
+ name: any('@media', { role: 'atkeyword' }),
1226
+ prelude: list([
1227
+ seq([
1228
+ paren(decl({
1229
+ name: '-webkit-min-device-pixel-ratio',
1230
+ value: num(2)
1231
+ }))
1232
+ ]),
1233
+ seq([
1234
+ paren(decl({
1235
+ name: 'min--moz-device-pixel-ratio',
1236
+ value: num(2)
1237
+ }))
1238
+ ]),
1239
+ seq([
1240
+ paren(decl({
1241
+ name: '-o-min-device-pixel-ratio',
1242
+ value: quoted(any('2/1', { role: 'any' }))
1243
+ }))
1244
+ ]),
1245
+ seq([
1246
+ paren(decl({
1247
+ name: 'min-resolution',
1248
+ value: dimension([2, 'dppx'])
1249
+ }))
1250
+ ]),
1251
+ seq([
1252
+ paren(decl({
1253
+ name: 'min-resolution',
1254
+ value: dimension([128, 'dpcm'])
1255
+ }))
1256
+ ])
1257
+ ]),
1258
+ rules: rules([
1259
+ ruleset({
1260
+ selector: el('.b'),
1261
+ rules: rules([
1262
+ decl({
1263
+ name: 'background',
1264
+ value: color({ node: 'red', format: 0, rgb: [255, 0, 0], alpha: 1 })
1265
+ })
1266
+ ])
1267
+ })
1268
+ ])
1269
+ }),
1270
+ mixin({
1271
+ name: any('.bg'),
1272
+ rules: rules([
1273
+ decl({
1274
+ name: 'background',
1275
+ value: color({ node: 'red', format: 0, rgb: [255, 0, 0], alpha: 1 })
1276
+ }),
1277
+ atrule({
1278
+ name: any('@media', { role: 'atkeyword' }),
1279
+ prelude: seq([
1280
+ paren(decl({
1281
+ name: 'max-width',
1282
+ value: dimension([500, 'px'])
1283
+ }))
1284
+ ]),
1285
+ rules: rules([
1286
+ decl({
1287
+ name: 'background',
1288
+ value: color({ node: 'green', format: 0, rgb: [0, 128, 0], alpha: 1 })
1289
+ })
1290
+ ])
1291
+ })
1292
+ ])
1293
+ }),
1294
+ ruleset({
1295
+ selector: el('.body'),
1296
+ rules: rules([
1297
+ call({
1298
+ name: ref({ key: '.bg' }, { type: 'mixin-ruleset' })
1299
+ })
1300
+ ])
1301
+ }),
1302
+ vardecl({
1303
+ name: any('bpMedium', { role: 'ident' }),
1304
+ value: dimension([1000, 'px'])
1305
+ }),
1306
+ atrule({
1307
+ name: any('@media', { role: 'atkeyword' }),
1308
+ prelude: seq([
1309
+ paren(decl({
1310
+ name: 'max-width',
1311
+ value: ref({ key: 'bpMedium' }, { type: 'variable' })
1312
+ }))
1313
+ ]),
1314
+ rules: rules([
1315
+ ruleset({
1316
+ selector: el('.body'),
1317
+ rules: rules([
1318
+ decl({
1319
+ name: 'background',
1320
+ value: color({ node: 'red', format: 0, rgb: [255, 0, 0], alpha: 1 })
1321
+ }),
1322
+ atrule({
1323
+ name: any('@media', { role: 'atkeyword' }),
1324
+ prelude: seq([
1325
+ paren(decl({
1326
+ name: 'max-width',
1327
+ value: dimension([500, 'px'])
1328
+ }))
1329
+ ]),
1330
+ rules: rules([
1331
+ decl({
1332
+ name: 'background',
1333
+ value: color({ node: 'green', format: 0, rgb: [0, 128, 0], alpha: 1 })
1334
+ })
1335
+ ])
1336
+ }),
1337
+ decl({
1338
+ name: 'background',
1339
+ value: color({ node: 'blue', format: 0, rgb: [0, 0, 255], alpha: 1 })
1340
+ })
1341
+ ])
1342
+ })
1343
+ ])
1344
+ }),
1345
+ atrule({
1346
+ name: any('@media', { role: 'atkeyword' }),
1347
+ prelude: seq([
1348
+ paren(decl({
1349
+ name: 'max-width',
1350
+ value: dimension([1200, 'px'])
1351
+ }))
1352
+ ]),
1353
+ rules: rules([
1354
+ comment('/* a comment */'),
1355
+ atrule({
1356
+ name: any('@media', { role: 'atkeyword' }),
1357
+ prelude: seq([
1358
+ paren(decl({
1359
+ name: 'max-width',
1360
+ value: dimension([900, 'px'])
1361
+ }))
1362
+ ]),
1363
+ rules: rules([
1364
+ ruleset({
1365
+ selector: el('.body'),
1366
+ rules: rules([
1367
+ decl({
1368
+ name: 'font-size',
1369
+ value: dimension([11, 'px'])
1370
+ })
1371
+ ])
1372
+ })
1373
+ ])
1374
+ })
1375
+ ])
1376
+ }),
1377
+ ruleset({
1378
+ selector: el('.nav-justified'),
1379
+ rules: rules([
1380
+ atrule({
1381
+ name: any('@media', { role: 'atkeyword' }),
1382
+ prelude: seq([
1383
+ paren(decl({
1384
+ name: 'min-width',
1385
+ value: dimension([480, 'px'])
1386
+ }))
1387
+ ]),
1388
+ rules: rules([
1389
+ ruleset({
1390
+ selector: el('.nav-justified'),
1391
+ rules: rules([
1392
+ ruleset({
1393
+ selector: sel([
1394
+ el('.nav-justified'),
1395
+ co('>'),
1396
+ el('li')
1397
+ ]) as any,
1398
+ rules: rules([
1399
+ decl({
1400
+ name: 'display',
1401
+ value: any('table-cell')
1402
+ })
1403
+ ])
1404
+ })
1405
+ ])
1406
+ })
1407
+ ])
1408
+ })
1409
+ ])
1410
+ }),
1411
+ ruleset({
1412
+ selector: el('.menu'),
1413
+ rules: rules([
1414
+ atrule({
1415
+ name: any('@media', { role: 'atkeyword' }),
1416
+ prelude: seq([
1417
+ paren(decl({
1418
+ name: 'min-width',
1419
+ value: dimension([768, 'px'])
1420
+ }))
1421
+ ]),
1422
+ rules: rules([
1423
+ ruleset({
1424
+ selector: el('.menu'),
1425
+ rules: rules([
1426
+ atrule({
1427
+ name: any('@media', { role: 'atkeyword' }),
1428
+ prelude: seq([
1429
+ paren(decl({
1430
+ name: 'min-width',
1431
+ value: dimension([480, 'px'])
1432
+ }))
1433
+ ]),
1434
+ rules: rules([
1435
+ ruleset({
1436
+ selector: el('.menu'),
1437
+ rules: rules([
1438
+ ruleset({
1439
+ selector: sel([
1440
+ el('.menu'),
1441
+ co('>'),
1442
+ el('li')
1443
+ ]) as any,
1444
+ rules: rules([
1445
+ decl({
1446
+ name: 'display',
1447
+ value: any('table-cell')
1448
+ })
1449
+ ])
1450
+ })
1451
+ ])
1452
+ })
1453
+ ])
1454
+ })
1455
+ ])
1456
+ })
1457
+ ])
1458
+ })
1459
+ ])
1460
+ }),
1461
+ vardecl({
1462
+ name: any('all', { role: 'ident' }),
1463
+ value: quoted(any('all', { role: 'any' }))
1464
+ }),
1465
+ vardecl({
1466
+ name: any('tv', { role: 'ident' }),
1467
+ value: quoted(any('(tv)', { role: 'any' }))
1468
+ }),
1469
+ atrule({
1470
+ name: any('@media', { role: 'atkeyword' }),
1471
+ prelude: seq([
1472
+ any('all', { role: 'any' }),
1473
+ any('and', { role: 'keyword' }),
1474
+ any('(tv)', { role: 'any' })
1475
+ ]),
1476
+ rules: rules([
1477
+ ruleset({
1478
+ selector: el('.all-and-tv-variables'),
1479
+ rules: rules([
1480
+ decl({
1481
+ name: 'var',
1482
+ value: any('all-and-tv')
1483
+ })
1484
+ ])
1485
+ })
1486
+ ])
1487
+ }),
1488
+ vardecl({
1489
+ name: any('some-var', { role: 'ident' }),
1490
+ value: dimension([60, 'px'])
1491
+ }),
1492
+ atrule({
1493
+ name: any('@media', { role: 'atkeyword' }),
1494
+ prelude: seq([
1495
+ any('screen', { role: 'keyword' }),
1496
+ any('and', { role: 'keyword' }),
1497
+ paren(decl({
1498
+ name: 'min-width',
1499
+ value: dimension([61, 'px'])
1500
+ }))
1501
+ ]),
1502
+ rules: rules([
1503
+ ruleset({
1504
+ selector: el('.selector'),
1505
+ rules: rules([
1506
+ decl({
1507
+ name: 'foo',
1508
+ value: any('bar')
1509
+ })
1510
+ ])
1511
+ })
1512
+ ])
1513
+ }),
1514
+ atrule({
1515
+ name: any('@media', { role: 'atkeyword' }),
1516
+ prelude: list([
1517
+ seq([
1518
+ any('screen', { role: 'keyword' }),
1519
+ any('and', { role: 'keyword' }),
1520
+ seq([
1521
+ paren(any('color', { role: 'keyword' }))
1522
+ ])
1523
+ ]),
1524
+ seq([
1525
+ any('projection', { role: 'keyword' }),
1526
+ any('and', { role: 'keyword' }),
1527
+ seq([
1528
+ paren(any('color', { role: 'keyword' }))
1529
+ ])
1530
+ ])
1531
+ ]),
1532
+ rules: rules([
1533
+ ruleset({
1534
+ selector: el('.selector'),
1535
+ rules: rules([
1536
+ decl({
1537
+ name: 'color',
1538
+ value: color({ node: '#eee', format: 0 })
1539
+ })
1540
+ ])
1541
+ })
1542
+ ])
1543
+ }),
1544
+ atrule({
1545
+ name: any('@media', { role: 'atkeyword' }),
1546
+ prelude: seq([
1547
+ any('not', { role: 'keyword' }),
1548
+ paren(seq([
1549
+ any('width', { role: 'ident' }),
1550
+ any('<=', { role: 'keyword' }),
1551
+ dimension([-100, 'px'])
1552
+ ]))
1553
+ ]),
1554
+ rules: rules([
1555
+ ruleset({
1556
+ selector: el('body'),
1557
+ rules: rules([
1558
+ decl({
1559
+ name: 'background',
1560
+ value: color({ node: 'green', format: 0, rgb: [0, 128, 0], alpha: 1 })
1561
+ })
1562
+ ])
1563
+ })
1564
+ ])
1565
+ }),
1566
+ atrule({
1567
+ name: any('@media', { role: 'atkeyword' }),
1568
+ prelude: seq([
1569
+ paren(seq([
1570
+ any('height', { role: 'ident' }),
1571
+ any('>', { role: 'keyword' }),
1572
+ dimension([-100, 'px'])
1573
+ ]))
1574
+ ]),
1575
+ rules: rules([
1576
+ ruleset({
1577
+ selector: el('body'),
1578
+ rules: rules([
1579
+ decl({
1580
+ name: 'background',
1581
+ value: color({ node: 'green', format: 0, rgb: [0, 128, 0], alpha: 1 })
1582
+ })
1583
+ ])
1584
+ })
1585
+ ])
1586
+ }),
1587
+ atrule({
1588
+ name: any('@media', { role: 'atkeyword' }),
1589
+ prelude: seq([
1590
+ any('not', { role: 'keyword' }),
1591
+ paren(decl({
1592
+ name: 'resolution',
1593
+ value: dimension([-300, 'dpi'])
1594
+ }))
1595
+ ]),
1596
+ rules: rules([
1597
+ ruleset({
1598
+ selector: el('body'),
1599
+ rules: rules([
1600
+ decl({
1601
+ name: 'background',
1602
+ value: color({ node: 'green', format: 0, rgb: [0, 128, 0], alpha: 1 })
1603
+ })
1604
+ ])
1605
+ })
1606
+ ])
1607
+ }),
1608
+ atrule({
1609
+ name: any('@media', { role: 'atkeyword' }),
1610
+ prelude: seq([
1611
+ paren(decl({
1612
+ name: 'min-orientation',
1613
+ value: any('portrait')
1614
+ }))
1615
+ ]),
1616
+ rules: rules([
1617
+ ruleset({
1618
+ selector: el('body'),
1619
+ rules: rules([
1620
+ decl({
1621
+ name: 'background',
1622
+ value: color({ node: 'green', format: 0, rgb: [0, 128, 0], alpha: 1 })
1623
+ })
1624
+ ])
1625
+ })
1626
+ ])
1627
+ }),
1628
+ atrule({
1629
+ name: any('@media', { role: 'atkeyword' }),
1630
+ prelude: seq([
1631
+ any('print', { role: 'keyword' }),
1632
+ any('and', { role: 'keyword' }),
1633
+ seq([
1634
+ paren(decl({
1635
+ name: 'min-resolution',
1636
+ value: dimension([118, 'dpcm'])
1637
+ }))
1638
+ ])
1639
+ ]),
1640
+ rules: rules([
1641
+ ruleset({
1642
+ selector: el('body'),
1643
+ rules: rules([
1644
+ decl({
1645
+ name: 'background',
1646
+ value: color({ node: 'green', format: 0, rgb: [0, 128, 0], alpha: 1 })
1647
+ })
1648
+ ])
1649
+ })
1650
+ ])
1651
+ }),
1652
+ atrule({
1653
+ name: any('@media', { role: 'atkeyword' }),
1654
+ prelude: seq([
1655
+ paren(seq([
1656
+ dimension([200, 'px']),
1657
+ any('<=', { role: 'keyword' }),
1658
+ any('width', { role: 'ident' }),
1659
+ any('<=', { role: 'keyword' }),
1660
+ dimension([500, 'px'])
1661
+ ]))
1662
+ ]),
1663
+ rules: rules([
1664
+ ruleset({
1665
+ selector: el('.test-range-syntax'),
1666
+ rules: rules([
1667
+ decl({
1668
+ name: 'padding',
1669
+ value: num(0)
1670
+ })
1671
+ ])
1672
+ })
1673
+ ])
1674
+ }),
1675
+ ruleset({
1676
+ selector: el('.selector'),
1677
+ rules: rules([
1678
+ decl({
1679
+ name: 'color',
1680
+ value: color({ node: '#eee', format: 0 })
1681
+ }),
1682
+ atrule({
1683
+ name: any('@media', { role: 'atkeyword' }),
1684
+ prelude: seq([
1685
+ paren(seq([
1686
+ dimension([200, 'px']),
1687
+ any('<=', { role: 'keyword' }),
1688
+ any('width', { role: 'ident' }),
1689
+ any('<=', { role: 'keyword' }),
1690
+ dimension([500, 'px'])
1691
+ ]))
1692
+ ]),
1693
+ rules: rules([
1694
+ ruleset({
1695
+ selector: el('.selector'),
1696
+ rules: rules([
1697
+ ruleset({
1698
+ selector: sel([
1699
+ el('.selector'),
1700
+ co(' '),
1701
+ el('.test-range-syntax')
1702
+ ]) as any,
1703
+ rules: rules([
1704
+ decl({
1705
+ name: 'padding',
1706
+ value: num(0)
1707
+ })
1708
+ ])
1709
+ })
1710
+ ])
1711
+ })
1712
+ ])
1713
+ })
1714
+ ])
1715
+ }),
1716
+ atrule({
1717
+ name: any('@media', { role: 'atkeyword' }),
1718
+ prelude: list([
1719
+ seq([any('print', { role: 'keyword' })]),
1720
+ seq([
1721
+ paren(decl({
1722
+ name: 'max-width',
1723
+ value: dimension([992, 'px'])
1724
+ }))
1725
+ ])
1726
+ ]),
1727
+ rules: rules([
1728
+ ruleset({
1729
+ selector: el('body'),
1730
+ rules: rules([
1731
+ decl({
1732
+ name: 'background',
1733
+ value: color({ node: 'green', format: 0, rgb: [0, 128, 0], alpha: 1 })
1734
+ })
1735
+ ])
1736
+ })
1737
+ ])
1738
+ })
1739
+ ]);
1740
+
1741
+ /** This represents already eval'd nodes */
1742
+ const evald = await node.eval(context);
1743
+ const serialized = evald.render(context);
1744
+
1745
+ // The serialized output should match the structure
1746
+ expect(serialized).toBeString(`
1747
+ @media print {
1748
+ .class {
1749
+ color: blue;
1750
+ }
1751
+ .class .sub {
1752
+ width: 42;
1753
+ }
1754
+ .top,
1755
+ header > h1 {
1756
+ color: #444444;
1757
+ }
1758
+ }
1759
+ @media screen {
1760
+ .body {
1761
+ max-width: 480;
1762
+ }
1763
+ }
1764
+ @media all and (device-aspect-ratio: 16 / 9) {
1765
+ .body {
1766
+ max-width: 800px;
1767
+ }
1768
+ }
1769
+ @media all and (orientation: portrait) {
1770
+ aside {
1771
+ float: none;
1772
+ }
1773
+ }
1774
+ @media handheld and (min-width: 42), screen and (min-width: 20em) {
1775
+ .body {
1776
+ max-width: 480px;
1777
+ }
1778
+ }
1779
+ @media print {
1780
+ .body {
1781
+ padding: 20px;
1782
+ }
1783
+ .body header {
1784
+ background-color: red;
1785
+ }
1786
+ @media (orientation: landscape) {
1787
+ .body {
1788
+ margin-left: 20px;
1789
+ }
1790
+ }
1791
+ }
1792
+ @media screen {
1793
+ .sidebar {
1794
+ width: 300px;
1795
+ }
1796
+ @media (orientation: landscape) {
1797
+ .sidebar {
1798
+ width: 500px;
1799
+ }
1800
+ }
1801
+ }
1802
+ @media a {
1803
+ @media (b) {
1804
+ .first .second .third {
1805
+ width: 300px;
1806
+ }
1807
+ @media (c) {
1808
+ .first .second .third {
1809
+ width: 500px;
1810
+ }
1811
+ }
1812
+ .first .second .fourth {
1813
+ width: 3;
1814
+ }
1815
+ }
1816
+ }
1817
+ @media a, (b) and (c) {
1818
+ .body {
1819
+ width: 95%;
1820
+ }
1821
+ @media (x), (y) {
1822
+ .body {
1823
+ width: 100%;
1824
+ }
1825
+ }
1826
+ }
1827
+ .a {
1828
+ background: black;
1829
+ }
1830
+ @media handheld {
1831
+ .a {
1832
+ background: white;
1833
+ }
1834
+ @media (max-width: 100px) {
1835
+ .a {
1836
+ background: red;
1837
+ }
1838
+ }
1839
+ }
1840
+ .b {
1841
+ background: black;
1842
+ }
1843
+ @media handheld {
1844
+ .b {
1845
+ background: white;
1846
+ }
1847
+ @media (max-width: 200px) {
1848
+ .b {
1849
+ background: red;
1850
+ }
1851
+ }
1852
+ }
1853
+ @media only screen and (max-width: 200px) {
1854
+ .body {
1855
+ width: 480px;
1856
+ }
1857
+ }
1858
+ @media print {
1859
+ @page :left {
1860
+ margin: 0.5cm;
1861
+ }
1862
+ @page :right {
1863
+ margin: 0.5cm;
1864
+ }
1865
+ @page Test:first {
1866
+ margin: 1cm;
1867
+ }
1868
+ @page :first {
1869
+ margin: 0.5cm;
1870
+ size: 8.5in 11in;
1871
+ @top-left {
1872
+ margin: 1cm;
1873
+ }
1874
+ @top-left-corner {
1875
+ margin: 1cm;
1876
+ }
1877
+ @top-center {
1878
+ margin: 1cm;
1879
+ }
1880
+ @top-right {
1881
+ margin: 1cm;
1882
+ }
1883
+ @top-right-corner {
1884
+ margin: 1cm;
1885
+ }
1886
+ @bottom-left {
1887
+ margin: 1cm;
1888
+ }
1889
+ @bottom-left-corner {
1890
+ margin: 1cm;
1891
+ }
1892
+ @bottom-center {
1893
+ margin: 1cm;
1894
+ }
1895
+ @bottom-right {
1896
+ margin: 1cm;
1897
+ }
1898
+ @bottom-right-corner {
1899
+ margin: 1cm;
1900
+ }
1901
+ @left-top {
1902
+ margin: 1cm;
1903
+ }
1904
+ @left-middle {
1905
+ margin: 1cm;
1906
+ }
1907
+ @left-bottom {
1908
+ margin: 1cm;
1909
+ }
1910
+ @right-top {
1911
+ margin: 1cm;
1912
+ }
1913
+ @right-middle {
1914
+ content: "Page " counter(page);
1915
+ }
1916
+ @right-bottom {
1917
+ margin: 1cm;
1918
+ }
1919
+ }
1920
+ }
1921
+ @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: "2/1"), (min-resolution: 2dppx), (min-resolution: 128dpcm) {
1922
+ .b {
1923
+ background: red;
1924
+ }
1925
+ }
1926
+ .body {
1927
+ background: red;
1928
+ }
1929
+ @media (max-width: 500px) {
1930
+ .body {
1931
+ background: green;
1932
+ }
1933
+ }
1934
+ @media (max-width: 1000px) {
1935
+ .body {
1936
+ background: red;
1937
+ }
1938
+ @media (max-width: 500px) {
1939
+ .body {
1940
+ background: green;
1941
+ }
1942
+ }
1943
+ .body {
1944
+ background: blue;
1945
+ }
1946
+ }
1947
+ @media (max-width: 1200px) {
1948
+ /* a comment */
1949
+ @media (max-width: 900px) {
1950
+ .body {
1951
+ font-size: 11px;
1952
+ }
1953
+ }
1954
+ }
1955
+ @media (min-width: 480px) {
1956
+ .nav-justified .nav-justified .nav-justified > li {
1957
+ display: table-cell;
1958
+ }
1959
+ }
1960
+ @media (min-width: 768px) {
1961
+ @media (min-width: 480px) {
1962
+ .menu .menu .menu .menu > li {
1963
+ display: table-cell;
1964
+ }
1965
+ }
1966
+ }
1967
+ @media all and (tv) {
1968
+ .all-and-tv-variables {
1969
+ var: all-and-tv;
1970
+ }
1971
+ }
1972
+ @media screen and (min-width: 61px) {
1973
+ .selector {
1974
+ foo: bar;
1975
+ }
1976
+ }
1977
+ @media screen and (color), projection and (color) {
1978
+ .selector {
1979
+ color: #eee;
1980
+ }
1981
+ }
1982
+ @media not (width <= -100px) {
1983
+ body {
1984
+ background: green;
1985
+ }
1986
+ }
1987
+ @media (height > -100px) {
1988
+ body {
1989
+ background: green;
1990
+ }
1991
+ }
1992
+ @media not (resolution: -300dpi) {
1993
+ body {
1994
+ background: green;
1995
+ }
1996
+ }
1997
+ @media (min-orientation: portrait) {
1998
+ body {
1999
+ background: green;
2000
+ }
2001
+ }
2002
+ @media print and (min-resolution: 118dpcm) {
2003
+ body {
2004
+ background: green;
2005
+ }
2006
+ }
2007
+ @media (200px <= width <= 500px) {
2008
+ .test-range-syntax {
2009
+ padding: 0;
2010
+ }
2011
+ }
2012
+ .selector {
2013
+ color: #eee;
2014
+ }
2015
+ @media (200px <= width <= 500px) {
2016
+ .selector .selector .selector .test-range-syntax {
2017
+ padding: 0;
2018
+ }
2019
+ }
2020
+ @media print, (max-width: 992px) {
2021
+ body {
2022
+ background: green;
2023
+ }
2024
+ }
2025
+ `);
2026
+ });
2027
+ });
2028
+
2029
+ describe('evaluation', () => {
2030
+ it('evaluates interpolated names and preludes before serialization', async () => {
2031
+ const node = atrule({
2032
+ name: interpolated({
2033
+ source: '@%%',
2034
+ replacements: [expr(any('media'))]
2035
+ }, { role: 'atkeyword' }),
2036
+ prelude: seq([expr(any('screen'))]),
2037
+ rules: rules([
2038
+ decl({ name: 'color', value: expr(any('blue')) })
2039
+ ])
2040
+ });
2041
+
2042
+ const evald = await node.eval(context);
2043
+
2044
+ expect(evald.render(context)).toBe('@media screen {\n color: blue;\n}\n');
2045
+ });
2046
+ });
2047
+ });