fix: ensure dynamic event handlers are wrapped in a derived

pull/12563/head
Dominic Gannaway 2 years ago
parent 7b2279d84c
commit b49cd79bc4

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure dynamic event handlers are wrapped in a derived

@ -1132,20 +1132,27 @@ function serialize_event_handler(node, { state, visit }) {
handler = node.expression;
// Event handlers can be dynamic (source/store/prop/conditional etc)
const dynamic_handler = () =>
b.function(
const dynamic_handler = () => {
const id = b.id(state.scope.generate('event_handler'));
state.init.push(
b.var(id, b.call('$.derived', b.thunk(/** @type {Expression} */ (visit(handler)))))
);
return b.function(
null,
[b.rest(b.id('$$args'))],
b.block([
b.return(
b.call(
b.member(/** @type {Expression} */ (visit(handler)), b.id('apply'), false, true),
b.member(b.call('$.get', id), b.id('apply'), false, true),
b.this,
b.id('$$args')
)
)
])
);
};
if (handler.type === 'Identifier' || handler.type === 'MemberExpression') {
const id = object(handler);

@ -0,0 +1,15 @@
import { test } from '../../test';
export default test({
html: '<button>Click</button>',
test({ assert, logs, target }) {
const button = target.querySelector('button');
button?.click();
button?.click();
button?.click();
assert.deepEqual(logs, ['create', 'trigger', 'trigger', 'trigger']);
}
});

@ -0,0 +1,9 @@
<script>
let makeHandler = null;
makeHandler = () => {
console.log('create');
return () => console.log('trigger');
};
</script>
<button on:click={makeHandler()}>Click</button>
Loading…
Cancel
Save