@tbela99/css-parser 1.4.2 → 1.4.3

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 (216) hide show
  1. package/.nyc_output/4874b20e-6f53-4d7a-be5a-cf68316925f2.json +1 -0
  2. package/.nyc_output/6193bc4c-6f5f-4898-8950-c628825e6342.json +1 -0
  3. package/.nyc_output/processinfo/4874b20e-6f53-4d7a-be5a-cf68316925f2.json +1 -0
  4. package/.nyc_output/processinfo/6193bc4c-6f5f-4898-8950-c628825e6342.json +1 -0
  5. package/.repl_history +4 -0
  6. package/CHANGELOG.md +164 -4
  7. package/README.md +43 -0
  8. package/badges/coverage.svg +20 -0
  9. package/deno.lock +2861 -0
  10. package/dist/config.json.js +33 -1
  11. package/dist/index-umd-web.js +24382 -18476
  12. package/dist/index.cjs +24522 -18618
  13. package/dist/index.d.ts +1396 -929
  14. package/dist/lib/ast/clone.d.ts +10 -0
  15. package/dist/lib/ast/clone.js +45 -0
  16. package/dist/lib/ast/expand.d.ts +14 -0
  17. package/dist/lib/ast/expand.js +89 -64
  18. package/dist/lib/ast/features/calc.d.ts +10 -0
  19. package/dist/lib/ast/features/calc.js +62 -24
  20. package/dist/lib/ast/features/if.d.ts +10 -0
  21. package/dist/lib/ast/features/if.js +215 -0
  22. package/dist/lib/ast/features/index.d.ts +6 -0
  23. package/dist/lib/ast/features/index.js +1 -0
  24. package/dist/lib/ast/features/inlinecssvariables.d.ts +15 -0
  25. package/dist/lib/ast/features/inlinecssvariables.js +32 -27
  26. package/dist/lib/ast/features/prefix.d.ts +8 -0
  27. package/dist/lib/ast/features/prefix.js +68 -43
  28. package/dist/lib/ast/features/shorthand.d.ts +12 -0
  29. package/dist/lib/ast/features/shorthand.js +6 -9
  30. package/dist/lib/ast/features/transform.d.ts +10 -0
  31. package/dist/lib/ast/features/transform.js +9 -13
  32. package/dist/lib/ast/features/type.d.ts +15 -0
  33. package/dist/lib/ast/find.d.ts +165 -0
  34. package/dist/lib/ast/find.js +175 -0
  35. package/dist/lib/ast/math/expression.d.ts +18 -0
  36. package/dist/lib/ast/math/expression.js +140 -98
  37. package/dist/lib/ast/math/math.d.ts +6 -0
  38. package/dist/lib/ast/math/math.js +30 -41
  39. package/dist/lib/ast/minify.d.ts +19 -0
  40. package/dist/lib/ast/minify.js +541 -217
  41. package/dist/lib/ast/transform/compute.d.ts +8 -0
  42. package/dist/lib/ast/transform/compute.js +82 -69
  43. package/dist/lib/ast/transform/matrix.d.ts +22 -0
  44. package/dist/lib/ast/transform/matrix.js +12 -26
  45. package/dist/lib/ast/transform/minify.d.ts +5 -0
  46. package/dist/lib/ast/transform/minify.js +20 -20
  47. package/dist/lib/ast/transform/perspective.d.ts +3 -0
  48. package/dist/lib/ast/transform/perspective.js +1 -1
  49. package/dist/lib/ast/transform/rotate.d.ts +12 -0
  50. package/dist/lib/ast/transform/rotate.js +1 -1
  51. package/dist/lib/ast/transform/scale.d.ts +6 -0
  52. package/dist/lib/ast/transform/scale.js +1 -1
  53. package/dist/lib/ast/transform/skew.d.ts +4 -0
  54. package/dist/lib/ast/transform/skew.js +1 -1
  55. package/dist/lib/ast/transform/translate.d.ts +6 -0
  56. package/dist/lib/ast/transform/translate.js +1 -1
  57. package/dist/lib/ast/transform/utils.d.ts +9 -0
  58. package/dist/lib/ast/types.d.ts +903 -0
  59. package/dist/lib/ast/types.js +277 -23
  60. package/dist/lib/ast/walk.d.ts +162 -0
  61. package/dist/lib/ast/walk.js +116 -60
  62. package/dist/lib/fs/resolve.d.ts +20 -0
  63. package/dist/lib/fs/resolve.js +37 -45
  64. package/dist/lib/parser/declaration/list.d.ts +16 -0
  65. package/dist/lib/parser/declaration/list.js +26 -24
  66. package/dist/lib/parser/declaration/map.d.ts +15 -0
  67. package/dist/lib/parser/declaration/map.js +140 -95
  68. package/dist/lib/parser/declaration/set.d.ts +9 -0
  69. package/dist/lib/parser/declaration/set.js +30 -25
  70. package/dist/lib/parser/node.d.ts +7 -0
  71. package/dist/lib/parser/parse.d.ts +107 -0
  72. package/dist/lib/parser/parse.js +1454 -1445
  73. package/dist/lib/parser/tokenize.d.ts +57 -0
  74. package/dist/lib/parser/tokenize.js +557 -404
  75. package/dist/lib/parser/utils/at-rule-container.d.ts +5 -0
  76. package/dist/lib/parser/utils/at-rule-container.js +486 -0
  77. package/dist/lib/parser/utils/at-rule-font-feature-values.d.ts +5 -0
  78. package/dist/lib/parser/utils/at-rule-font-feature-values.js +13 -0
  79. package/dist/lib/parser/utils/at-rule-generic.d.ts +5 -0
  80. package/dist/lib/parser/utils/at-rule-generic.js +118 -0
  81. package/dist/lib/parser/utils/at-rule-import.d.ts +5 -0
  82. package/dist/lib/parser/utils/at-rule-import.js +393 -0
  83. package/dist/lib/parser/utils/at-rule-media.d.ts +5 -0
  84. package/dist/lib/parser/utils/at-rule-media.js +603 -0
  85. package/dist/lib/parser/utils/at-rule-page.d.ts +5 -0
  86. package/dist/lib/parser/utils/at-rule-page.js +28 -0
  87. package/dist/lib/parser/utils/at-rule-support.d.ts +5 -0
  88. package/dist/lib/parser/utils/at-rule-support.js +366 -0
  89. package/dist/lib/parser/utils/at-rule-token.d.ts +1 -0
  90. package/dist/lib/parser/utils/at-rule-when-else.d.ts +5 -0
  91. package/dist/lib/parser/utils/at-rule-when-else.js +363 -0
  92. package/dist/lib/parser/utils/at-rule.d.ts +13 -0
  93. package/dist/lib/parser/utils/at-rule.js +37 -0
  94. package/dist/lib/parser/utils/cache.d.ts +6 -0
  95. package/dist/lib/parser/utils/cache.js +19 -0
  96. package/dist/lib/parser/utils/config.d.ts +2 -0
  97. package/dist/lib/parser/utils/config.js +1 -0
  98. package/dist/lib/parser/utils/declaration-list.d.ts +5 -0
  99. package/dist/lib/parser/utils/declaration.d.ts +18 -0
  100. package/dist/lib/parser/utils/declaration.js +569 -91
  101. package/dist/lib/parser/utils/eq.d.ts +1 -0
  102. package/dist/lib/parser/utils/hash.d.ts +21 -0
  103. package/dist/lib/parser/utils/hash.js +1 -1
  104. package/dist/lib/parser/utils/selector.d.ts +5 -0
  105. package/dist/lib/parser/utils/selector.js +476 -0
  106. package/dist/lib/parser/utils/text.d.ts +3 -0
  107. package/dist/lib/parser/utils/text.js +17 -1
  108. package/dist/lib/parser/utils/token.d.ts +14 -0
  109. package/dist/lib/parser/utils/token.js +102 -0
  110. package/dist/lib/parser/utils/type.d.ts +2 -0
  111. package/dist/lib/parser/utils/type.js +29 -18
  112. package/dist/lib/renderer/render.d.ts +28 -0
  113. package/dist/lib/renderer/render.js +421 -262
  114. package/dist/lib/renderer/sourcemap/lib/encode.d.ts +1 -0
  115. package/dist/lib/renderer/sourcemap/sourcemap.d.ts +26 -0
  116. package/dist/lib/renderer/sourcemap/sourcemap.js +17 -7
  117. package/dist/lib/syntax/color/a98rgb.d.ts +2 -0
  118. package/dist/lib/syntax/color/a98rgb.js +8 -12
  119. package/dist/lib/syntax/color/cmyk.d.ts +10 -0
  120. package/dist/lib/syntax/color/cmyk.js +23 -21
  121. package/dist/lib/syntax/color/color-mix.d.ts +2 -0
  122. package/dist/lib/syntax/color/color-mix.js +88 -77
  123. package/dist/lib/syntax/color/color.d.ts +42 -0
  124. package/dist/lib/syntax/color/color.js +65 -68
  125. package/dist/lib/syntax/color/hex.d.ts +16 -0
  126. package/dist/lib/syntax/color/hex.js +27 -31
  127. package/dist/lib/syntax/color/hsl.d.ts +20 -0
  128. package/dist/lib/syntax/color/hsl.js +5 -12
  129. package/dist/lib/syntax/color/hsv.d.ts +2 -0
  130. package/dist/lib/syntax/color/hwb.d.ts +21 -0
  131. package/dist/lib/syntax/color/hwb.js +8 -21
  132. package/dist/lib/syntax/color/lab.d.ts +25 -0
  133. package/dist/lib/syntax/color/lab.js +20 -21
  134. package/dist/lib/syntax/color/lch.d.ts +23 -0
  135. package/dist/lib/syntax/color/lch.js +13 -15
  136. package/dist/lib/syntax/color/oklab.d.ts +22 -0
  137. package/dist/lib/syntax/color/oklab.js +20 -39
  138. package/dist/lib/syntax/color/oklch.d.ts +20 -0
  139. package/dist/lib/syntax/color/oklch.js +14 -16
  140. package/dist/lib/syntax/color/p3.d.ts +6 -0
  141. package/dist/lib/syntax/color/p3.js +0 -8
  142. package/dist/lib/syntax/color/prophotorgb.d.ts +2 -0
  143. package/dist/lib/syntax/color/rec2020.d.ts +2 -0
  144. package/dist/lib/syntax/color/rec2020.js +9 -13
  145. package/dist/lib/syntax/color/relativecolor.d.ts +13 -0
  146. package/dist/lib/syntax/color/relativecolor.js +68 -41
  147. package/dist/lib/syntax/color/rgb.d.ts +20 -0
  148. package/dist/lib/syntax/color/rgb.js +14 -18
  149. package/dist/lib/syntax/color/srgb.d.ts +23 -0
  150. package/dist/lib/syntax/color/srgb.js +27 -26
  151. package/dist/lib/syntax/color/utils/components.d.ts +2 -0
  152. package/dist/lib/syntax/color/utils/components.js +30 -14
  153. package/dist/lib/syntax/color/utils/distance.d.ts +18 -0
  154. package/dist/lib/syntax/color/utils/distance.js +1 -8
  155. package/dist/lib/syntax/color/utils/matrix.d.ts +6 -0
  156. package/dist/lib/syntax/color/xyz.d.ts +5 -0
  157. package/dist/lib/syntax/color/xyz.js +8 -20
  158. package/dist/lib/syntax/color/xyzd50.d.ts +4 -0
  159. package/dist/lib/syntax/color/xyzd50.js +6 -20
  160. package/dist/lib/syntax/constants.d.ts +67 -0
  161. package/dist/lib/syntax/constants.js +436 -0
  162. package/dist/lib/syntax/syntax.d.ts +38 -0
  163. package/dist/lib/syntax/syntax.js +533 -568
  164. package/dist/lib/validation/config.d.ts +14 -0
  165. package/dist/lib/validation/config.js +72 -33
  166. package/dist/lib/validation/config.json.js +1159 -74
  167. package/dist/lib/validation/json.d.ts +2 -0
  168. package/dist/lib/validation/match.d.ts +38 -0
  169. package/dist/lib/validation/match.js +2985 -0
  170. package/dist/lib/validation/parser/parse.d.ts +8 -0
  171. package/dist/lib/validation/parser/parse.js +684 -935
  172. package/dist/lib/validation/parser/typedef.d.ts +95 -0
  173. package/dist/lib/validation/parser/typedef.js +100 -0
  174. package/dist/lib/validation/utils/list.d.ts +4 -0
  175. package/dist/lib/validation/utils/list.js +4 -11
  176. package/dist/lib/validation/utils/whitespace.d.ts +2 -0
  177. package/dist/lib/validation/utils/whitespace.js +2 -8
  178. package/dist/node.d.ts +207 -0
  179. package/dist/node.js +42 -39
  180. package/dist/web.d.ts +169 -0
  181. package/dist/web.js +38 -33
  182. package/package.json +15 -12
  183. package/playground/index.html +1328 -0
  184. package/playground/sw.js +55 -0
  185. package/playground/tree.js +176 -0
  186. package/dist/lib/syntax/color/utils/constants.js +0 -214
  187. package/dist/lib/syntax/utils.js +0 -70
  188. package/dist/lib/validation/at-rules/container.js +0 -342
  189. package/dist/lib/validation/at-rules/counter-style.js +0 -90
  190. package/dist/lib/validation/at-rules/custom-media.js +0 -50
  191. package/dist/lib/validation/at-rules/document.js +0 -89
  192. package/dist/lib/validation/at-rules/else.js +0 -5
  193. package/dist/lib/validation/at-rules/font-feature-values.js +0 -63
  194. package/dist/lib/validation/at-rules/import.js +0 -150
  195. package/dist/lib/validation/at-rules/keyframes.js +0 -67
  196. package/dist/lib/validation/at-rules/layer.js +0 -41
  197. package/dist/lib/validation/at-rules/media.js +0 -255
  198. package/dist/lib/validation/at-rules/namespace.js +0 -81
  199. package/dist/lib/validation/at-rules/page-margin-box.js +0 -64
  200. package/dist/lib/validation/at-rules/page.js +0 -100
  201. package/dist/lib/validation/at-rules/supports.js +0 -295
  202. package/dist/lib/validation/at-rules/when.js +0 -185
  203. package/dist/lib/validation/atrule.js +0 -184
  204. package/dist/lib/validation/selector.js +0 -36
  205. package/dist/lib/validation/syntax.js +0 -1073
  206. package/dist/lib/validation/syntaxes/complex-selector-list.js +0 -27
  207. package/dist/lib/validation/syntaxes/complex-selector.js +0 -52
  208. package/dist/lib/validation/syntaxes/compound-selector.js +0 -196
  209. package/dist/lib/validation/syntaxes/family-name.js +0 -57
  210. package/dist/lib/validation/syntaxes/keyframe-selector.js +0 -36
  211. package/dist/lib/validation/syntaxes/layer-name.js +0 -57
  212. package/dist/lib/validation/syntaxes/relative-selector-list.js +0 -31
  213. package/dist/lib/validation/syntaxes/relative-selector.js +0 -38
  214. package/dist/lib/validation/syntaxes/selector-list.js +0 -5
  215. package/dist/lib/validation/syntaxes/selector.js +0 -5
  216. package/dist/lib/validation/syntaxes/url.js +0 -40
@@ -0,0 +1,1328 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>@tbela99/css-parser Playground</title>
6
+ <meta content="width=device-width, initial-scale=1" name="viewport"/>
7
+ <meta content="@tbela99/css-parser demonstration" name="description"/>
8
+ <meta content="@tbela99/css-parser Playground" name="title"/>
9
+ <meta
10
+ content="parser,css,css-parser,node,ast,nesting,nested,compiler,browser,css-nesting,css-compiler,nested-css,walker,stream,streaming,streaming-parser"
11
+ name="keywords"
12
+ />
13
+ <link
14
+ crossorigin="anonymous"
15
+ href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
16
+ integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
17
+ rel="stylesheet"
18
+ />
19
+ <link
20
+ href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
21
+ rel="stylesheet"
22
+ />
23
+ <title>@tbela99/css-parser Playground</title>
24
+ <style>
25
+
26
+ .css-parse-options-module-box {
27
+ display: none;
28
+ }
29
+
30
+ .css-parse-options-module {
31
+
32
+ .css-parse-options-module-box {
33
+ display: block;
34
+ }
35
+ }
36
+
37
+ .css-tree {
38
+ list-style: none;
39
+ font-size: 14px;
40
+
41
+ .property {
42
+ cursor: pointer;
43
+ }
44
+
45
+ ul {
46
+ list-style: none;
47
+ padding-left: 15px;
48
+
49
+ > li:not(.tree-collapsed) > .tree-more-dots {
50
+ display: none;
51
+ }
52
+ }
53
+ }
54
+
55
+ .tree-collapsed {
56
+ > ul {
57
+ display: none;
58
+ }
59
+
60
+ > .e:before {
61
+ content: "\2192";
62
+ }
63
+ }
64
+
65
+ .e:before {
66
+ content: "\2193";
67
+ cursor: pointer;
68
+ }
69
+ </style>
70
+ <script>
71
+ document.documentElement.setAttribute(
72
+ "data-bs-theme",
73
+ window.matchMedia("(prefers-color-scheme: dark)").matches
74
+ ? "dark"
75
+ : "light"
76
+ );
77
+ </script>
78
+ </head>
79
+ <body>
80
+
81
+ <nav class="navbar navbar-expand-lg bg-body-tertiary mb-2">
82
+ <div class="container-fluid">
83
+ <a class="navbar-brand" href="https://github.com/tbela99/css-parser">@tbela99/css-parser</a>
84
+ <button aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"
85
+ class="navbar-toggler" data-bs-target="#navbarSupportedContent" data-bs-toggle="collapse" type="button">
86
+ <span class="navbar-toggler-icon"></span>
87
+ </button>
88
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
89
+ <ul class="navbar-nav me-auto mb-2 mb-lg-0">
90
+ <li class="nav-item">
91
+ <a aria-current="page" class="nav-link"
92
+ href="https://tbela99.github.io/css-parser/benchmark/index.html">Benchmark</a>
93
+ </li>
94
+ <li class="nav-item">
95
+ <a class="nav-link active" href="https://tbela99.github.io/css-parser/playground/">Playground</a>
96
+ </li>
97
+ <li class="nav-item">
98
+ <a class="nav-link" href="https://tbela99.github.io/css-parser/docs/">Docs</a>
99
+ </li>
100
+ <li class="nav-item">
101
+ <a class="nav-link" href="https://github.com/tbela99/css-parser">GitHub</a>
102
+ </li>
103
+ </ul>
104
+ </div>
105
+ </div>
106
+ </nav>
107
+ <div class="container-fluid mt-15">
108
+ <div class="row">
109
+ <div class="col-md-2">
110
+ <div class="row" id="optionsWrapper">
111
+ <div class="col-sm-12">
112
+ <div class="mb-3">
113
+ <label class="form-label">Parse Options</label>
114
+ <hr class="mt-0"/>
115
+ <div class="form-check">
116
+ <input
117
+ checked
118
+ class="form-check-input"
119
+ id="parseoptionsminify"
120
+ name="parseoptions[minify]"
121
+ type="checkbox"
122
+ value=""
123
+ />
124
+ <label class="form-check-label" for="parseoptionsminify">
125
+ Minify
126
+ </label>
127
+ </div>
128
+ <div class="form-check">
129
+ <input
130
+ class="form-check-input"
131
+ id="parseoptionsmodule"
132
+ name="parseoptions[module]"
133
+ type="checkbox"
134
+ value=""
135
+ />
136
+ <label class="form-check-label" for="parseoptionsmodule">
137
+ CSS module
138
+ </label>
139
+ </div>
140
+ <div class="form-check">
141
+ <input
142
+ checked
143
+ class="form-check-input"
144
+ id="parseoptionsparseColor"
145
+ name="parseoptions[parseColor]"
146
+ type="checkbox"
147
+ value=""
148
+ />
149
+ <label class="form-check-label" for="parseoptionsparseColor">
150
+ Parse color
151
+ </label>
152
+ </div>
153
+ <div class="form-check">
154
+ <input
155
+ class="form-check-input"
156
+ id="parseoptionsresolveImport"
157
+ name="parseoptions[resolveImport]"
158
+ type="checkbox"
159
+ value=""
160
+ />
161
+ <label
162
+ class="form-check-label"
163
+ for="parseoptionsresolveImport"
164
+ >
165
+ Resolve @import
166
+ </label>
167
+ </div>
168
+ <div class="form-check">
169
+ <input
170
+ checked
171
+ class="form-check-input"
172
+ id="parseoptionsremoveCharset"
173
+ name="parseoptions[removeCharset]"
174
+ type="checkbox"
175
+ value=""
176
+ />
177
+ <label
178
+ class="form-check-label"
179
+ for="parseoptionsremoveCharset"
180
+ >
181
+ Remove @charset
182
+ </label>
183
+ </div>
184
+ <div class="form-check">
185
+ <input
186
+ checked
187
+ class="form-check-input"
188
+ id="parseoptionsremoveEmpty"
189
+ name="parseoptions[removeEmpty]"
190
+ type="checkbox"
191
+ value=""
192
+ />
193
+ <label class="form-check-label" for="parseoptionsremoveEmpty">
194
+ Remove empty nodes
195
+ </label>
196
+ </div>
197
+ <div class="form-check">
198
+ <input
199
+ checked
200
+ class="form-check-input"
201
+ id="parseoptionsremovePrefix"
202
+ name="parseoptions[removePrefix]"
203
+ type="checkbox"
204
+ value=""
205
+ />
206
+ <label
207
+ class="form-check-label"
208
+ for="parseoptionsremovePrefix"
209
+ >
210
+ Remove CSS prefixes
211
+ </label>
212
+ </div>
213
+ <div class="form-check">
214
+ <input
215
+ checked
216
+ class="form-check-input"
217
+ id="parseoptionsremoveDuplicateDeclarations"
218
+ name="parseoptions[removeDuplicateDeclarations]"
219
+ type="checkbox"
220
+ value=""
221
+ />
222
+ <label
223
+ class="form-check-label"
224
+ for="parseoptionsremoveDuplicateDeclarations"
225
+ >
226
+ Deduplicate declarations
227
+ </label>
228
+ </div>
229
+ <div class="form-check">
230
+ <input
231
+ checked
232
+ class="form-check-input"
233
+ id="parseoptionscomputeShorthand"
234
+ name="parseoptions[computeShorthand]"
235
+ type="checkbox"
236
+ value=""
237
+ />
238
+ <label
239
+ class="form-check-label"
240
+ for="parseoptionscomputeShorthand"
241
+ >
242
+ Shorthand
243
+ </label>
244
+ </div>
245
+ <div class="form-check">
246
+ <input
247
+ checked
248
+ class="form-check-input"
249
+ id="parseoptionscomputeCalcExpression"
250
+ name="parseoptions[computeCalcExpression]"
251
+ type="checkbox"
252
+ value=""
253
+ />
254
+ <label
255
+ class="form-check-label"
256
+ for="parseoptionscomputeCalcExpression"
257
+ >
258
+ Math expressions
259
+ </label>
260
+ </div>
261
+ <div class="form-check">
262
+ <input
263
+ checked
264
+ class="form-check-input"
265
+ id="parseoptionsinlineCssVariables"
266
+ name="parseoptions[inlineCssVariables]"
267
+ type="checkbox"
268
+ value=""
269
+ />
270
+ <label
271
+ class="form-check-label"
272
+ for="parseoptionsinlineCssVariables"
273
+ >
274
+ Inline CSS variables
275
+ </label>
276
+ </div>
277
+ <div class="form-check">
278
+ <input
279
+ checked
280
+ class="form-check-input"
281
+ id="parseoptionsTransform"
282
+ name="parseoptions[computeTransform]"
283
+ type="checkbox"
284
+ value=""
285
+ />
286
+ <label class="form-check-label" for="parseoptionsTransform">
287
+ Minify Transform
288
+ </label>
289
+ </div>
290
+ <div class="form-check">
291
+ <input
292
+ checked
293
+ class="form-check-input"
294
+ id="parseoptionsLenient"
295
+ name="parseoptions[lenient]"
296
+ type="checkbox"
297
+ value=""
298
+ />
299
+ <label class="form-check-label" for="parseoptionsLenient">
300
+ Lenient validation
301
+ </label>
302
+ </div>
303
+ <div class="form-check">
304
+ <input
305
+ checked
306
+ class="form-check-input"
307
+ id="parseoptionsnestingRules"
308
+ name="parseoptions[nestingRules]"
309
+ type="checkbox"
310
+ value=""
311
+ />
312
+ <label
313
+ class="form-check-label"
314
+ for="parseoptionsnestingRules"
315
+ >
316
+ CSS Nesting
317
+ </label>
318
+ </div>
319
+
320
+ <div class="form-check">
321
+ <input
322
+ class="form-check-input"
323
+ id="parseoptionsexpandNestingRules"
324
+ name="parseoptions[expandNestingRules]"
325
+ type="checkbox"
326
+ value=""
327
+ />
328
+ <label
329
+ class="form-check-label"
330
+ for="parseoptionsexpandNestingRules"
331
+ >
332
+ Expand nesting rules
333
+ </label>
334
+ </div>
335
+
336
+ <div class="form-check">
337
+ <input
338
+ class="form-check-input"
339
+ id="parseoptionsexpandIfSyntax"
340
+ name="parseoptions[expandIfSyntax]"
341
+ type="checkbox"
342
+ value=""
343
+ />
344
+ <label
345
+ class="form-check-label"
346
+ for="parseoptionsexpandIfSyntax"
347
+ >
348
+ Expand if() function
349
+ </label>
350
+ </div>
351
+ <div class="form-check">
352
+ <input
353
+ class="form-check-input"
354
+ id="parseoptionsresolveUrls"
355
+ name="parseoptions[resolveUrls]"
356
+ type="checkbox"
357
+ value=""
358
+ />
359
+ <label class="form-check-label" for="parseoptionsresolveUrls">
360
+ Rewrite URLs
361
+ </label>
362
+ </div>
363
+ <div class="form-check">
364
+ <input
365
+ class="form-check-input"
366
+ id="parseoptionssourcemap"
367
+ name="parseoptions[sourcemap]"
368
+ type="checkbox"
369
+ value=""
370
+ />
371
+ <label class="form-check-label" for="parseoptionssourcemap">
372
+ Sourcemap
373
+ </label>
374
+ </div>
375
+ <div class="form-check">
376
+ <label class="form-check-label" for="parseoptionsValidation">
377
+ Validation
378
+ </label>
379
+
380
+ <select
381
+ class="form-select form-select-sm"
382
+ id="parseoptionsValidation"
383
+ name="parseoptions[validation]"
384
+ >
385
+ <option value="0">None</option>
386
+ <option value="1">Selector</option>
387
+ <option value="2">AtRule</option>
388
+ <option value="4">Declaration</option>
389
+ <option selected value="3">Default</option>
390
+ <option value="7">All</option>
391
+ </select>
392
+ </div>
393
+ <hr/>
394
+ </div>
395
+ </div>
396
+ <div class="col-sm-12">
397
+ <div class="mb-3">
398
+ <label class="form-label">Render Options</label>
399
+ <hr class="mt-0"/>
400
+
401
+ <div class="form-check">
402
+ <input
403
+ checked
404
+ class="form-check-input"
405
+ id="renderoptionsbeautify"
406
+ name="renderoptions[beautify]"
407
+ type="checkbox"
408
+ value=""
409
+ />
410
+ <label class="form-check-label" for="renderoptionsbeautify">
411
+ Beautify
412
+ </label>
413
+ </div>
414
+ <div class="form-check">
415
+ <input
416
+ checked
417
+ class="form-check-input"
418
+ id="renderoptionsminify"
419
+ name="renderoptions[minify]"
420
+ type="checkbox"
421
+ value=""
422
+ />
423
+ <label class="form-check-label" for="renderoptionsminify">
424
+ Minify
425
+ </label>
426
+ </div>
427
+ <div class="form-check">
428
+ <label
429
+ class="form-check-label"
430
+ for="renderoptionsconvertColor"
431
+ >
432
+ Convert color
433
+ </label>
434
+ <select
435
+ class="form-select form-select-sm"
436
+ id="renderoptionsconvertColor"
437
+ name="renderoptions[convertColor]"
438
+ >
439
+ <option value="NONE">NONE</option>
440
+ <option selected value="HEX">HEX</option>
441
+ <option value="RGB">RGB</option>
442
+ <option value="HSL">HSL</option>
443
+ <option value="HWB">HWB</option>
444
+ <option value="CMYK">CMYK</option>
445
+ <option value="SRGB">SRGB</option>
446
+ <option value="SRGB_LINEAR">SRGB_LINEAR</option>
447
+ <option value="DISPLAY_P3">DISPLAY_P3</option>
448
+ <option value="PROPHOTO_RGB">PROPHOTO_RGB</option>
449
+ <option value="A98_RGB">A98_RGB</option>
450
+ <option value="REC2020">REC2020</option>
451
+ <option value="XYZ">XYZ</option>
452
+ <option value="XYZ_D50">XYZ_D50</option>
453
+ <option value="LAB">LAB</option>
454
+ <option value="LCH">LCH</option>
455
+ <option value="OKLAB">OKLAB</option>
456
+ <option value="OKLCH">OKLCH</option>
457
+ </select>
458
+ </div>
459
+ <div class="form-check">
460
+ <input
461
+ checked
462
+ class="form-check-input"
463
+ id="renderoptionsremoveComments"
464
+ name="renderoptions[removeComments]"
465
+ type="checkbox"
466
+ value=""
467
+ />
468
+ <label
469
+ class="form-check-label"
470
+ for="renderoptionsremoveComments"
471
+ >
472
+ Remove comments
473
+ </label>
474
+ </div>
475
+ <div class="form-check">
476
+ <input
477
+ class="form-check-input"
478
+ id="renderoptionspreserveLicense"
479
+ name="renderoptions[preserveLicense]"
480
+ type="checkbox"
481
+ value=""
482
+ />
483
+ <label
484
+ class="form-check-label"
485
+ for="renderoptionspreserveLicense"
486
+ >
487
+ Preserve license
488
+ </label>
489
+ </div>
490
+ <div class="form-check">
491
+ <input
492
+ class="form-check-input"
493
+ id="renderoptionssourcemap"
494
+ name="renderoptions[sourcemap]"
495
+ type="checkbox"
496
+ value=""
497
+ />
498
+ <label class="form-check-label" for="renderoptionssourcemap">
499
+ Soucemap
500
+ </label>
501
+ </div>
502
+ <div class="form-check">
503
+ <input
504
+ class="form-check-input"
505
+ id="renderoptionsexpandNestingRules"
506
+ name="renderoptions[expandNestingRules]"
507
+ type="checkbox"
508
+ value=""
509
+ />
510
+ <label
511
+ class="form-check-label"
512
+ for="renderoptionsexpandNestingRules"
513
+ >
514
+ Expand nesting rules
515
+ </label>
516
+ </div>
517
+ <hr/>
518
+ </div>
519
+ </div>
520
+ </div>
521
+ </div>
522
+ <div class="col-md-10" id="zone">
523
+ <div class="row">
524
+ <div class="col-sm-12 col-md-6">
525
+ <div class="mb-3">
526
+ <div class="row">
527
+ <div class="col-sm-9">
528
+ <div class="input-group mb-3" data-type="preset-group">
529
+ <label class="input-group-text" for="css"
530
+ >CSS Preset
531
+ </label>
532
+ <select class="form-select form-control" name="preset">
533
+ <option value="">None</option>
534
+ <option selected value="calc">Calc</option>
535
+ <option value="validation">Validation</option>
536
+ <option value="prefix">Remove Prefixes</option>
537
+ <option value="bootstrap">Import Bootstrap</option>
538
+ <option value="tailwind">Import Tailwind CSS</option>
539
+ </select>
540
+ </div>
541
+ </div>
542
+ <div class="col-sm-3">
543
+ <div class="input-group mb-3">
544
+ <button
545
+ class="btn btn-outline-secondary"
546
+ data-bs-copy="css"
547
+ type="button"
548
+ >
549
+ <i class="bi bi-copy"></i>
550
+ </button>
551
+ </div>
552
+ </div>
553
+ </div>
554
+ <textarea class="form-control" id="css" name="css" rows="10">
555
+ :root {
556
+ --color: green;
557
+ }
558
+ ._19_u :focus {
559
+ color: hsl(from var(--color) calc(h * 2) s l);
560
+ }
561
+ :root {
562
+ --preferred-width: 20px;
563
+ }
564
+ .foo-bar {
565
+ width: calc(calc(var(--preferred-width) + 1px) / 3 + 5px);
566
+ height: calc(100% / 4);
567
+ transform: scaleX(1.5) scaleY(2);
568
+ }}</textarea
569
+ >
570
+ </div>
571
+ </div>
572
+ <div class="col-sm-12 col-md-6">
573
+ <div class="mb-3">
574
+ <div class="row">
575
+ <div class="col-sm-9">
576
+ <div class="input-group mb-3">
577
+ <label class="input-group-text" for="result"
578
+ >CSS</label
579
+ >
580
+ <a
581
+ class="btn btn-outline-secondary"
582
+ download="result"
583
+ href="#"
584
+ >
585
+ <i class="bi bi-download"></i>
586
+ </a>
587
+ </div>
588
+ </div>
589
+ <div class="col-sm-3">
590
+ <div class="input-group mb-3">
591
+ <button
592
+ class="btn btn-outline-secondary"
593
+ data-bs-copy="result"
594
+ type="button"
595
+ >
596
+ <i class="bi bi-copy"></i>
597
+ </button>
598
+ </div>
599
+ </div>
600
+ </div>
601
+ <textarea
602
+ class="form-control"
603
+ disabled
604
+ id="result"
605
+ name="result"
606
+ rows="10"
607
+ ></textarea>
608
+ </div>
609
+ </div>
610
+ <div class="col-sm-12 col-md-6 css-parse-options-module-box">
611
+ <div class="mb-3">
612
+ <div class="row">
613
+ <div class="col-sm-9">
614
+ <div class="input-group mb-3">
615
+ <label class="input-group-text" for="mapping"
616
+ >CSS Modules Mapping</label
617
+ >
618
+ <a
619
+ class="btn btn-outline-secondary"
620
+ download="mapping"
621
+ href="#"
622
+ >
623
+ <i class="bi bi-download"></i>
624
+ </a>
625
+ </div>
626
+ </div>
627
+ <div class="col-sm-3">
628
+ <div class="input-group mb-3">
629
+ <button
630
+ class="btn btn-outline-secondary"
631
+ data-bs-copy="mapping"
632
+ type="button"
633
+ >
634
+ <i class="bi bi-copy"></i>
635
+ </button>
636
+ </div>
637
+ </div>
638
+ </div>
639
+ <textarea
640
+ class="form-control"
641
+ disabled
642
+ id="mapping"
643
+ name="mapping"
644
+ rows="10"
645
+ ></textarea>
646
+ </div>
647
+ </div>
648
+ <div class="col-sm-12 col-md-6">
649
+ <div class="mb-3">
650
+ <div class="row">
651
+ <div class="col-sm-9">
652
+ <div class="input-group mb-3">
653
+ <label class="input-group-text" for="render-stats"
654
+ >Stats</label
655
+ >
656
+ </div>
657
+ </div>
658
+ <div class="col-sm-3">
659
+ <div class="input-group mb-3">
660
+ <button
661
+ class="btn btn-outline-secondary"
662
+ data-bs-copy="render-stats"
663
+ type="button"
664
+ >
665
+ <i class="bi bi-copy"></i>
666
+ </button>
667
+ </div>
668
+ </div>
669
+ </div>
670
+ <textarea
671
+ class="form-control"
672
+ disabled
673
+ id="render-stats"
674
+ rows="10"
675
+ ></textarea>
676
+ </div>
677
+ </div>
678
+ <div class="col-sm-12 col-md-6">
679
+ <div class="mb-3">
680
+ <div class="row">
681
+ <div class="col-sm-9">
682
+ <div class="input-group mb-3">
683
+ <label class="input-group-text" for="errors"
684
+ >Errors</label
685
+ >
686
+ <a
687
+ class="btn btn-outline-secondary"
688
+ download="errors"
689
+ href="#"
690
+ >
691
+ <i class="bi bi-download"></i>
692
+ </a>
693
+ </div>
694
+ </div>
695
+ <div class="col-sm-3">
696
+ <div class="input-group mb-3">
697
+ <button
698
+ class="btn btn-outline-secondary"
699
+ data-bs-copy="errors"
700
+ type="button"
701
+ >
702
+ <i class="bi bi-copy"></i>
703
+ </button>
704
+ </div>
705
+ </div>
706
+ </div>
707
+ <textarea
708
+ class="form-control"
709
+ disabled
710
+ id="errors"
711
+ name="errors"
712
+ rows="10"
713
+ ></textarea>
714
+ </div>
715
+ </div>
716
+ <div class="col-sm-12">
717
+ <div class="mb-3">
718
+ <div class="row">
719
+ <div class="col">
720
+ <div class="input-group mb-3">
721
+ <label class="input-group-text" for="ast">AST</label>
722
+ <button
723
+ class="btn btn-outline-secondary"
724
+ data-bs-tree="expand"
725
+ title="Expand"
726
+ type="button"
727
+ >
728
+ <i class="bi bi-arrows-expand-vertical"></i>
729
+ </button>
730
+ <button
731
+ class="btn btn-outline-secondary"
732
+ data-bs-tree="collapse"
733
+ title="Collapse"
734
+ type="button"
735
+ >
736
+ <i class="bi bi-arrows-collapse-vertical"></i>
737
+ </button>
738
+ <a
739
+ class="btn btn-outline-secondary"
740
+ download="ast"
741
+ href="#"
742
+ >
743
+ <i class="bi bi-download"></i>
744
+ </a>
745
+ <button
746
+ class="btn btn-outline-secondary"
747
+ data-bs-copy="ast"
748
+ type="button"
749
+ >
750
+ <i class="bi bi-copy"></i>
751
+ </button>
752
+ </div>
753
+ </div>
754
+ </div>
755
+
756
+ <textarea
757
+ class="form-control d-none"
758
+ disabled
759
+ id="ast"
760
+ name="ast"
761
+ rows="10"
762
+ ></textarea>
763
+ <div class="nav flex-column css-tree" id="css-tree"></div>
764
+ </div>
765
+ </div>
766
+ </div>
767
+ <div class="row">
768
+ <div class="col">
769
+ <div class="mb-3">
770
+ <ul class="navbar-nav">
771
+ <li class="nav-item">
772
+ <a
773
+ class="nav-link"
774
+ href="https://github.com/tbela99/css-parser"
775
+ target="_blank"
776
+ >
777
+ <i class="bi bi-github"></i>
778
+ GitHub</a
779
+ >
780
+ </li>
781
+ </ul>
782
+ </div>
783
+ </div>
784
+ </div>
785
+ </div>
786
+ </div>
787
+ </div>
788
+ <script type="module">
789
+ import {
790
+ parse,
791
+ render,
792
+ EnumToken,
793
+ ColorType,
794
+ } from "https://esm.sh/@tbela99/css-parser@1.4.3/web";
795
+ import {buildTree} from "./tree.js";
796
+
797
+ const units = ["B", "KB", "MB", "GB", "TB", "PB"];
798
+
799
+ const css = document.querySelector("#css");
800
+ const result = document.querySelector("#result");
801
+ const mapping = document.querySelector("#mapping");
802
+ const ast = document.querySelector("#ast");
803
+ const errors = document.querySelector("#errors");
804
+ const renderStats = document.querySelector("#render-stats");
805
+ const tree = document.querySelector("#css-tree");
806
+
807
+ function toFileSize(size) {
808
+ if (size === 0) return 0;
809
+
810
+ const e = Math.floor(Math.log(size) / Math.log(1024));
811
+
812
+ size = size / Math.pow(1024, Math.floor(e));
813
+
814
+ return (
815
+ (Number.isInteger(size) ? size : size.toFixed(2)) +
816
+ " " +
817
+ (units?.[e] ?? s[e])
818
+ );
819
+ }
820
+
821
+ css.addEventListener("change", async (e) => {
822
+ e.stopPropagation();
823
+
824
+ const parseOptions = {};
825
+ const renderOptions = {};
826
+
827
+ if (css.value.trim() === "") {
828
+ result.value = "";
829
+ mapping.value = "";
830
+ ast.value = "";
831
+ errors.value = "";
832
+ renderStats.value = "";
833
+ tree.innerHTML = "";
834
+ } else {
835
+ let value;
836
+ let name;
837
+
838
+ for (const option of document.querySelectorAll(
839
+ ':scope :is(input[type=checkbox][name],input[type=radio][name]:checked,select[name^="parseoptions["],select[name^="renderoptions["])'
840
+ )) {
841
+ name = option.name;
842
+ value = option.tagName === "SELECT" ? option.value : option.checked;
843
+
844
+ if (option.name.startsWith("renderoptions[")) {
845
+ name = option.name.slice("renderoptions[".length, -1);
846
+
847
+ if (name === "convertColor") {
848
+ value = value === "NONE" ? false : ColorType[option.value];
849
+ }
850
+
851
+ renderOptions[name] =
852
+ name === "convertColor" ? value : +value > 0;
853
+ } else if (option.name.startsWith("parseoptions[")) {
854
+ name = option.name.slice("parseoptions[".length, -1);
855
+ parseOptions[name] =
856
+ name === "validation"
857
+ ? +option.value === 0
858
+ ? false
859
+ : +option.value
860
+ : +value > 0;
861
+ }
862
+ }
863
+
864
+ console.error({parseOptions, renderOptions});
865
+ console.debug("parsing");
866
+
867
+ const startTime = performance.now();
868
+
869
+ for (const [key, value] of Object.entries(parseOptions)) {
870
+
871
+ document.body.classList.toggle(`css-parse-options-${key.replace(/([A-Z])/g, (all, one) => `-${one.toLowerCase()}`)}`, value)
872
+ }
873
+
874
+ parse(css.value, parseOptions).then((parseResult) => {
875
+ console.debug("rendering");
876
+ const rendered = render(parseResult.ast, renderOptions);
877
+
878
+ const transformResult = {
879
+ parseOptions,
880
+ renderOptions,
881
+ ...parseResult,
882
+ ...rendered,
883
+ errors: parseResult.errors.concat(rendered.errors),
884
+ stats: {
885
+ bytesOut: rendered.code.length,
886
+ ...parseResult.stats,
887
+ render: rendered.stats.total,
888
+ total: (performance.now() - startTime).toFixed(2) + "ms",
889
+ },
890
+ };
891
+
892
+ console.error({transformResult});
893
+
894
+ result.value =
895
+ transformResult.code +
896
+ (transformResult.map
897
+ ? "\n" +
898
+ `/*# sourceMappingURL=data:application/json,${encodeURIComponent(
899
+ JSON.stringify(transformResult.map)
900
+ )} */`
901
+ : "");
902
+
903
+ mapping.value = transformResult.mapping ? JSON.stringify(transformResult.mapping, null, 1) : "";
904
+ ast.value = JSON.stringify(transformResult.ast, null, 1);
905
+
906
+ errors.value =
907
+ transformResult.errors.length === 0
908
+ ? ""
909
+ : JSON.stringify(transformResult.errors, null, 1);
910
+
911
+ Array.from(errors.labels ?? []).forEach(
912
+ (label) =>
913
+ (label.textContent =
914
+ "Errors" +
915
+ (transformResult.errors.length === 0
916
+ ? ""
917
+ : " (" + transformResult.errors.length + ")"))
918
+ );
919
+
920
+ renderStats.value = Object.entries(transformResult.stats)
921
+ .concat([
922
+ [
923
+ "Ratio",
924
+ (
925
+ 100 *
926
+ (1 -
927
+ transformResult.code.length /
928
+ transformResult.stats.bytesIn)
929
+ ).toFixed(2) + " %",
930
+ ],
931
+ ["Input", toFileSize(transformResult.stats.bytesIn)],
932
+ ["Output", toFileSize(transformResult.code.length)],
933
+ ])
934
+ .reduce(
935
+ (acc, [key, value]) =>
936
+ acc +
937
+ (acc.length > 0 ? "\n" : "") +
938
+ `${key}: ${
939
+ typeof value === "number" && !key.includes("Count")
940
+ ? toFileSize(value)
941
+ : typeof value === "object"
942
+ ? JSON.stringify(value)
943
+ : value
944
+ }`,
945
+ ""
946
+ );
947
+
948
+ buildTree(tree, transformResult.ast, {
949
+ rootName: EnumToken[transformResult.ast.typ],
950
+ transform: (name, value, object) =>
951
+ Array.isArray(object)
952
+ ? {
953
+ name: name + " [" + EnumToken[value.typ] + "]",
954
+ value,
955
+ }
956
+ : {name, value},
957
+ });
958
+ });
959
+ }
960
+
961
+ /*
962
+ code.value = `
963
+
964
+ import {parse, render} from 'https://esm.sh/@tbela99/css-parser/web';
965
+
966
+ const css = ${JSON.stringify(css.value)};
967
+ const parsed = await parse(css, ${JSON.stringify(parseOptions)});
968
+ const rendered = render(parsed.ast, ${JSON.stringify(renderOptions)});
969
+
970
+ console.debug({parsed, rendered});`;
971
+ */
972
+ });
973
+
974
+ function generateDownloadUrl(target, input, type) {
975
+ if (input.length === 0) {
976
+ return null;
977
+ }
978
+
979
+ return URL.createObjectURL(new Blob([input], {type}));
980
+ }
981
+
982
+ document.documentElement.addEventListener("click", async (event) => {
983
+ const target = event.target.closest("[data-bs-copy]");
984
+
985
+ if (target != null) {
986
+ target.classList.add("btn-outline-danger");
987
+ await navigator.clipboard.writeText(
988
+ document.getElementById(target.getAttribute("data-bs-copy")).value
989
+ );
990
+ }
991
+ });
992
+
993
+ document.querySelector("#zone").addEventListener("click", (event) => {
994
+ let target = event.target.closest("a[download]");
995
+
996
+ if (target != null) {
997
+ const url = generateDownloadUrl(
998
+ target,
999
+ document.getElementById(target.getAttribute('download')).value,
1000
+ target.download === "result" ? "text/css" : "application/json"
1001
+ );
1002
+
1003
+ if (url === null) {
1004
+ event.preventDefault();
1005
+ return;
1006
+ }
1007
+
1008
+ if (target.href.startsWith("blob:")) {
1009
+ URL.revokeObjectURL(target.href);
1010
+ }
1011
+
1012
+ target.classList.add("btn-outline-danger");
1013
+ target.href = url;
1014
+
1015
+ setTimeout(
1016
+ () => event.target.classList.remove("btn-outline-danger"),
1017
+ 1000
1018
+ );
1019
+ return;
1020
+ }
1021
+
1022
+ target = event.target.closest("[data-bs-tree]");
1023
+
1024
+ if (target != null) {
1025
+ const collapse = target.dataset.bsTree == "collapse";
1026
+ const stack = [tree.firstElementChild];
1027
+
1028
+ let item;
1029
+ let maxDepth = 100;
1030
+
1031
+ while ((item = stack.shift())) {
1032
+ if (maxDepth < 0) {
1033
+ break;
1034
+ }
1035
+
1036
+ for (const child of item.children) {
1037
+ if (collapse && child.classList.contains("tree-collapsed")) {
1038
+ continue;
1039
+ }
1040
+
1041
+ if (!collapse && child.dataset.parsed === "no") {
1042
+ const el = child.querySelector(":scope>.e");
1043
+
1044
+ if (el != null) {
1045
+ maxDepth--;
1046
+ el.click();
1047
+ }
1048
+ }
1049
+
1050
+ const ul = child.querySelector(":scope>ul");
1051
+
1052
+ if (ul != null) {
1053
+ stack.push(ul);
1054
+ }
1055
+
1056
+ child.classList.toggle("tree-collapsed", collapse);
1057
+ }
1058
+ }
1059
+ }
1060
+ });
1061
+
1062
+ document
1063
+ .querySelector("#optionsWrapper")
1064
+ .addEventListener("change", (event) => {
1065
+ event.stopPropagation();
1066
+
1067
+ if (
1068
+ event.target.matches(
1069
+ "input[type=checkbox][name],input[type=radio][name],select[name]"
1070
+ )
1071
+ ) {
1072
+ css.dispatchEvent(new Event("change"));
1073
+ }
1074
+ });
1075
+
1076
+ document
1077
+ .querySelector("select[name=preset]")
1078
+ .addEventListener("change", (event) => {
1079
+ if (event.target.value === "calc") {
1080
+ css.value = `:root {
1081
+ --color: green;
1082
+ }
1083
+ ._19_u :focus {
1084
+ color: hsl(from var(--color) calc(h * 2) s l);
1085
+ }
1086
+ :root {
1087
+ --preferred-width: 20px;
1088
+ }
1089
+ .foo-bar {
1090
+ width: calc(calc(var(--preferred-width) + 1px) / 3 + 5px);
1091
+ height: calc(100% / 4);
1092
+ transform: scaleX(1.5) scaleY(2);
1093
+
1094
+ .foo-bar {
1095
+ color: lch(from slateblue calc(l + 10%) c h);
1096
+ }
1097
+
1098
+ transform: scaleX(.5)scaleY(1)scaleZ(1.7)rotate3d(1,1,1,67deg);
1099
+ color: color-mix(in oklch, currentcolor 35%, #0000 )
1100
+
1101
+ }
1102
+ `;
1103
+ } else if (event.target.value === "validation") {
1104
+ parseoptionsValidation.checked = true;
1105
+ css.value = `
1106
+ #404 {
1107
+ --animate-duration: 1s;
1108
+ }
1109
+
1110
+ .s, #404 {
1111
+ --animate-duration: 1s;
1112
+ }
1113
+
1114
+ .s [type="text" {
1115
+ --animate-duration: 1s;
1116
+ }
1117
+
1118
+ .s [type="text"]] {
1119
+ --animate-duration: 1s;
1120
+ }
1121
+
1122
+ .s [type="text"] {
1123
+ --animate-duration: 1s;
1124
+ }
1125
+
1126
+ .s [type="text" i] {
1127
+ --animate-duration: 1s;
1128
+ }
1129
+
1130
+ .s [type="text" s] {
1131
+ --animate-duration: 1s;
1132
+ }
1133
+
1134
+ .s [type="text" b] {
1135
+ --animate-duration: 1s;
1136
+ }
1137
+
1138
+ .s [type="text" b], {
1139
+ --animate-duration: 1s;
1140
+ }
1141
+
1142
+ .s [type="text" b]+ {
1143
+ --animate-duration: 1s;
1144
+ }
1145
+
1146
+ .s [type="text" b]+ b {
1147
+ --animate-duration: 1s;
1148
+ }
1149
+
1150
+ .s [type="text" i]+ b {
1151
+ --animate-duration: 1s;
1152
+ }
1153
+
1154
+
1155
+ .s [type="text"())] {
1156
+ --animate-duration: 1s;
1157
+ }
1158
+ .s() {
1159
+ --animate-duration: 1s;
1160
+ }
1161
+ .s:focus {
1162
+ --animate-duration: 1s;
1163
+ transform: translate(0,-100px) scaleX(0.5) scaleY( 1) scaleZ(1.7) rotate3d(1, 1, 1, 67deg);
1164
+ }`;
1165
+ } else if (event.target.value === "bootstrap") {
1166
+ parseoptionsresolveImport.checked = true;
1167
+ css.value = `@import url('https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.css');`;
1168
+ } else if (event.target.value === "tailwind") {
1169
+ parseoptionsresolveImport.checked = true;
1170
+ css.value = `@import url('https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.4/tailwind.css');`;
1171
+ } else if (event.target.value === "prefix") {
1172
+ parseoptionsresolveImport.removePrefix = true;
1173
+ css.value = `
1174
+ ::-webkit-input-placeholder {
1175
+ color: gray;
1176
+ }
1177
+
1178
+ ::-moz-placeholder {
1179
+ color: gray;
1180
+ }
1181
+
1182
+ :-ms-input-placeholder {
1183
+ color: gray;
1184
+ }
1185
+
1186
+ ::-ms-input-placeholder {
1187
+ color: gray;
1188
+ }
1189
+
1190
+ ::placeholder {
1191
+ color: gray;
1192
+ }
1193
+
1194
+ @supports selector(:-ms-input-placeholder) {
1195
+
1196
+
1197
+ :-ms-input-placeholder {
1198
+ color: gray;
1199
+ }
1200
+ }
1201
+
1202
+ .image {
1203
+ background-image: url(image@1x.png);
1204
+ }
1205
+ @media (-webkit-min-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx) {
1206
+ .image {
1207
+ background-image: url(image@2x.png);
1208
+ }
1209
+
1210
+ }
1211
+
1212
+
1213
+ @-webkit-keyframes bar {
1214
+
1215
+ from, 0% {
1216
+
1217
+ height: 10px;
1218
+ }
1219
+ }
1220
+
1221
+ @keyframes bar {
1222
+
1223
+ from, 0% {
1224
+
1225
+ height: 10px;
1226
+ }
1227
+ }
1228
+ .example {
1229
+
1230
+ -moz-animation: bar 1s infinite;
1231
+ display: -ms-grid;
1232
+ display: grid;
1233
+ -webkit-transition: all .5s;
1234
+ -o-transition: all .5s;
1235
+ transition: all .5s;
1236
+ -webkit-user-select: none;
1237
+ -moz-user-select: none;
1238
+ -ms-user-select: none;
1239
+ user-select: none;
1240
+ background: -o-linear-gradient(top, white, black);
1241
+ background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
1242
+ background: linear-gradient(to bottom, white, black);
1243
+ }
1244
+
1245
+ .site{
1246
+ display:-ms-grid;
1247
+ display:grid; -ms-grid-columns:2fr 1fr;
1248
+ grid-template-columns:2fr 1fr;
1249
+ grid-template-areas:"header header"
1250
+ "title sidebar"
1251
+ "main sidebar"
1252
+ "footer footer";
1253
+ }
1254
+ .site > *{padding:30px; color:#fff; font-size:20px;}
1255
+ .mastheader{
1256
+ -ms-grid-row:1;
1257
+ -ms-grid-column:1;
1258
+ -ms-grid-column-span:2;
1259
+ grid-area:header;
1260
+ }
1261
+ .page-title{
1262
+ -ms-grid-row:2;
1263
+ -ms-grid-column:1;
1264
+ grid-area:title;
1265
+ }
1266
+ .main-content{
1267
+ -ms-grid-row:3;
1268
+ -ms-grid-column:1;
1269
+ grid-area:main;
1270
+ }
1271
+ .sidebar{
1272
+ -ms-grid-row:2;
1273
+ -ms-grid-row-span:2;
1274
+ -ms-grid-column:2;
1275
+ grid-area:sidebar;
1276
+ }
1277
+ .footer{
1278
+ -ms-grid-row:4;
1279
+ -ms-grid-column:1;
1280
+ -ms-grid-column-span:2;
1281
+ grid-area:footer;
1282
+ }
1283
+ a {
1284
+ -webkit-transition: -webkit-transform 1s;
1285
+ -ms-transition: -ms-transform 1s;
1286
+ transition: transform 1s
1287
+ }
1288
+ `;
1289
+ } else {
1290
+ css.value = "";
1291
+ }
1292
+
1293
+ event.target.classList.add("btn-outline-danger");
1294
+ css.dispatchEvent(new Event("change"));
1295
+
1296
+ setTimeout(
1297
+ () => event.target.classList.remove("btn-outline-danger"),
1298
+ 1000
1299
+ );
1300
+ });
1301
+
1302
+ css.dispatchEvent(new Event("change"));
1303
+ </script>
1304
+ <script>
1305
+ navigator.serviceWorker
1306
+ .register("./sw.js", {scope: "./", type: "module"})
1307
+ .then((registration) => {
1308
+ if (registration.installing) {
1309
+ location.reload();
1310
+ }
1311
+ });
1312
+ </script>
1313
+
1314
+ <script>
1315
+ document.body.addEventListener('click', (event) => {
1316
+
1317
+ // data-bs-target="#navbarSupportedContent" data-bs-toggle="collapse"
1318
+ const target = event.target.closest('[data-bs-toggle="collapse"][data-bs-target]');
1319
+
1320
+ if (target != null) {
1321
+
1322
+ document.querySelector(target.dataset.bsTarget).classList.toggle('show');
1323
+ target.classList.toggle('collapsed');
1324
+ }
1325
+ })
1326
+ </script>
1327
+ </body>
1328
+ </html>