Skip to content

Commit 484d8a8

Browse files
committed
fix: always synchronously call bind:this
fixes #12673 #12591 wrongfully applied the "wrap in effect if an action on this element" logic for `bind:this`
1 parent ccccac3 commit 484d8a8

File tree

4 files changed

+86
-24
lines changed

4 files changed

+86
-24
lines changed

.changeset/smooth-pens-exist.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: always synchronously call `bind:this`

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3164,16 +3164,15 @@ export const template_visitors = {
31643164
}
31653165

31663166
const parent = /** @type {import('#compiler').SvelteNode} */ (context.path.at(-1));
3167-
const has_action_directive =
3168-
parent.type === 'RegularElement' && parent.attributes.find((a) => a.type === 'UseDirective');
31693167

31703168
// Bindings need to happen after attribute updates, therefore after the render effect, and in order with events/actions.
31713169
// bind:this is a special case as it's one-way and could influence the render effect.
31723170
if (node.name === 'this') {
3173-
state.init.push(
3174-
b.stmt(has_action_directive ? b.call('$.effect', b.thunk(call_expr)) : call_expr)
3175-
);
3171+
state.init.push(b.stmt(call_expr));
31763172
} else {
3173+
const has_action_directive =
3174+
parent.type === 'RegularElement' &&
3175+
parent.attributes.find((a) => a.type === 'UseDirective');
31773176
state.after_update.push(
31783177
b.stmt(has_action_directive ? b.call('$.effect', b.thunk(call_expr)) : call_expr)
31793178
);

packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/_config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export default test({
2222
}
2323

2424
assert.deepEqual(value, [
25+
'bind:this true',
2526
'1',
2627
'2',
2728
'3',
Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,91 @@
11
<script>
2+
import { onMount } from 'svelte';
3+
24
export let value = [];
35
4-
function one(elem) { elem.addEventListener('input', () => { value.push('1'); }); }
5-
function four(elem) { elem.addEventListener('input', () => { value.push('4'); }); }
6-
function eight(elem) { elem.addEventListener('input', () => { value.push('8'); }); }
7-
function twelve(elem) { elem.addEventListener('input', () => { value.push('12'); }); }
8-
function fifteen(elem) { elem.addEventListener('input', () => { value.push('15'); }); }
9-
function seventeen(elem) { elem.addEventListener('input', () => { value.push('17'); }); }
6+
function one(elem) {
7+
elem.addEventListener('input', () => {
8+
value.push('1');
9+
});
10+
}
11+
function four(elem) {
12+
elem.addEventListener('input', () => {
13+
value.push('4');
14+
});
15+
}
16+
function eight(elem) {
17+
elem.addEventListener('input', () => {
18+
value.push('8');
19+
});
20+
}
21+
function twelve(elem) {
22+
elem.addEventListener('input', () => {
23+
value.push('12');
24+
});
25+
}
26+
function fifteen(elem) {
27+
elem.addEventListener('input', () => {
28+
value.push('15');
29+
});
30+
}
31+
function seventeen(elem) {
32+
elem.addEventListener('input', () => {
33+
value.push('17');
34+
});
35+
}
1036
1137
const foo = {
12-
set two(v) { value.push('2'); },
13-
set six(v) { value.push('6'); },
14-
set nine(v) { value.push('9'); },
15-
set eleven(v) { value.push('11'); },
16-
set thirteen(v) { value.push('13'); },
17-
set sixteen(v) { value.push('16'); },
38+
set two(v) {
39+
value.push('2');
40+
},
41+
set six(v) {
42+
value.push('6');
43+
},
44+
set nine(v) {
45+
value.push('9');
46+
},
47+
set eleven(v) {
48+
value.push('11');
49+
},
50+
set thirteen(v) {
51+
value.push('13');
52+
},
53+
set sixteen(v) {
54+
value.push('16');
55+
}
56+
};
57+
58+
function three() {
59+
value.push('3');
60+
}
61+
function five() {
62+
value.push('5');
63+
}
64+
function seven() {
65+
value.push('7');
66+
}
67+
function ten() {
68+
value.push('10');
69+
}
70+
function fourteen() {
71+
value.push('14');
72+
}
73+
function eighteen() {
74+
value.push('18');
1875
}
1976
20-
function three() { value.push('3'); }
21-
function five() { value.push('5'); }
22-
function seven() { value.push('7'); }
23-
function ten() { value.push('10'); }
24-
function fourteen() { value.push('14'); }
25-
function eighteen() { value.push('18'); }
77+
let el;
2678
79+
onMount(() => {
80+
// ensure that bind:this doesn't influence the order of directives
81+
// and isn't affected itself by an action being on the element
82+
value.push('bind:this ' + !!el);
83+
});
2784
</script>
2885

2986
<input use:one bind:value={foo.two} on:input={three} />
3087
<input use:four on:input={five} bind:value={foo.six} />
3188
<input on:input={seven} use:eight bind:value={foo.nine} />
3289
<input on:input={ten} bind:value={foo.eleven} use:twelve />
3390
<input bind:value={foo.thirteen} on:input={fourteen} use:fifteen />
34-
<input bind:value={foo.sixteen} use:seventeen on:input={eighteen} />
91+
<input bind:this={el} bind:value={foo.sixteen} use:seventeen on:input={eighteen} />

0 commit comments

Comments
 (0)