Skip to content

Commit 5998481

Browse files
committed
fix: dynamic event delegation for stateful call expressions
1 parent 0891fa7 commit 5998481

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

.changeset/brown-moons-sleep.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: dynamic event delegation for stateful call expressions

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,8 +1143,19 @@ function serialize_event_handler(node, { state, visit }) {
11431143
])
11441144
);
11451145

1146-
if (handler.type === 'Identifier' || handler.type === 'MemberExpression') {
1147-
const id = object(handler);
1146+
if (
1147+
handler.type === 'Identifier' ||
1148+
handler.type === 'MemberExpression' ||
1149+
(handler.type === 'CallExpression' &&
1150+
(handler.callee.type === 'Identifier' || handler.callee.type === 'MemberExpression'))
1151+
) {
1152+
const id = object(
1153+
handler.type === 'CallExpression'
1154+
? /** @type {import("estree").Identifier | import("estree").MemberExpression} */ (
1155+
handler.callee
1156+
)
1157+
: handler
1158+
);
11481159
const binding = id === null ? null : state.scope.get(id.name);
11491160
if (
11501161
binding !== null &&
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { flushSync } from 'svelte';
2+
import { test, ok } from '../../test';
3+
4+
export default test({
5+
mode: ['client'],
6+
async test({ assert, target, logs }) {
7+
const [btn1, btn2, btn3] = target.querySelectorAll('button');
8+
9+
flushSync(() => {
10+
btn1.click();
11+
btn2.click();
12+
});
13+
14+
assert.deepEqual(logs, ['AA', 'AB']);
15+
16+
flushSync(() => {
17+
btn3.click();
18+
btn1.click();
19+
btn2.click();
20+
});
21+
22+
assert.deepEqual(logs, ['AA', 'AB', 'BA', 'BB']);
23+
}
24+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
let hof = $state((name) => () => console.log('A' + name));
3+
4+
const member = $derived({
5+
hof
6+
});
7+
8+
function change() {
9+
hof = (name) => () => console.log('B' + name);
10+
}
11+
</script>
12+
13+
<button onclick={hof('A')}>A</button>
14+
<button onclick={member.hof('B')}>B</button>
15+
16+
<br />
17+
<button onclick={change}>change</button>

0 commit comments

Comments
 (0)