svelte 5.56.8 → 5.56.10

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 (34) hide show
  1. package/compiler/index.js +1 -1
  2. package/package.json +1 -1
  3. package/src/compiler/index.js +2 -1
  4. package/src/compiler/migrate/index.js +6 -1
  5. package/src/compiler/phases/1-parse/index.js +4 -0
  6. package/src/compiler/phases/1-parse/read/style.js +75 -29
  7. package/src/compiler/phases/2-analyze/css/css-analyze.js +3 -0
  8. package/src/compiler/phases/2-analyze/css/css-warn.js +3 -0
  9. package/src/compiler/phases/2-analyze/index.js +19 -15
  10. package/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js +16 -3
  11. package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +13 -2
  12. package/src/compiler/phases/3-transform/client/visitors/UpdateExpression.js +0 -1
  13. package/src/compiler/phases/3-transform/css/index.js +8 -1
  14. package/src/compiler/phases/3-transform/server/visitors/LabeledStatement.js +1 -0
  15. package/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js +4 -2
  16. package/src/compiler/phases/3-transform/server/visitors/shared/element.js +48 -43
  17. package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +1 -1
  18. package/src/compiler/print/index.js +372 -177
  19. package/src/internal/client/context.js +20 -53
  20. package/src/internal/client/dom/blocks/css-props.js +3 -3
  21. package/src/internal/client/dom/blocks/each.js +6 -2
  22. package/src/internal/client/dom/css.js +6 -1
  23. package/src/internal/client/dom/elements/attributes.js +2 -1
  24. package/src/internal/client/dom/elements/events.js +19 -1
  25. package/src/internal/client/reactivity/batch.js +1 -0
  26. package/src/internal/client/reactivity/sources.js +7 -1
  27. package/src/internal/server/context.js +8 -47
  28. package/src/internal/server/renderer.js +1 -0
  29. package/src/internal/shared/attributes.js +2 -1
  30. package/src/internal/shared/context.js +52 -0
  31. package/src/internal/shared/errors.js +2 -2
  32. package/src/version.js +1 -1
  33. package/types/index.d.ts +23 -9
  34. package/types/index.d.ts.map +1 -1
@@ -7,6 +7,68 @@ import { is_void } from '../../utils.js';
7
7
  /** Threshold for when content should be formatted on separate lines */
8
8
  const LINE_BREAK_THRESHOLD = 50;
9
9
 
10
+ /** Characters that are valid in a CSS identifier without escaping */
11
+ const REGEX_IDENTIFIER_CHAR = /^[a-zA-Z0-9_-]$/;
12
+
13
+ /** Hex digits — a backslash followed by one of these is read as a hex escape */
14
+ const REGEX_HEX_DIGIT = /[0-9a-fA-F]/;
15
+
16
+ /**
17
+ * Re-escape a CSS identifier name so that it prints as valid CSS.
18
+ *
19
+ * `parse` decodes CSS escape sequences when building the AST — `\31` becomes `1`,
20
+ * `\a` becomes a newline — but keeps single-character escapes such as `\.` and
21
+ * escaped backslashes intact. When printing we therefore only need to escape the
22
+ * characters that would be illegal in a bare identifier: a leading digit, `-`
23
+ * followed by a digit, whitespace and control characters, and anything else that
24
+ * is not already escaped.
25
+ * @param {string} name
26
+ */
27
+ function escape_identifier(name) {
28
+ let escaped = '';
29
+ let i = 0;
30
+
31
+ while (i < name.length) {
32
+ const char = name[i];
33
+
34
+ if (char === '\\') {
35
+ const next = name.charAt(i + 1);
36
+ if (next === '' || REGEX_HEX_DIGIT.test(next)) {
37
+ // A literal backslash in a name must itself be escaped: `\5c `
38
+ // re-parses to a backslash, whereas a backslash followed by a hex
39
+ // digit (or by nothing) would be read back as a hex escape.
40
+ escaped += '\\5c ';
41
+ i += 1;
42
+ continue;
43
+ }
44
+
45
+ // Already escaped — copy the backslash and the escaped character as-is.
46
+ escaped += '\\' + next;
47
+ i += 2;
48
+ continue;
49
+ }
50
+
51
+ const code = /** @type {number} */ (char.codePointAt(0));
52
+ const is_leading_digit = i === 0 && char >= '0' && char <= '9';
53
+ const is_leading_hyphen_digit =
54
+ i === 0 && char === '-' && name.charAt(i + 1) >= '0' && name.charAt(i + 1) <= '9';
55
+
56
+ if (
57
+ is_leading_digit ||
58
+ is_leading_hyphen_digit ||
59
+ !(REGEX_IDENTIFIER_CHAR.test(char) || code >= 160)
60
+ ) {
61
+ escaped += `\\${code.toString(16)} `;
62
+ } else {
63
+ escaped += char;
64
+ }
65
+
66
+ i += 1;
67
+ }
68
+
69
+ return escaped;
70
+ }
71
+
10
72
  /**
11
73
  * `print` converts a Svelte AST node back into Svelte source code.
12
74
  * It is primarily intended for tools that parse and transform components using the compiler’s modern AST representation.
@@ -19,6 +81,10 @@ const LINE_BREAK_THRESHOLD = 50;
19
81
  */
20
82
  export function print(ast, options = undefined) {
21
83
  const comments = (ast.type === 'Root' && ast.comments) || [];
84
+ const state = { preserve_whitespace: 0 };
85
+ const css_comments =
86
+ (ast.type === 'Root' ? ast.css?.comments : ast.type === 'StyleSheet' ? ast.comments : null) ||
87
+ [];
22
88
 
23
89
  return esrap.print(
24
90
  ast,
@@ -28,8 +94,8 @@ export function print(ast, options = undefined) {
28
94
  getLeadingComments: options?.getLeadingComments,
29
95
  getTrailingComments: options?.getTrailingComments
30
96
  }),
31
- ...svelte_visitors(comments),
32
- ...css_visitors
97
+ ...svelte_visitors(comments, state),
98
+ ...css_visitors(css_comments, comments)
33
99
  }),
34
100
  {
35
101
  indent: options?.indent
@@ -40,9 +106,15 @@ export function print(ast, options = undefined) {
40
106
  /**
41
107
  * @param {Context} context
42
108
  * @param {AST.SvelteNode} node
109
+ * @param {boolean} preserve_whitespace
43
110
  * @param {boolean} allow_inline
44
111
  */
45
- function block(context, node, allow_inline = false) {
112
+ function block(context, node, preserve_whitespace = false, allow_inline = false) {
113
+ if (preserve_whitespace) {
114
+ context.visit(node);
115
+ return;
116
+ }
117
+
46
118
  const child_context = context.new();
47
119
  child_context.visit(node);
48
120
 
@@ -82,6 +154,7 @@ function attributes(node, attributes, context, comments) {
82
154
  }
83
155
 
84
156
  const separator = context.new();
157
+ let previous_attribute_end = node.start;
85
158
 
86
159
  const children = attributes.map((attribute) => {
87
160
  const child_context = context.new();
@@ -90,12 +163,16 @@ function attributes(node, attributes, context, comments) {
90
163
  const comment = comments[comment_index];
91
164
 
92
165
  if (comment.start < attribute.start) {
93
- if (comment.type === 'Line') {
94
- child_context.write('//' + comment.value);
95
- child_context.newline();
96
- } else {
97
- child_context.write('/*' + comment.value + '*/'); // TODO match indentation?
98
- child_context.append(separator);
166
+ // Inside a previous attribute's value can be comments which don't
167
+ // advance comment_index, therefore this additional check
168
+ if (comment.start >= previous_attribute_end) {
169
+ if (comment.type === 'Line') {
170
+ child_context.write('//' + comment.value);
171
+ child_context.newline();
172
+ } else {
173
+ child_context.write('/*' + comment.value + '*/'); // TODO match indentation?
174
+ child_context.append(separator);
175
+ }
99
176
  }
100
177
 
101
178
  comment_index += 1;
@@ -105,6 +182,7 @@ function attributes(node, attributes, context, comments) {
105
182
  }
106
183
 
107
184
  child_context.visit(attribute);
185
+ previous_attribute_end = attribute.end;
108
186
 
109
187
  length += child_context.measure() + 1;
110
188
 
@@ -137,8 +215,9 @@ function attributes(node, attributes, context, comments) {
137
215
  * @param {AST.BaseElement} node
138
216
  * @param {Context} context
139
217
  * @param {AST.JSComment[]} comments
218
+ * @param {{ preserve_whitespace: number }} state
140
219
  */
141
- function base_element(node, context, comments) {
220
+ function base_element(node, context, comments, state) {
142
221
  const child_context = context.new();
143
222
 
144
223
  child_context.write('<' + node.name);
@@ -164,174 +243,298 @@ function base_element(node, context, comments) {
164
243
  child_context.write(`${multiline_attributes ? '' : ' '}/>`);
165
244
  } else {
166
245
  child_context.write('>');
167
- block(child_context, node.fragment, true);
246
+ block(child_context, node.fragment, state.preserve_whitespace > 0, true);
168
247
  child_context.write(`</${node.name}>`);
169
248
  }
170
249
 
171
250
  context.append(child_context);
172
251
  }
173
252
 
174
- /** @type {Visitors<AST.SvelteNode>} */
175
- const css_visitors = {
176
- Atrule(node, context) {
177
- context.write(`@${node.name}`);
178
- if (node.prelude) context.write(` ${node.prelude}`);
253
+ /**
254
+ * @param {AST.BaseElement} node
255
+ * @param {Context} context
256
+ * @param {AST.JSComment[]} comments
257
+ * @param {{ preserve_whitespace: number }} state
258
+ */
259
+ function print_element(node, context, comments, state) {
260
+ const name = node.name.toLowerCase();
261
+ const preserve =
262
+ (node.type === 'RegularElement' || node.type === 'TitleElement') &&
263
+ (name === 'pre' || name === 'textarea' || name === 'title');
264
+
265
+ if (preserve) state.preserve_whitespace += 1;
266
+ base_element(node, context, comments, state);
267
+ if (preserve) state.preserve_whitespace -= 1;
268
+ }
179
269
 
180
- if (node.block) {
181
- context.write(' ');
182
- context.visit(node.block);
183
- } else {
184
- context.write(';');
185
- }
186
- },
270
+ /**
271
+ * @param {AST.CSS.CSSComment[]} comments
272
+ * @param {AST.JSComment[]} js_comments
273
+ * @returns {Visitors<AST.SvelteNode>}
274
+ */
275
+ function css_visitors(comments, js_comments) {
276
+ let comment_index = 0;
277
+
278
+ /** @param {number} end */
279
+ const has_comment_before = (end) => comments[comment_index]?.start < end;
280
+
281
+ /**
282
+ * @param {Context} context
283
+ * @param {AST.CSS.CSSComment} comment
284
+ */
285
+ function write_comment(context, comment) {
286
+ context.write(`/*${comment.value}*/`);
287
+ }
187
288
 
188
- AttributeSelector(node, context) {
189
- context.write(`[${node.name}`);
190
- if (node.matcher) {
191
- context.write(node.matcher);
192
- context.write(`"${node.value}"`);
193
- if (node.flags) {
194
- context.write(` ${node.flags}`);
195
- }
289
+ /**
290
+ * @param {Context} context
291
+ * @param {number} end
292
+ */
293
+ function write_inline_comments(context, end) {
294
+ let written = false;
295
+
296
+ while (has_comment_before(end)) {
297
+ if (written) context.write(' ');
298
+ write_comment(context, comments[comment_index++]);
299
+ written = true;
196
300
  }
197
- context.write(']');
198
- },
199
301
 
200
- Block(node, context) {
201
- context.write('{');
302
+ return written;
303
+ }
202
304
 
203
- if (node.children.length > 0) {
204
- context.indent();
205
- context.newline();
305
+ /**
306
+ * @param {Context} context
307
+ * @param {string} value
308
+ * @param {number} end
309
+ */
310
+ function write_value(context, value, end) {
311
+ let offset = 0;
312
+
313
+ while (has_comment_before(end)) {
314
+ const comment = comments[comment_index++];
315
+ const position = Math.max(offset, Math.min(comment.position ?? 0, value.length));
316
+ context.write(value.slice(offset, position));
317
+ write_comment(context, comment);
318
+ offset = position;
319
+ }
206
320
 
207
- let started = false;
321
+ context.write(value.slice(offset));
322
+ }
208
323
 
209
- for (const child of node.children) {
210
- if (started) {
211
- context.newline();
212
- }
324
+ /**
325
+ * @param {Context} context
326
+ * @param {Array<AST.CSS.Rule | AST.CSS.Atrule | AST.CSS.Declaration>} children
327
+ * @param {number} end
328
+ * @param {boolean} margins
329
+ */
330
+ function print_children(context, children, end, margins) {
331
+ let started = false;
213
332
 
214
- context.visit(child);
333
+ const separate = () => {
334
+ if (!started) return;
335
+ if (margins) context.margin();
336
+ context.newline();
337
+ };
215
338
 
339
+ for (const child of children) {
340
+ while (has_comment_before(child.start)) {
341
+ separate();
342
+ write_comment(context, comments[comment_index++]);
216
343
  started = true;
217
344
  }
218
345
 
219
- context.dedent();
220
- context.newline();
346
+ separate();
347
+ context.visit(child);
348
+ started = true;
221
349
  }
222
350
 
223
- context.write('}');
224
- },
351
+ while (has_comment_before(end)) {
352
+ separate();
353
+ write_comment(context, comments[comment_index++]);
354
+ started = true;
355
+ }
356
+ }
225
357
 
226
- ClassSelector(node, context) {
227
- context.write(`.${node.name}`);
228
- },
358
+ /**
359
+ * @param {AST.CSS.SelectorList} node
360
+ * @param {Context} context
361
+ * @param {boolean} multiline
362
+ */
363
+ function print_selector_list(node, context, multiline) {
364
+ let needs_separator = false;
365
+ let remaining_selectors = node.children.length;
229
366
 
230
- ComplexSelector(node, context) {
231
367
  for (const selector of node.children) {
368
+ while (has_comment_before(selector.start)) {
369
+ if (needs_separator) context.write(' ');
370
+ write_comment(context, comments[comment_index++]);
371
+ needs_separator = true;
372
+ }
373
+
374
+ if (needs_separator) {
375
+ if (multiline) context.newline();
376
+ else context.write(' ');
377
+ }
378
+
232
379
  context.visit(selector);
380
+ needs_separator = true;
381
+ remaining_selectors -= 1;
382
+
383
+ if (remaining_selectors > 0) context.write(',');
233
384
  }
234
- },
385
+ }
235
386
 
236
- Declaration(node, context) {
237
- context.write(`${node.property}: ${node.value};`);
238
- },
387
+ return {
388
+ Atrule(node, context) {
389
+ context.write(`@${escape_identifier(node.name)}`);
239
390
 
240
- IdSelector(node, context) {
241
- context.write(`#${node.name}`);
242
- },
391
+ const prelude_end = node.block?.start ?? node.end;
392
+ if (node.prelude || has_comment_before(prelude_end)) {
393
+ context.write(' ');
394
+ write_value(context, node.prelude, prelude_end);
395
+ }
243
396
 
244
- NestingSelector(node, context) {
245
- context.write('&');
246
- },
397
+ if (node.block) {
398
+ context.write(' ');
399
+ context.visit(node.block);
400
+ } else {
401
+ context.write(';');
402
+ }
403
+ },
404
+
405
+ AttributeSelector(node, context) {
406
+ context.write(`[${escape_identifier(node.name)}`);
407
+ if (node.matcher) {
408
+ context.write(node.matcher);
409
+ context.write(`"${node.value}"`);
410
+ if (node.flags) context.write(` ${node.flags}`);
411
+ }
412
+ context.write(']');
413
+ },
247
414
 
248
- Nth(node, context) {
249
- context.write(node.value);
250
- },
415
+ Block(node, context) {
416
+ context.write('{');
251
417
 
252
- Percentage(node, context) {
253
- context.write(node.value);
254
- },
418
+ if (node.children.length > 0 || has_comment_before(node.end)) {
419
+ context.indent();
420
+ context.newline();
421
+ print_children(context, node.children, node.end, false);
422
+ context.dedent();
423
+ context.newline();
424
+ }
255
425
 
256
- PseudoClassSelector(node, context) {
257
- context.write(`:${node.name}`);
426
+ context.write('}');
427
+ },
258
428
 
259
- if (node.args) {
260
- context.write('(');
429
+ ClassSelector(node, context) {
430
+ context.write(`.${escape_identifier(node.name)}`);
431
+ },
261
432
 
262
- let started = false;
433
+ ComplexSelector(node, context) {
434
+ for (const selector of node.children) context.visit(selector);
435
+ },
263
436
 
264
- for (const arg of node.args.children) {
265
- if (started) {
266
- context.write(', ');
267
- }
437
+ Declaration(node, context) {
438
+ context.write(`${node.property}: `);
439
+ write_value(context, node.value, node.end);
440
+ context.write(';');
441
+ },
268
442
 
269
- context.visit(arg);
443
+ IdSelector(node, context) {
444
+ context.write(`#${escape_identifier(node.name)}`);
445
+ },
270
446
 
271
- started = true;
272
- }
447
+ NestingSelector(node, context) {
448
+ context.write('&');
449
+ },
273
450
 
274
- context.write(')');
275
- }
276
- },
451
+ Nth(node, context) {
452
+ context.write(node.value);
453
+ },
277
454
 
278
- PseudoElementSelector(node, context) {
279
- context.write(`::${node.name}`);
280
- },
455
+ Percentage(node, context) {
456
+ context.write(node.value);
457
+ },
281
458
 
282
- RelativeSelector(node, context) {
283
- if (node.combinator) {
284
- if (node.combinator.name === ' ') {
285
- context.write(' ');
286
- } else {
287
- context.write(` ${node.combinator.name} `);
459
+ PseudoClassSelector(node, context) {
460
+ context.write(`:${escape_identifier(node.name)}`);
461
+
462
+ if (node.args) {
463
+ context.write('(');
464
+ context.visit(node.args);
465
+ if (has_comment_before(node.end)) {
466
+ context.write(' ');
467
+ write_inline_comments(context, node.end);
468
+ }
469
+ context.write(')');
288
470
  }
289
- }
471
+ },
472
+
473
+ PseudoElementSelector(node, context) {
474
+ context.write(`::${escape_identifier(node.name)}`);
475
+ if (node.args) {
476
+ context.write('(');
477
+ context.visit(node.args);
478
+ if (has_comment_before(node.end)) {
479
+ context.write(' ');
480
+ write_inline_comments(context, node.end);
481
+ }
482
+ context.write(')');
483
+ }
484
+ },
290
485
 
291
- for (const selector of node.selectors) {
292
- context.visit(selector);
293
- }
294
- },
486
+ RelativeSelector(node, context) {
487
+ if (node.combinator) {
488
+ if (node.combinator.name === ' ') context.write(' ');
489
+ else context.write(` ${node.combinator.name} `);
490
+ }
295
491
 
296
- Rule(node, context) {
297
- let started = false;
492
+ for (const selector of node.selectors) context.visit(selector);
493
+ },
298
494
 
299
- for (const selector of node.prelude.children) {
300
- if (started) {
301
- context.write(',');
302
- context.newline();
303
- }
495
+ Rule(node, context) {
496
+ print_selector_list(node.prelude, context, true);
497
+ context.write(' ');
498
+ if (write_inline_comments(context, node.block.start)) context.write(' ');
499
+ context.visit(node.block);
500
+ },
304
501
 
305
- context.visit(selector);
306
- started = true;
307
- }
502
+ SelectorList(node, context) {
503
+ print_selector_list(node, context, false);
504
+ },
308
505
 
309
- context.write(' ');
310
- context.visit(node.block);
311
- },
506
+ StyleSheet(node, context) {
507
+ context.write('<style');
508
+ attributes(node, node.attributes, context, js_comments);
509
+ context.write('>');
312
510
 
313
- SelectorList(node, context) {
314
- let started = false;
315
- for (const selector of node.children) {
316
- if (started) {
317
- context.write(', ');
511
+ if (node.children.length > 0 || node.comments.length > 0) {
512
+ context.indent();
513
+ context.newline();
514
+ print_children(context, node.children, node.content.end, true);
515
+ context.dedent();
516
+ context.newline();
318
517
  }
319
518
 
320
- context.visit(selector);
321
- started = true;
322
- }
323
- },
519
+ context.write('</style>');
520
+ },
324
521
 
325
- TypeSelector(node, context) {
326
- context.write(node.name);
327
- }
328
- };
522
+ TypeSelector(node, context) {
523
+ if (node.namespace !== undefined) {
524
+ context.write(node.namespace === '*' ? '*' : escape_identifier(node.namespace));
525
+ context.write('|');
526
+ }
527
+ context.write(node.name === '*' ? node.name : escape_identifier(node.name));
528
+ }
529
+ };
530
+ }
329
531
 
330
532
  /**
331
533
  * @param {AST.JSComment[]} comments
534
+ * @param {{ preserve_whitespace: number }} state
332
535
  * @returns {Visitors<AST.SvelteNode>}
333
536
  */
334
- const svelte_visitors = (comments) => ({
537
+ const svelte_visitors = (comments, state) => ({
335
538
  Root(node, context) {
336
539
  if (node.options) {
337
540
  context.write('<svelte:options');
@@ -363,11 +566,27 @@ const svelte_visitors = (comments) => ({
363
566
  context.write('<script');
364
567
  attributes(node, node.attributes, context, comments);
365
568
  context.write('>');
366
- block(context, node.content);
569
+ block(context, node.content, state.preserve_whitespace > 0);
367
570
  context.write('</script>');
368
571
  },
369
572
 
370
573
  Fragment(node, context) {
574
+ if (state.preserve_whitespace > 0) {
575
+ for (const child of node.nodes) {
576
+ context.visit(child);
577
+ context.multiline ||= child.type === 'Text' && /[\r\n]/.test(child.data);
578
+ }
579
+ return;
580
+ }
581
+
582
+ const first = node.nodes[0];
583
+ const last = node.nodes.at(-1);
584
+ const has_surrounding_whitespace =
585
+ first?.type === 'Text' &&
586
+ /^\s/.test(first.data) &&
587
+ last?.type === 'Text' &&
588
+ /\s$/.test(last.data);
589
+
371
590
  /** @type {AST.SvelteNode[][]} */
372
591
  const items = [];
373
592
 
@@ -459,6 +678,10 @@ const svelte_visitors = (comments) => ({
459
678
  });
460
679
 
461
680
  multiline ||= width > LINE_BREAK_THRESHOLD;
681
+ // Normally context.newline() also makes context.multiline true, but the below loop only
682
+ // does that if we have more than one child context. If there's one long text block inside
683
+ // with whitespace at the edges we wanna split that up, too.
684
+ context.multiline ||= has_surrounding_whitespace && width > LINE_BREAK_THRESHOLD * 2;
462
685
 
463
686
  for (let i = 0; i < child_contexts.length; i += 1) {
464
687
  const prev = child_contexts[i];
@@ -525,7 +748,7 @@ const svelte_visitors = (comments) => ({
525
748
 
526
749
  if (node.pending) {
527
750
  context.write('}');
528
- block(context, node.pending);
751
+ block(context, node.pending, state.preserve_whitespace > 0);
529
752
  context.write('{:');
530
753
  } else {
531
754
  context.write(' ');
@@ -536,7 +759,7 @@ const svelte_visitors = (comments) => ({
536
759
  if (node.value) context.visit(node.value);
537
760
  context.write('}');
538
761
 
539
- block(context, node.then);
762
+ block(context, node.then, state.preserve_whitespace > 0);
540
763
 
541
764
  if (node.catch) {
542
765
  context.write('{:');
@@ -544,11 +767,11 @@ const svelte_visitors = (comments) => ({
544
767
  }
545
768
 
546
769
  if (node.catch) {
547
- context.write(node.value ? 'catch ' : 'catch');
770
+ context.write(node.error ? 'catch ' : 'catch');
548
771
  if (node.error) context.visit(node.error);
549
772
  context.write('}');
550
773
 
551
- block(context, node.catch);
774
+ block(context, node.catch, state.preserve_whitespace > 0);
552
775
  }
553
776
 
554
777
  context.write('{/await}');
@@ -592,7 +815,7 @@ const svelte_visitors = (comments) => ({
592
815
  },
593
816
 
594
817
  Component(node, context) {
595
- base_element(node, context, comments);
818
+ print_element(node, context, comments, state);
596
819
  },
597
820
 
598
821
  ConstTag(node, context) {
@@ -682,11 +905,11 @@ const svelte_visitors = (comments) => ({
682
905
 
683
906
  context.write('}');
684
907
 
685
- block(context, node.body);
908
+ block(context, node.body, state.preserve_whitespace > 0);
686
909
 
687
910
  if (node.fallback) {
688
911
  context.write('{:else}');
689
- block(context, node.fallback);
912
+ block(context, node.fallback, state.preserve_whitespace > 0);
690
913
  }
691
914
 
692
915
  context.write('{/each}');
@@ -710,13 +933,13 @@ const svelte_visitors = (comments) => ({
710
933
  context.visit(node.test);
711
934
  context.write('}');
712
935
 
713
- block(context, node.consequent);
936
+ block(context, node.consequent, state.preserve_whitespace > 0);
714
937
  } else {
715
938
  context.write('{#if ');
716
939
  context.visit(node.test);
717
940
  context.write('}');
718
941
 
719
- block(context, node.consequent);
942
+ block(context, node.consequent, state.preserve_whitespace > 0);
720
943
  }
721
944
 
722
945
  if (node.alternate !== null) {
@@ -728,7 +951,7 @@ const svelte_visitors = (comments) => ({
728
951
  )
729
952
  ) {
730
953
  context.write('{:else}');
731
- block(context, node.alternate);
954
+ block(context, node.alternate, state.preserve_whitespace > 0);
732
955
  } else {
733
956
  context.visit(node.alternate);
734
957
  }
@@ -743,7 +966,7 @@ const svelte_visitors = (comments) => ({
743
966
  context.write('{#key ');
744
967
  context.visit(node.expression);
745
968
  context.write('}');
746
- block(context, node.fragment);
969
+ block(context, node.fragment, state.preserve_whitespace > 0);
747
970
  context.write('{/key}');
748
971
  },
749
972
 
@@ -775,7 +998,7 @@ const svelte_visitors = (comments) => ({
775
998
  },
776
999
 
777
1000
  RegularElement(node, context) {
778
- base_element(node, context, comments);
1001
+ print_element(node, context, comments, state);
779
1002
  },
780
1003
 
781
1004
  RenderTag(node, context) {
@@ -785,7 +1008,7 @@ const svelte_visitors = (comments) => ({
785
1008
  },
786
1009
 
787
1010
  SlotElement(node, context) {
788
- base_element(node, context, comments);
1011
+ print_element(node, context, comments, state);
789
1012
  },
790
1013
 
791
1014
  SnippetBlock(node, context) {
@@ -804,7 +1027,7 @@ const svelte_visitors = (comments) => ({
804
1027
  }
805
1028
 
806
1029
  context.write(')}');
807
- block(context, node.body);
1030
+ block(context, node.body, state.preserve_whitespace > 0);
808
1031
  context.write('{/snippet}');
809
1032
  },
810
1033
 
@@ -839,40 +1062,12 @@ const svelte_visitors = (comments) => ({
839
1062
  }
840
1063
  },
841
1064
 
842
- StyleSheet(node, context) {
843
- context.write('<style');
844
- attributes(node, node.attributes, context, comments);
845
- context.write('>');
846
-
847
- if (node.children.length > 0) {
848
- context.indent();
849
- context.newline();
850
-
851
- let started = false;
852
-
853
- for (const child of node.children) {
854
- if (started) {
855
- context.margin();
856
- context.newline();
857
- }
858
-
859
- context.visit(child);
860
- started = true;
861
- }
862
-
863
- context.dedent();
864
- context.newline();
865
- }
866
-
867
- context.write('</style>');
868
- },
869
-
870
1065
  SvelteBody(node, context) {
871
- base_element(node, context, comments);
1066
+ print_element(node, context, comments, state);
872
1067
  },
873
1068
 
874
1069
  SvelteBoundary(node, context) {
875
- base_element(node, context, comments);
1070
+ print_element(node, context, comments, state);
876
1071
  },
877
1072
 
878
1073
  SvelteComponent(node, context) {
@@ -884,7 +1079,7 @@ const svelte_visitors = (comments) => ({
884
1079
  attributes(node, node.attributes, context, comments);
885
1080
  if (node.fragment && node.fragment.nodes.length > 0) {
886
1081
  context.write('>');
887
- block(context, node.fragment, true);
1082
+ block(context, node.fragment, state.preserve_whitespace > 0, true);
888
1083
  context.write(`</svelte:component>`);
889
1084
  } else {
890
1085
  context.write(' />');
@@ -892,7 +1087,7 @@ const svelte_visitors = (comments) => ({
892
1087
  },
893
1088
 
894
1089
  SvelteDocument(node, context) {
895
- base_element(node, context, comments);
1090
+ print_element(node, context, comments, state);
896
1091
  },
897
1092
 
898
1093
  SvelteElement(node, context) {
@@ -905,7 +1100,7 @@ const svelte_visitors = (comments) => ({
905
1100
 
906
1101
  if (node.fragment && node.fragment.nodes.length > 0) {
907
1102
  context.write('>');
908
- block(context, node.fragment);
1103
+ block(context, node.fragment, state.preserve_whitespace > 0);
909
1104
  context.write(`</svelte:element>`);
910
1105
  } else {
911
1106
  context.write(' />');
@@ -913,19 +1108,19 @@ const svelte_visitors = (comments) => ({
913
1108
  },
914
1109
 
915
1110
  SvelteFragment(node, context) {
916
- base_element(node, context, comments);
1111
+ print_element(node, context, comments, state);
917
1112
  },
918
1113
 
919
1114
  SvelteHead(node, context) {
920
- base_element(node, context, comments);
1115
+ print_element(node, context, comments, state);
921
1116
  },
922
1117
 
923
1118
  SvelteSelf(node, context) {
924
- base_element(node, context, comments);
1119
+ print_element(node, context, comments, state);
925
1120
  },
926
1121
 
927
1122
  SvelteWindow(node, context) {
928
- base_element(node, context, comments);
1123
+ print_element(node, context, comments, state);
929
1124
  },
930
1125
 
931
1126
  Text(node, context) {
@@ -933,7 +1128,7 @@ const svelte_visitors = (comments) => ({
933
1128
  },
934
1129
 
935
1130
  TitleElement(node, context) {
936
- base_element(node, context, comments);
1131
+ print_element(node, context, comments, state);
937
1132
  },
938
1133
 
939
1134
  TransitionDirective(node, context) {