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.
- package/compiler/index.js +1 -1
- package/package.json +1 -1
- package/src/compiler/index.js +2 -1
- package/src/compiler/migrate/index.js +6 -1
- package/src/compiler/phases/1-parse/index.js +4 -0
- package/src/compiler/phases/1-parse/read/style.js +75 -29
- package/src/compiler/phases/2-analyze/css/css-analyze.js +3 -0
- package/src/compiler/phases/2-analyze/css/css-warn.js +3 -0
- package/src/compiler/phases/2-analyze/index.js +19 -15
- package/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js +16 -3
- package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +13 -2
- package/src/compiler/phases/3-transform/client/visitors/UpdateExpression.js +0 -1
- package/src/compiler/phases/3-transform/css/index.js +8 -1
- package/src/compiler/phases/3-transform/server/visitors/LabeledStatement.js +1 -0
- package/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js +4 -2
- package/src/compiler/phases/3-transform/server/visitors/shared/element.js +48 -43
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +1 -1
- package/src/compiler/print/index.js +372 -177
- package/src/internal/client/context.js +20 -53
- package/src/internal/client/dom/blocks/css-props.js +3 -3
- package/src/internal/client/dom/blocks/each.js +6 -2
- package/src/internal/client/dom/css.js +6 -1
- package/src/internal/client/dom/elements/attributes.js +2 -1
- package/src/internal/client/dom/elements/events.js +19 -1
- package/src/internal/client/reactivity/batch.js +1 -0
- package/src/internal/client/reactivity/sources.js +7 -1
- package/src/internal/server/context.js +8 -47
- package/src/internal/server/renderer.js +1 -0
- package/src/internal/shared/attributes.js +2 -1
- package/src/internal/shared/context.js +52 -0
- package/src/internal/shared/errors.js +2 -2
- package/src/version.js +1 -1
- package/types/index.d.ts +23 -9
- 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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
/**
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
201
|
-
|
|
302
|
+
return written;
|
|
303
|
+
}
|
|
202
304
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
|
|
321
|
+
context.write(value.slice(offset));
|
|
322
|
+
}
|
|
208
323
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
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
|
-
|
|
220
|
-
context.
|
|
346
|
+
separate();
|
|
347
|
+
context.visit(child);
|
|
348
|
+
started = true;
|
|
221
349
|
}
|
|
222
350
|
|
|
223
|
-
|
|
224
|
-
|
|
351
|
+
while (has_comment_before(end)) {
|
|
352
|
+
separate();
|
|
353
|
+
write_comment(context, comments[comment_index++]);
|
|
354
|
+
started = true;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
225
357
|
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
237
|
-
|
|
238
|
-
|
|
387
|
+
return {
|
|
388
|
+
Atrule(node, context) {
|
|
389
|
+
context.write(`@${escape_identifier(node.name)}`);
|
|
239
390
|
|
|
240
|
-
|
|
241
|
-
|
|
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
|
-
|
|
245
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
},
|
|
415
|
+
Block(node, context) {
|
|
416
|
+
context.write('{');
|
|
251
417
|
|
|
252
|
-
|
|
253
|
-
|
|
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
|
-
|
|
257
|
-
|
|
426
|
+
context.write('}');
|
|
427
|
+
},
|
|
258
428
|
|
|
259
|
-
|
|
260
|
-
context.write(
|
|
429
|
+
ClassSelector(node, context) {
|
|
430
|
+
context.write(`.${escape_identifier(node.name)}`);
|
|
431
|
+
},
|
|
261
432
|
|
|
262
|
-
|
|
433
|
+
ComplexSelector(node, context) {
|
|
434
|
+
for (const selector of node.children) context.visit(selector);
|
|
435
|
+
},
|
|
263
436
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
|
|
443
|
+
IdSelector(node, context) {
|
|
444
|
+
context.write(`#${escape_identifier(node.name)}`);
|
|
445
|
+
},
|
|
270
446
|
|
|
271
|
-
|
|
272
|
-
|
|
447
|
+
NestingSelector(node, context) {
|
|
448
|
+
context.write('&');
|
|
449
|
+
},
|
|
273
450
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
451
|
+
Nth(node, context) {
|
|
452
|
+
context.write(node.value);
|
|
453
|
+
},
|
|
277
454
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
455
|
+
Percentage(node, context) {
|
|
456
|
+
context.write(node.value);
|
|
457
|
+
},
|
|
281
458
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
context.
|
|
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
|
-
|
|
292
|
-
|
|
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
|
-
|
|
297
|
-
|
|
492
|
+
for (const selector of node.selectors) context.visit(selector);
|
|
493
|
+
},
|
|
298
494
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
502
|
+
SelectorList(node, context) {
|
|
503
|
+
print_selector_list(node, context, false);
|
|
504
|
+
},
|
|
308
505
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
506
|
+
StyleSheet(node, context) {
|
|
507
|
+
context.write('<style');
|
|
508
|
+
attributes(node, node.attributes, context, js_comments);
|
|
509
|
+
context.write('>');
|
|
312
510
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
context.
|
|
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.
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
},
|
|
519
|
+
context.write('</style>');
|
|
520
|
+
},
|
|
324
521
|
|
|
325
|
-
|
|
326
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1066
|
+
print_element(node, context, comments, state);
|
|
872
1067
|
},
|
|
873
1068
|
|
|
874
1069
|
SvelteBoundary(node, context) {
|
|
875
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1111
|
+
print_element(node, context, comments, state);
|
|
917
1112
|
},
|
|
918
1113
|
|
|
919
1114
|
SvelteHead(node, context) {
|
|
920
|
-
|
|
1115
|
+
print_element(node, context, comments, state);
|
|
921
1116
|
},
|
|
922
1117
|
|
|
923
1118
|
SvelteSelf(node, context) {
|
|
924
|
-
|
|
1119
|
+
print_element(node, context, comments, state);
|
|
925
1120
|
},
|
|
926
1121
|
|
|
927
1122
|
SvelteWindow(node, context) {
|
|
928
|
-
|
|
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
|
-
|
|
1131
|
+
print_element(node, context, comments, state);
|
|
937
1132
|
},
|
|
938
1133
|
|
|
939
1134
|
TransitionDirective(node, context) {
|