Skip to content

Commit c0832fd

Browse files
authored
fix: exclude bind:this from reactive state validation (#12566)
1 parent 2ea2be3 commit c0832fd

File tree

5 files changed

+52
-20
lines changed

5 files changed

+52
-20
lines changed

.changeset/silent-rocks-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: exclude `bind:this` from reactive state validation

packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2867,9 +2867,18 @@ export const template_visitors = {
28672867
BindDirective(node, context) {
28682868
const { state, path, visit } = context;
28692869
const expression = node.expression;
2870+
const property = binding_properties[node.name];
28702871

28712872
if (
28722873
expression.type === 'MemberExpression' &&
2874+
(node.name !== 'this' ||
2875+
path.some(
2876+
({ type }) =>
2877+
type === 'IfBlock' ||
2878+
type === 'EachBlock' ||
2879+
type === 'AwaitBlock' ||
2880+
type === 'KeyBlock'
2881+
)) &&
28732882
context.state.options.dev &&
28742883
context.state.analysis.runes
28752884
) {
@@ -2900,8 +2909,7 @@ export const template_visitors = {
29002909
/** @type {CallExpression} */
29012910
let call_expr;
29022911

2903-
const property = binding_properties[node.name];
2904-
if (property && property.event) {
2912+
if (property?.event) {
29052913
call_expr = b.call(
29062914
'$.bind_property',
29072915
b.literal(node.name),

packages/svelte/src/compiler/phases/bindings.js

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ export const binding_properties = {
1515
// media
1616
currentTime: {
1717
valid_elements: ['audio', 'video'],
18-
omit_in_ssr: true
18+
omit_in_ssr: true,
19+
bidirectional: true
1920
},
2021
duration: {
2122
valid_elements: ['audio', 'video'],
@@ -25,7 +26,8 @@ export const binding_properties = {
2526
focused: {},
2627
paused: {
2728
valid_elements: ['audio', 'video'],
28-
omit_in_ssr: true
29+
omit_in_ssr: true,
30+
bidirectional: true
2931
},
3032
buffered: {
3133
valid_elements: ['audio', 'video'],
@@ -41,15 +43,18 @@ export const binding_properties = {
4143
},
4244
volume: {
4345
valid_elements: ['audio', 'video'],
44-
omit_in_ssr: true
46+
omit_in_ssr: true,
47+
bidirectional: true
4548
},
4649
muted: {
4750
valid_elements: ['audio', 'video'],
48-
omit_in_ssr: true
51+
omit_in_ssr: true,
52+
bidirectional: true
4953
},
5054
playbackRate: {
5155
valid_elements: ['audio', 'video'],
52-
omit_in_ssr: true
56+
omit_in_ssr: true,
57+
bidirectional: true
5358
},
5459
seeking: {
5560
valid_elements: ['audio', 'video'],
@@ -124,11 +129,13 @@ export const binding_properties = {
124129
},
125130
scrollX: {
126131
valid_elements: ['svelte:window'],
127-
omit_in_ssr: true
132+
omit_in_ssr: true,
133+
bidirectional: true
128134
},
129135
scrollY: {
130136
valid_elements: ['svelte:window'],
131-
omit_in_ssr: true
137+
omit_in_ssr: true,
138+
bidirectional: true
132139
},
133140
online: {
134141
valid_elements: ['svelte:window'],
@@ -180,34 +187,41 @@ export const binding_properties = {
180187
omit_in_ssr: true // no corresponding attribute
181188
},
182189
checked: {
183-
valid_elements: ['input']
190+
valid_elements: ['input'],
191+
bidirectional: true
184192
},
185193
group: {
186-
valid_elements: ['input']
194+
valid_elements: ['input'],
195+
bidirectional: true
187196
},
188197
// various
189198
this: {
190199
omit_in_ssr: true
191200
},
192201
innerText: {
193-
invalid_elements: ['svelte:window', 'svelte:document']
202+
invalid_elements: ['svelte:window', 'svelte:document'],
203+
bidirectional: true
194204
},
195205
innerHTML: {
196-
invalid_elements: ['svelte:window', 'svelte:document']
206+
invalid_elements: ['svelte:window', 'svelte:document'],
207+
bidirectional: true
197208
},
198209
textContent: {
199-
invalid_elements: ['svelte:window', 'svelte:document']
210+
invalid_elements: ['svelte:window', 'svelte:document'],
211+
bidirectional: true
200212
},
201213
open: {
202214
event: 'toggle',
203215
bidirectional: true,
204216
valid_elements: ['details']
205217
},
206218
value: {
207-
valid_elements: ['input', 'textarea', 'select']
219+
valid_elements: ['input', 'textarea', 'select'],
220+
bidirectional: true
208221
},
209222
files: {
210223
valid_elements: ['input'],
211-
omit_in_ssr: true
224+
omit_in_ssr: true,
225+
bidirectional: true
212226
}
213227
};

packages/svelte/tests/runtime-runes/samples/binding-property-static/_config.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ export default test({
77

88
async test({ assert, warnings }) {
99
assert.deepEqual(warnings, [
10-
`\`bind:value={pojo.value}\` (main.svelte:50:7) is binding to a non-reactive property`,
11-
`\`bind:value={frozen.value}\` (main.svelte:51:7) is binding to a non-reactive property`,
12-
`\`bind:value={pojo.value}\` (main.svelte:52:7) is binding to a non-reactive property`,
13-
`\`bind:value={frozen.value}\` (main.svelte:53:7) is binding to a non-reactive property`
10+
'`bind:value={pojo.value}` (main.svelte:50:7) is binding to a non-reactive property',
11+
'`bind:value={frozen.value}` (main.svelte:51:7) is binding to a non-reactive property',
12+
'`bind:value={pojo.value}` (main.svelte:52:7) is binding to a non-reactive property',
13+
'`bind:value={frozen.value}` (main.svelte:53:7) is binding to a non-reactive property',
14+
'`bind:this={pojo.value}` (main.svelte:55:6) is binding to a non-reactive property'
1415
]);
1516
}
1617
});

packages/svelte/tests/runtime-runes/samples/binding-property-static/main.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
<input bind:value={frozen.value} />
5252
<Child bind:value={pojo.value} />
5353
<Child bind:value={frozen.value} />
54+
{#if value}
55+
<div bind:this={pojo.value}></div>
56+
{/if}
5457

5558
<!-- should not warn -->
5659
<input bind:value={reactive.value} />
@@ -59,3 +62,4 @@
5962
<Child bind:value={reactive.value} />
6063
<Child bind:value={accessors.value} />
6164
<Child bind:value={proxy.value} />
65+
<div bind:this={pojo.value}></div>

0 commit comments

Comments
 (0)