svelte 5.2.4 → 5.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiler/index.js +1 -1
- package/elements.d.ts +18 -0
- package/package.json +1 -1
- package/src/compiler/phases/2-analyze/visitors/Attribute.js +4 -5
- package/src/compiler/phases/2-analyze/visitors/CallExpression.js +0 -2
- package/src/compiler/phases/2-analyze/visitors/ExportDefaultDeclaration.js +7 -2
- package/src/compiler/phases/2-analyze/visitors/ExportNamedDeclaration.js +0 -18
- package/src/compiler/phases/2-analyze/visitors/ExportSpecifier.js +2 -23
- package/src/compiler/phases/2-analyze/visitors/ExpressionTag.js +5 -0
- package/src/compiler/phases/2-analyze/visitors/Identifier.js +3 -14
- package/src/compiler/phases/2-analyze/visitors/MemberExpression.js +0 -3
- package/src/compiler/phases/2-analyze/visitors/RegularElement.js +0 -10
- package/src/compiler/phases/2-analyze/visitors/TaggedTemplateExpression.js +0 -1
- package/src/compiler/phases/2-analyze/visitors/shared/utils.js +20 -1
- package/src/compiler/phases/3-transform/client/utils.js +5 -5
- package/src/compiler/phases/3-transform/client/visitors/ClassBody.js +1 -1
- package/src/compiler/phases/3-transform/client/visitors/Fragment.js +5 -5
- package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +20 -56
- package/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +14 -54
- package/src/compiler/phases/3-transform/client/visitors/shared/utils.js +37 -55
- package/src/compiler/phases/nodes.js +1 -2
- package/src/compiler/types/index.d.ts +0 -2
- package/src/internal/client/index.js +0 -1
- package/src/utils.js +15 -2
- package/src/version.js +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @import { Expression, ExpressionStatement, Identifier, MemberExpression, Statement, Super
|
|
1
|
+
/** @import { Expression, ExpressionStatement, Identifier, MemberExpression, Statement, Super } from 'estree' */
|
|
2
2
|
/** @import { AST, SvelteNode } from '#compiler' */
|
|
3
3
|
/** @import { ComponentClientTransformState } from '../../types' */
|
|
4
4
|
import { walk } from 'zimmerframe';
|
|
@@ -14,7 +14,7 @@ import { locator } from '../../../../../state.js';
|
|
|
14
14
|
* @param {Array<AST.Text | AST.ExpressionTag>} values
|
|
15
15
|
* @param {(node: SvelteNode, state: any) => any} visit
|
|
16
16
|
* @param {ComponentClientTransformState} state
|
|
17
|
-
* @returns {{ value: Expression, has_state: boolean, has_call: boolean
|
|
17
|
+
* @returns {{ value: Expression, has_state: boolean, has_call: boolean }}
|
|
18
18
|
*/
|
|
19
19
|
export function build_template_chunk(values, visit, state) {
|
|
20
20
|
/** @type {Expression[]} */
|
|
@@ -25,23 +25,15 @@ export function build_template_chunk(values, visit, state) {
|
|
|
25
25
|
|
|
26
26
|
let has_call = false;
|
|
27
27
|
let has_state = false;
|
|
28
|
-
let can_inline = true;
|
|
29
28
|
let contains_multiple_call_expression = false;
|
|
30
29
|
|
|
31
30
|
for (const node of values) {
|
|
32
31
|
if (node.type === 'ExpressionTag') {
|
|
33
|
-
|
|
34
|
-
if (has_call) contains_multiple_call_expression = true;
|
|
35
|
-
has_call = true;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (node.metadata.expression.has_state) {
|
|
39
|
-
has_state = true;
|
|
40
|
-
}
|
|
32
|
+
const metadata = node.metadata.expression;
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
contains_multiple_call_expression ||= has_call && metadata.has_call;
|
|
35
|
+
has_call ||= metadata.has_call;
|
|
36
|
+
has_state ||= metadata.has_state;
|
|
45
37
|
}
|
|
46
38
|
}
|
|
47
39
|
|
|
@@ -50,49 +42,39 @@ export function build_template_chunk(values, visit, state) {
|
|
|
50
42
|
|
|
51
43
|
if (node.type === 'Text') {
|
|
52
44
|
quasi.value.cooked += node.data;
|
|
45
|
+
} else if (node.type === 'ExpressionTag' && node.expression.type === 'Literal') {
|
|
46
|
+
if (node.expression.value != null) {
|
|
47
|
+
quasi.value.cooked += node.expression.value + '';
|
|
48
|
+
}
|
|
53
49
|
} else {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
50
|
+
if (contains_multiple_call_expression) {
|
|
51
|
+
const id = b.id(state.scope.generate('stringified_text'));
|
|
52
|
+
state.init.push(
|
|
53
|
+
b.const(
|
|
54
|
+
id,
|
|
55
|
+
create_derived(
|
|
56
|
+
state,
|
|
57
|
+
b.thunk(
|
|
58
|
+
b.logical(
|
|
59
|
+
'??',
|
|
60
|
+
/** @type {Expression} */ (visit(node.expression, state)),
|
|
61
|
+
b.literal('')
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
);
|
|
67
|
+
expressions.push(b.call('$.get', id));
|
|
68
|
+
} else if (values.length === 1) {
|
|
69
|
+
// If we have a single expression, then pass that in directly to possibly avoid doing
|
|
70
|
+
// extra work in the template_effect (instead we do the work in set_text).
|
|
71
|
+
return { value: visit(node.expression, state), has_state, has_call };
|
|
60
72
|
} else {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// if we don't know the value, we need to add `?? ''` to replace
|
|
64
|
-
// `null` and `undefined` with the empty string
|
|
65
|
-
let needs_fallback = true;
|
|
66
|
-
|
|
67
|
-
if (value.type === 'Identifier') {
|
|
68
|
-
const binding = state.scope.get(value.name);
|
|
69
|
-
|
|
70
|
-
if (binding && binding.initial?.type === 'Literal' && !binding.reassigned) {
|
|
71
|
-
needs_fallback = binding.initial.value === null;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (needs_fallback) {
|
|
76
|
-
value = b.logical('??', expression, b.literal(''));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (contains_multiple_call_expression) {
|
|
80
|
-
const id = b.id(state.scope.generate('stringified_text'));
|
|
81
|
-
|
|
82
|
-
state.init.push(b.const(id, create_derived(state, b.thunk(value))));
|
|
83
|
-
|
|
84
|
-
expressions.push(b.call('$.get', id));
|
|
85
|
-
} else if (values.length === 1) {
|
|
86
|
-
// If we have a single expression, then pass that in directly to possibly avoid doing
|
|
87
|
-
// extra work in the template_effect (instead we do the work in set_text).
|
|
88
|
-
return { value: visit(node.expression, state), has_state, has_call, can_inline };
|
|
89
|
-
} else {
|
|
90
|
-
expressions.push(value);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
quasi = b.quasi('', i + 1 === values.length);
|
|
94
|
-
quasis.push(quasi);
|
|
73
|
+
expressions.push(b.logical('??', visit(node.expression, state), b.literal('')));
|
|
95
74
|
}
|
|
75
|
+
|
|
76
|
+
quasi = b.quasi('', i + 1 === values.length);
|
|
77
|
+
quasis.push(quasi);
|
|
96
78
|
}
|
|
97
79
|
}
|
|
98
80
|
|
|
@@ -102,7 +84,7 @@ export function build_template_chunk(values, visit, state) {
|
|
|
102
84
|
|
|
103
85
|
const value = b.template(quasis, expressions);
|
|
104
86
|
|
|
105
|
-
return { value, has_state, has_call
|
|
87
|
+
return { value, has_state, has_call };
|
|
106
88
|
}
|
|
107
89
|
|
|
108
90
|
/**
|
|
@@ -317,8 +317,6 @@ export interface ExpressionMetadata {
|
|
|
317
317
|
has_state: boolean;
|
|
318
318
|
/** True if the expression involves a call expression (often, it will need to be wrapped in a derived) */
|
|
319
319
|
has_call: boolean;
|
|
320
|
-
/** True if the expression can be inlined into a template */
|
|
321
|
-
can_inline: boolean;
|
|
322
320
|
}
|
|
323
321
|
|
|
324
322
|
export * from './template.js';
|
package/src/utils.js
CHANGED
|
@@ -192,7 +192,8 @@ const ATTRIBUTE_ALIASES = {
|
|
|
192
192
|
ismap: 'isMap',
|
|
193
193
|
nomodule: 'noModule',
|
|
194
194
|
playsinline: 'playsInline',
|
|
195
|
-
readonly: 'readOnly'
|
|
195
|
+
readonly: 'readOnly',
|
|
196
|
+
srcobject: 'srcObject'
|
|
196
197
|
};
|
|
197
198
|
|
|
198
199
|
/**
|
|
@@ -212,7 +213,8 @@ const DOM_PROPERTIES = [
|
|
|
212
213
|
'readOnly',
|
|
213
214
|
'value',
|
|
214
215
|
'inert',
|
|
215
|
-
'volume'
|
|
216
|
+
'volume',
|
|
217
|
+
'srcObject'
|
|
216
218
|
];
|
|
217
219
|
|
|
218
220
|
/**
|
|
@@ -222,6 +224,17 @@ export function is_dom_property(name) {
|
|
|
222
224
|
return DOM_PROPERTIES.includes(name);
|
|
223
225
|
}
|
|
224
226
|
|
|
227
|
+
const NON_STATIC_PROPERTIES = ['autofocus', 'muted'];
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Returns `true` if the given attribute cannot be set through the template
|
|
231
|
+
* string, i.e. needs some kind of JavaScript handling to work.
|
|
232
|
+
* @param {string} name
|
|
233
|
+
*/
|
|
234
|
+
export function cannot_be_set_statically(name) {
|
|
235
|
+
return NON_STATIC_PROPERTIES.includes(name);
|
|
236
|
+
}
|
|
237
|
+
|
|
225
238
|
/**
|
|
226
239
|
* Subset of delegated events which should be passive by default.
|
|
227
240
|
* These two are already passive via browser defaults on window, document and body.
|
package/src/version.js
CHANGED