iobroker.mywebui 1.37.21 → 1.37.22

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 (29) hide show
  1. package/io-package.json +1 -1
  2. package/package.json +1 -1
  3. package/www/node_modules/@node-projects/css-parser/LICENSE +11 -0
  4. package/www/node_modules/@node-projects/css-parser/README.md +161 -0
  5. package/www/node_modules/@node-projects/css-parser/dist/CssParseError.d.ts +8 -0
  6. package/www/node_modules/@node-projects/css-parser/dist/CssParseError.js +15 -0
  7. package/www/node_modules/@node-projects/css-parser/dist/CssPosition.d.ts +25 -0
  8. package/www/node_modules/@node-projects/css-parser/dist/CssPosition.js +13 -0
  9. package/www/node_modules/@node-projects/css-parser/dist/index-min.js +56 -0
  10. package/www/node_modules/@node-projects/css-parser/dist/index-min.js.map +7 -0
  11. package/www/node_modules/@node-projects/css-parser/dist/index.d.ts +12 -0
  12. package/www/node_modules/@node-projects/css-parser/dist/index.js +8 -0
  13. package/www/node_modules/@node-projects/css-parser/dist/parse/index.d.ts +8 -0
  14. package/www/node_modules/@node-projects/css-parser/dist/parse/index.js +1293 -0
  15. package/www/node_modules/@node-projects/css-parser/dist/parse/lexer.d.ts +118 -0
  16. package/www/node_modules/@node-projects/css-parser/dist/parse/lexer.js +248 -0
  17. package/www/node_modules/@node-projects/css-parser/dist/stringify/compiler.d.ts +172 -0
  18. package/www/node_modules/@node-projects/css-parser/dist/stringify/compiler.js +732 -0
  19. package/www/node_modules/@node-projects/css-parser/dist/stringify/index.d.ts +5 -0
  20. package/www/node_modules/@node-projects/css-parser/dist/stringify/index.js +5 -0
  21. package/www/node_modules/@node-projects/css-parser/dist/type.d.ts +205 -0
  22. package/www/node_modules/@node-projects/css-parser/dist/type.js +31 -0
  23. package/www/node_modules/@node-projects/css-parser/dist/utils/stringSearch.d.ts +53 -0
  24. package/www/node_modules/@node-projects/css-parser/dist/utils/stringSearch.js +166 -0
  25. package/www/node_modules/@node-projects/css-parser/docs/API.md +362 -0
  26. package/www/node_modules/@node-projects/css-parser/docs/AST.md +417 -0
  27. package/www/node_modules/@node-projects/css-parser/docs/CHANGELOG.md +205 -0
  28. package/www/node_modules/@node-projects/css-parser/docs/EXAMPLES.md +497 -0
  29. package/www/node_modules/@node-projects/css-parser/package.json +66 -0
@@ -0,0 +1,732 @@
1
+ import { CssTypes, } from '../type.js';
2
+ class Compiler {
3
+ level = 0;
4
+ indentation = ' ';
5
+ compress = false;
6
+ identity = false;
7
+ removeEmptyRules = false;
8
+ constructor(options) {
9
+ if (typeof options?.indent === 'string') {
10
+ this.indentation = options?.indent;
11
+ }
12
+ if (options?.compress) {
13
+ this.compress = true;
14
+ }
15
+ if (options?.identity) {
16
+ this.identity = true;
17
+ }
18
+ if (options?.removeEmptyRules) {
19
+ this.removeEmptyRules = true;
20
+ }
21
+ }
22
+ // We disable no-unused-vars for _position. We keep position for potential reintroduction of source-map
23
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
24
+ emit(str, _position) {
25
+ return str;
26
+ }
27
+ /**
28
+ * Increase, decrease or return current indentation.
29
+ */
30
+ indent(level) {
31
+ this.level = this.level || 1;
32
+ if (level) {
33
+ this.level += level;
34
+ return '';
35
+ }
36
+ return this.level > 1 ? this.indentation.repeat(this.level - 1) : '';
37
+ }
38
+ visit(node) {
39
+ switch (node.type) {
40
+ case CssTypes.stylesheet:
41
+ return this.stylesheet(node);
42
+ case CssTypes.rule:
43
+ return this.rule(node);
44
+ case CssTypes.declaration:
45
+ return this.declaration(node);
46
+ case CssTypes.comment:
47
+ return this.comment(node);
48
+ case CssTypes.whitespace:
49
+ return this.whitespace(node);
50
+ case CssTypes.container:
51
+ return this.container(node);
52
+ case CssTypes.charset:
53
+ return this.charset(node);
54
+ case CssTypes.counterStyle:
55
+ return this.counterStyle(node);
56
+ case CssTypes.document:
57
+ return this.document(node);
58
+ case CssTypes.customMedia:
59
+ return this.customMedia(node);
60
+ case CssTypes.fontFace:
61
+ return this.fontFace(node);
62
+ case CssTypes.fontFeatureValues:
63
+ return this.fontFeatureValues(node);
64
+ case CssTypes.host:
65
+ return this.host(node);
66
+ case CssTypes.import:
67
+ return this.import(node);
68
+ case CssTypes.keyframes:
69
+ return this.keyframes(node);
70
+ case CssTypes.keyframe:
71
+ return this.keyframe(node);
72
+ case CssTypes.layer:
73
+ return this.layer(node);
74
+ case CssTypes.media:
75
+ return this.media(node);
76
+ case CssTypes.namespace:
77
+ return this.namespace(node);
78
+ case CssTypes.page:
79
+ return this.page(node);
80
+ case CssTypes.pageMarginBox:
81
+ return this.pageMarginBox(node);
82
+ case CssTypes.positionTry:
83
+ return this.positionTry(node);
84
+ case CssTypes.property:
85
+ return this.property(node);
86
+ case CssTypes.scope:
87
+ return this.scope(node);
88
+ case CssTypes.startingStyle:
89
+ return this.startingStyle(node);
90
+ case CssTypes.supports:
91
+ return this.supports(node);
92
+ case CssTypes.viewTransition:
93
+ return this.viewTransition(node);
94
+ case CssTypes.atRule:
95
+ return this.genericAtRule(node);
96
+ }
97
+ }
98
+ mapVisit(nodes, delim) {
99
+ let buf = '';
100
+ delim = delim || '';
101
+ for (let i = 0, length = nodes.length; i < length; i++) {
102
+ const str = this.visit(nodes[i]);
103
+ if (str) {
104
+ if (delim && buf) {
105
+ buf += this.emit(delim);
106
+ }
107
+ buf += str;
108
+ }
109
+ }
110
+ return buf;
111
+ }
112
+ /**
113
+ * Emit a block at-rule that contains nested rules (e.g. @media, @supports, @container).
114
+ */
115
+ rulesBlock(header, rules, position, rawPrelude) {
116
+ if (this.identity && rawPrelude) {
117
+ this.indent(1);
118
+ const result = this.emit(rawPrelude, position) +
119
+ this.emit('{') +
120
+ this.identityVisitBlock(this.filterEmptyRules(rules), 'rules') +
121
+ this.emit('}');
122
+ this.indent(-1);
123
+ return result;
124
+ }
125
+ const filteredRules = this.filterEmptyRules(this.stripWhitespace(rules));
126
+ if (this.compress) {
127
+ return (this.emit(header, position) +
128
+ this.emit('{') +
129
+ this.mapVisit(filteredRules) +
130
+ this.emit('}'));
131
+ }
132
+ return (this.emit(`${this.indent()}${header}`, position) +
133
+ this.emit(` {\n${this.indent(1)}`) +
134
+ this.mapVisit(filteredRules, '\n\n') +
135
+ this.emit(`\n${this.indent(-1)}${this.indent()}}`));
136
+ }
137
+ /**
138
+ * Emit a block at-rule that contains declarations (e.g. @font-face, @property).
139
+ */
140
+ declsBlock(header, declarations, position, rawPrelude) {
141
+ if (this.identity && rawPrelude) {
142
+ this.indent(1);
143
+ const result = this.emit(rawPrelude, position) +
144
+ this.emit('{') +
145
+ this.identityVisitBlock(declarations, 'decls') +
146
+ this.emit('}');
147
+ this.indent(-1);
148
+ return result;
149
+ }
150
+ const stripped = this.stripWhitespace(declarations);
151
+ if (this.compress) {
152
+ return (this.emit(header, position) +
153
+ this.emit('{') +
154
+ this.mapVisit(stripped) +
155
+ this.emit('}'));
156
+ }
157
+ return (this.emit(`${header} `, position) +
158
+ this.emit('{\n') +
159
+ this.emit(this.indent(1)) +
160
+ this.mapVisit(stripped, '\n') +
161
+ this.emit(this.indent(-1)) +
162
+ this.emit('\n}'));
163
+ }
164
+ compile(node) {
165
+ if (this.identity) {
166
+ return this.identityCompile(node);
167
+ }
168
+ if (this.compress) {
169
+ return this.filterEmptyRules(this.stripWhitespace(node.stylesheet.rules))
170
+ .map(this.visit, this)
171
+ .join('');
172
+ }
173
+ return this.stylesheet(node);
174
+ }
175
+ /**
176
+ * Identity mode: walk the AST including whitespace nodes.
177
+ * Falls back to beautified output when whitespace nodes are not available.
178
+ */
179
+ identityCompile(node) {
180
+ const rules = node.stylesheet.rules;
181
+ const hasWhitespace = rules.some((r) => r.type === CssTypes.whitespace);
182
+ if (!hasWhitespace) {
183
+ // Fallback to beautified when preserveFormatting was not used
184
+ return this.stylesheet(node);
185
+ }
186
+ return this.identityVisitBlock(rules, 'stylesheet');
187
+ }
188
+ /**
189
+ * Visit stylesheet node.
190
+ */
191
+ stylesheet(node) {
192
+ return this.mapVisit(this.filterEmptyRules(this.stripWhitespace(node.stylesheet.rules)), '\n\n');
193
+ }
194
+ /**
195
+ * Strip whitespace nodes from an array (used in beautified/compressed modes).
196
+ */
197
+ stripWhitespace(nodes) {
198
+ return nodes.filter((n) => n.type !== CssTypes.whitespace);
199
+ }
200
+ /**
201
+ * Filter out empty rules when removeEmptyRules is enabled.
202
+ */
203
+ filterEmptyRules(rules) {
204
+ if (!this.removeEmptyRules) {
205
+ return rules;
206
+ }
207
+ return rules.filter((rule) => {
208
+ if (rule.type === CssTypes.rule) {
209
+ const decls = rule.declarations.filter((d) => d.type !== CssTypes.whitespace);
210
+ return decls.length > 0;
211
+ }
212
+ return true;
213
+ });
214
+ }
215
+ /**
216
+ * Check whether a node was newly created (not parsed from source).
217
+ * New nodes lack the raw formatting properties set by the parser.
218
+ */
219
+ isNewNode(node) {
220
+ switch (node.type) {
221
+ case CssTypes.whitespace:
222
+ return false;
223
+ case CssTypes.comment:
224
+ return !node.position;
225
+ case CssTypes.declaration:
226
+ return node.rawBetween == null;
227
+ case CssTypes.rule:
228
+ return node.rawPrelude == null;
229
+ default:
230
+ if ('rawPrelude' in node)
231
+ return !node.rawPrelude;
232
+ if ('rawSource' in node)
233
+ return !node.rawSource;
234
+ return !node.position;
235
+ }
236
+ }
237
+ /**
238
+ * Visit block children in identity mode, formatting newly added nodes
239
+ * with beautified output while preserving original formatting for
240
+ * existing nodes.
241
+ *
242
+ * @param nodes - The child nodes to visit
243
+ * @param context - 'decls' for declaration blocks, 'rules' for nested
244
+ * rule blocks (e.g. @media), 'stylesheet' for top-level
245
+ */
246
+ identityVisitBlock(nodes, context) {
247
+ const filtered = this.filterEmptyRules(nodes);
248
+ // Fast path: no new nodes – visit normally
249
+ if (!filtered.some((n) => this.isNewNode(n))) {
250
+ return this.mapVisit(filtered);
251
+ }
252
+ let buf = '';
253
+ const needsDoubleNewline = context === 'rules' || context === 'stylesheet';
254
+ for (let i = 0; i < filtered.length; i++) {
255
+ const node = filtered[i];
256
+ if (!this.isNewNode(node)) {
257
+ buf += this.visit(node);
258
+ continue;
259
+ }
260
+ // ── New node: add proper separator before it ──
261
+ // Check whether the buffer already ends with \n (possibly followed
262
+ // by spaces that were originally the closing-brace indent). If so,
263
+ // trim those trailing spaces – the beautified fallback of the new
264
+ // node will supply the correct indentation.
265
+ const lastNl = buf.lastIndexOf('\n');
266
+ const hasTrailingNewline = lastNl >= 0 && buf.slice(lastNl + 1).trim() === '';
267
+ if (hasTrailingNewline) {
268
+ buf = buf.slice(0, lastNl + 1);
269
+ }
270
+ else if (buf.length === 0 && context !== 'stylesheet') {
271
+ // First child in a block – add newline after opening brace
272
+ buf += '\n';
273
+ }
274
+ else if (buf.length > 0) {
275
+ buf += '\n';
276
+ }
277
+ if (needsDoubleNewline && buf.length > 1 && !buf.endsWith('\n\n')) {
278
+ buf += '\n';
279
+ }
280
+ // Visit the node (uses beautified fallback since raw props are absent)
281
+ const str = this.visit(node);
282
+ if (str)
283
+ buf += str;
284
+ }
285
+ // Add trailing newline + closing-brace indent when the last meaningful
286
+ // node is new (blocks only, not the top-level stylesheet)
287
+ if (context !== 'stylesheet') {
288
+ const lastMeaningful = [...filtered]
289
+ .reverse()
290
+ .find((n) => n.type !== CssTypes.whitespace);
291
+ if (lastMeaningful &&
292
+ this.isNewNode(lastMeaningful) &&
293
+ buf.length > 0 &&
294
+ !buf.endsWith('\n')) {
295
+ buf += '\n';
296
+ // Indent for the closing brace (one level less than current)
297
+ this.indent(-1);
298
+ buf += this.indent();
299
+ this.indent(1);
300
+ }
301
+ }
302
+ return buf;
303
+ }
304
+ /**
305
+ * Visit whitespace node.
306
+ */
307
+ whitespace(node) {
308
+ if (this.identity) {
309
+ return this.emit(node.value);
310
+ }
311
+ // In beautified/compressed mode, whitespace nodes are stripped before visiting
312
+ return '';
313
+ }
314
+ /**
315
+ * Visit comment node.
316
+ */
317
+ comment(node) {
318
+ if (this.compress) {
319
+ return this.emit('', node.position);
320
+ }
321
+ const indent = this.identity && node.position ? '' : this.indent();
322
+ return this.emit(`${indent}/*${node.comment}*/`, node.position);
323
+ }
324
+ /**
325
+ * Visit container node.
326
+ */
327
+ container(node) {
328
+ return this.rulesBlock(`@container ${node.container}`, node.rules, node.position, node.rawPrelude);
329
+ }
330
+ /**
331
+ * Visit container node.
332
+ */
333
+ layer(node) {
334
+ if (this.identity && node.rawPrelude && node.rules) {
335
+ this.indent(1);
336
+ const result = this.emit(node.rawPrelude, node.position) +
337
+ this.emit('{') +
338
+ this.identityVisitBlock(this.filterEmptyRules(node.rules), 'rules') +
339
+ this.emit('}');
340
+ this.indent(-1);
341
+ return result;
342
+ }
343
+ if (this.identity && !node.rules && node.rawSource) {
344
+ return this.emit(node.rawSource, node.position);
345
+ }
346
+ const rules = node.rules
347
+ ? this.stripWhitespace(node.rules)
348
+ : undefined;
349
+ if (this.compress) {
350
+ return (this.emit(`@layer ${node.layer}`, node.position) +
351
+ (rules ? this.emit('{') + this.mapVisit(rules) + this.emit('}') : ';'));
352
+ }
353
+ return (this.emit(`${this.indent()}@layer ${node.layer}`, node.position) +
354
+ (rules
355
+ ? this.emit(` {\n${this.indent(1)}`) +
356
+ this.mapVisit(rules, '\n\n') +
357
+ this.emit(`\n${this.indent(-1)}${this.indent()}}`)
358
+ : ';'));
359
+ }
360
+ /**
361
+ * Visit import node.
362
+ */
363
+ import(node) {
364
+ if (this.identity && node.rawSource) {
365
+ return this.emit(node.rawSource, node.position);
366
+ }
367
+ return this.emit(`@import ${node.import};`, node.position);
368
+ }
369
+ /**
370
+ * Visit media node.
371
+ */
372
+ media(node) {
373
+ return this.rulesBlock(`@media ${node.media}`, node.rules, node.position, node.rawPrelude);
374
+ }
375
+ /**
376
+ * Visit document node.
377
+ */
378
+ document(node) {
379
+ const doc = `@${node.vendor || ''}document ${node.document}`;
380
+ if (this.identity && node.rawPrelude) {
381
+ this.indent(1);
382
+ const result = this.emit(node.rawPrelude, node.position) +
383
+ this.emit('{') +
384
+ this.identityVisitBlock(this.filterEmptyRules(node.rules), 'rules') +
385
+ this.emit('}');
386
+ this.indent(-1);
387
+ return result;
388
+ }
389
+ const rules = this.stripWhitespace(node.rules);
390
+ if (this.compress) {
391
+ return (this.emit(doc, node.position) +
392
+ this.emit('{') +
393
+ this.mapVisit(rules) +
394
+ this.emit('}'));
395
+ }
396
+ return (this.emit(doc, node.position) +
397
+ this.emit(` {\n${this.indent(1)}`) +
398
+ this.mapVisit(rules, '\n\n') +
399
+ this.emit(`${this.indent(-1)}\n}`));
400
+ }
401
+ /**
402
+ * Visit charset node.
403
+ */
404
+ charset(node) {
405
+ if (this.identity && node.rawSource) {
406
+ return this.emit(node.rawSource, node.position);
407
+ }
408
+ return this.emit(`@charset ${node.charset};`, node.position);
409
+ }
410
+ /**
411
+ * Visit namespace node.
412
+ */
413
+ namespace(node) {
414
+ if (this.identity && node.rawSource) {
415
+ return this.emit(node.rawSource, node.position);
416
+ }
417
+ return this.emit(`@namespace ${node.namespace};`, node.position);
418
+ }
419
+ /**
420
+ * Visit starting-style node.
421
+ */
422
+ startingStyle(node) {
423
+ return this.rulesBlock('@starting-style', node.rules, node.position, node.rawPrelude);
424
+ }
425
+ /**
426
+ * Visit supports node.
427
+ */
428
+ supports(node) {
429
+ return this.rulesBlock(`@supports ${node.supports}`, node.rules, node.position, node.rawPrelude);
430
+ }
431
+ /**
432
+ * Visit keyframes node.
433
+ */
434
+ keyframes(node) {
435
+ if (this.identity && node.rawPrelude) {
436
+ this.indent(1);
437
+ const result = this.emit(node.rawPrelude, node.position) +
438
+ this.emit('{') +
439
+ this.identityVisitBlock(node.keyframes, 'rules') +
440
+ this.emit('}');
441
+ this.indent(-1);
442
+ return result;
443
+ }
444
+ const frames = this.stripWhitespace(node.keyframes);
445
+ if (this.compress) {
446
+ return (this.emit(`@${node.vendor || ''}keyframes ${node.name}`, node.position) +
447
+ this.emit('{') +
448
+ this.mapVisit(frames) +
449
+ this.emit('}'));
450
+ }
451
+ return (this.emit(`@${node.vendor || ''}keyframes ${node.name}`, node.position) +
452
+ this.emit(` {\n${this.indent(1)}`) +
453
+ this.mapVisit(frames, '\n') +
454
+ this.emit(`${this.indent(-1)}}`));
455
+ }
456
+ /**
457
+ * Visit keyframe node.
458
+ */
459
+ keyframe(node) {
460
+ const decls = node.declarations;
461
+ if (this.identity && node.rawPrelude) {
462
+ this.indent(1);
463
+ const result = this.emit(node.rawPrelude, node.position) +
464
+ this.emit('{') +
465
+ this.identityVisitBlock(decls, 'decls') +
466
+ this.emit('}');
467
+ this.indent(-1);
468
+ return result;
469
+ }
470
+ const stripped = this.stripWhitespace(decls);
471
+ if (this.compress) {
472
+ return (this.emit(node.values.join(','), node.position) +
473
+ this.emit('{') +
474
+ this.mapVisit(stripped) +
475
+ this.emit('}'));
476
+ }
477
+ return (this.emit(this.indent()) +
478
+ this.emit(node.values.join(', '), node.position) +
479
+ this.emit(` {\n${this.indent(1)}`) +
480
+ this.mapVisit(stripped, '\n') +
481
+ this.emit(`${this.indent(-1)}\n${this.indent()}}\n`));
482
+ }
483
+ /**
484
+ * Visit page node.
485
+ */
486
+ page(node) {
487
+ if (this.identity && node.rawPrelude) {
488
+ this.indent(1);
489
+ const result = this.emit(node.rawPrelude, node.position) +
490
+ this.emit('{') +
491
+ this.identityVisitBlock(node.declarations, 'decls') +
492
+ this.emit('}');
493
+ this.indent(-1);
494
+ return result;
495
+ }
496
+ const decls = this.stripWhitespace(node.declarations);
497
+ if (this.compress) {
498
+ const sel = node.selectors.length ? node.selectors.join(', ') : '';
499
+ return (this.emit(`@page ${sel}`, node.position) +
500
+ this.emit('{') +
501
+ this.mapVisit(decls) +
502
+ this.emit('}'));
503
+ }
504
+ const sel = node.selectors.length ? `${node.selectors.join(', ')} ` : '';
505
+ return (this.emit(`@page ${sel}`, node.position) +
506
+ this.emit('{\n') +
507
+ this.emit(this.indent(1)) +
508
+ this.mapVisit(decls, '\n') +
509
+ this.emit(this.indent(-1)) +
510
+ this.emit('\n}'));
511
+ }
512
+ /**
513
+ * Visit @page margin box node (@top-left, @bottom-right, etc.).
514
+ */
515
+ pageMarginBox(node) {
516
+ if (this.identity && node.rawPrelude) {
517
+ this.indent(1);
518
+ const result = this.emit(node.rawPrelude, node.position) +
519
+ this.emit('{') +
520
+ this.identityVisitBlock(node.declarations, 'decls') +
521
+ this.emit('}');
522
+ this.indent(-1);
523
+ return result;
524
+ }
525
+ const decls = this.stripWhitespace(node.declarations);
526
+ if (this.compress) {
527
+ return (this.emit(`@${node.name}`, node.position) +
528
+ this.emit('{') +
529
+ this.mapVisit(decls) +
530
+ this.emit('}'));
531
+ }
532
+ return (this.emit(`${this.indent()}@${node.name} `, node.position) +
533
+ this.emit('{\n') +
534
+ this.emit(this.indent(1)) +
535
+ this.mapVisit(decls, '\n') +
536
+ this.emit(this.indent(-1)) +
537
+ this.emit(`\n${this.indent()}}`));
538
+ }
539
+ /**
540
+ * Visit font-face node.
541
+ */
542
+ fontFace(node) {
543
+ return this.declsBlock('@font-face', node.declarations, node.position, node.rawPrelude);
544
+ }
545
+ /**
546
+ * Visit host node.
547
+ */
548
+ host(node) {
549
+ if (this.identity && node.rawPrelude) {
550
+ this.indent(1);
551
+ const result = this.emit(node.rawPrelude, node.position) +
552
+ this.emit('{') +
553
+ this.identityVisitBlock(this.filterEmptyRules(node.rules), 'rules') +
554
+ this.emit('}');
555
+ this.indent(-1);
556
+ return result;
557
+ }
558
+ const rules = this.stripWhitespace(node.rules);
559
+ if (this.compress) {
560
+ return (this.emit('@host', node.position) +
561
+ this.emit('{') +
562
+ this.mapVisit(rules) +
563
+ this.emit('}'));
564
+ }
565
+ return (this.emit('@host', node.position) +
566
+ this.emit(` {\n${this.indent(1)}`) +
567
+ this.mapVisit(rules, '\n\n') +
568
+ this.emit(`${this.indent(-1)}\n}`));
569
+ }
570
+ /**
571
+ * Visit custom-media node.
572
+ */
573
+ customMedia(node) {
574
+ if (this.identity && node.rawSource) {
575
+ return this.emit(node.rawSource, node.position);
576
+ }
577
+ return this.emit(`@custom-media ${node.name} ${node.media};`, node.position);
578
+ }
579
+ /**
580
+ * Visit @property node.
581
+ */
582
+ property(node) {
583
+ return this.declsBlock(`@property ${node.name}`, node.declarations, node.position, node.rawPrelude);
584
+ }
585
+ /**
586
+ * Visit @counter-style node.
587
+ */
588
+ counterStyle(node) {
589
+ return this.declsBlock(`@counter-style ${node.name}`, node.declarations, node.position, node.rawPrelude);
590
+ }
591
+ /**
592
+ * Visit @font-feature-values node.
593
+ */
594
+ fontFeatureValues(node) {
595
+ return this.rulesBlock(`@font-feature-values ${node.fontFamily}`, node.rules, node.position, node.rawPrelude);
596
+ }
597
+ /**
598
+ * Visit @scope node.
599
+ */
600
+ scope(node) {
601
+ if (this.identity && node.rawPrelude) {
602
+ this.indent(1);
603
+ const result = this.emit(node.rawPrelude, node.position) +
604
+ this.emit('{') +
605
+ this.identityVisitBlock(this.filterEmptyRules(node.rules), 'rules') +
606
+ this.emit('}');
607
+ this.indent(-1);
608
+ return result;
609
+ }
610
+ const prelude = node.scope ? ` ${node.scope}` : '';
611
+ return this.rulesBlock(`@scope${prelude}`, this.stripWhitespace(node.rules), node.position);
612
+ }
613
+ /**
614
+ * Visit @view-transition node.
615
+ */
616
+ viewTransition(node) {
617
+ return this.declsBlock('@view-transition', node.declarations, node.position, node.rawPrelude);
618
+ }
619
+ /**
620
+ * Visit @position-try node.
621
+ */
622
+ positionTry(node) {
623
+ return this.declsBlock(`@position-try ${node.name}`, node.declarations, node.position, node.rawPrelude);
624
+ }
625
+ /**
626
+ * Visit generic at-rule node (fallback for any unrecognized at-rule).
627
+ */
628
+ genericAtRule(node) {
629
+ if (this.identity && node.rawPrelude && node.rules) {
630
+ this.indent(1);
631
+ const result = this.emit(node.rawPrelude, node.position) +
632
+ this.emit('{') +
633
+ this.identityVisitBlock(this.filterEmptyRules(node.rules), 'rules') +
634
+ this.emit('}');
635
+ this.indent(-1);
636
+ return result;
637
+ }
638
+ const prelude = node.prelude ? ` ${node.prelude}` : '';
639
+ const rules = node.rules
640
+ ? this.stripWhitespace(node.rules)
641
+ : undefined;
642
+ if (this.compress) {
643
+ return (this.emit(`@${node.name}${prelude}`, node.position) +
644
+ (rules ? this.emit('{') + this.mapVisit(rules) + this.emit('}') : ';'));
645
+ }
646
+ if (!rules) {
647
+ return this.emit(`${this.indent()}@${node.name}${prelude};`, node.position);
648
+ }
649
+ const hasNestedRules = rules.some((r) => r.type !== CssTypes.declaration && r.type !== CssTypes.comment);
650
+ const delim = hasNestedRules ? '\n\n' : '\n';
651
+ return (this.emit(`${this.indent()}@${node.name}${prelude}`, node.position) +
652
+ this.emit(hasNestedRules ? ` {\n${this.indent(1)}` : ' {\n') +
653
+ this.emit(hasNestedRules ? '' : this.indent(1)) +
654
+ this.mapVisit(rules, delim) +
655
+ this.emit(hasNestedRules
656
+ ? `\n${this.indent(-1)}${this.indent()}}`
657
+ : `${this.indent(-1)}\n${this.indent()}}`));
658
+ }
659
+ /**
660
+ * Visit rule node.
661
+ */
662
+ rule(node) {
663
+ const decls = node.declarations;
664
+ if (this.identity && node.rawPrelude) {
665
+ this.indent(1);
666
+ const result = this.emit(node.rawPrelude, node.position) +
667
+ this.emit('{') +
668
+ this.identityVisitBlock(decls, 'decls') +
669
+ this.emit('}');
670
+ this.indent(-1);
671
+ return result;
672
+ }
673
+ const stripped = this.stripWhitespace(decls);
674
+ if (this.compress) {
675
+ if (this.removeEmptyRules && !stripped.length) {
676
+ return '';
677
+ }
678
+ return (this.emit(node.selectors.join(','), node.position) +
679
+ this.emit('{') +
680
+ this.mapVisit(stripped) +
681
+ this.emit('}'));
682
+ }
683
+ const indent = this.indent();
684
+ if (!stripped.length) {
685
+ if (this.removeEmptyRules) {
686
+ return '';
687
+ }
688
+ return (this.emit(node.selectors
689
+ .map((s) => {
690
+ return indent + s;
691
+ })
692
+ .join(',\n'), node.position) + this.emit(' {}'));
693
+ }
694
+ return (this.emit(node.selectors
695
+ .map((s) => {
696
+ return indent + s;
697
+ })
698
+ .join(',\n'), node.position) +
699
+ this.emit(' {\n') +
700
+ this.emit(this.indent(1)) +
701
+ this.mapVisit(stripped, '\n') +
702
+ this.emit(this.indent(-1)) +
703
+ this.emit(`\n${this.indent()}}`));
704
+ }
705
+ /**
706
+ * Visit declaration node.
707
+ */
708
+ declaration(node) {
709
+ if (this.identity && node.rawBetween != null) {
710
+ return this.emit(`${node.property}${node.rawBetween}${node.rawValue ?? node.value}`, node.position);
711
+ }
712
+ if (this.compress) {
713
+ return (this.emit(`${node.property}:${node.value}`, node.position) +
714
+ this.emit(';'));
715
+ }
716
+ if (node.property === 'grid-template-areas') {
717
+ const indent = this.indent();
718
+ const pad = indent.length + node.property.length + 2; // 2 for ": "
719
+ const parts = node.value.split('\n');
720
+ const aligned = parts
721
+ .map((p, i) => (i === 0 ? p : ' '.repeat(pad) + p.trimStart()))
722
+ .join('\n');
723
+ return (this.emit(indent) +
724
+ this.emit(`${node.property}: ${aligned}`, node.position) +
725
+ this.emit(';'));
726
+ }
727
+ return (this.emit(this.indent()) +
728
+ this.emit(`${node.property}: ${node.value}`, node.position) +
729
+ this.emit(';'));
730
+ }
731
+ }
732
+ export default Compiler;