fix: improve dynamic event handling (#12570)

pull/12552/head
Dominic Gannaway 5 months ago committed by GitHub
parent d17755a8b5
commit 64e9f0e5f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1148,25 +1148,7 @@ function serialize_event_handler(node, metadata, { state, visit }) {
])
);
if (handler.type === 'Identifier' || handler.type === 'MemberExpression') {
const id = object(handler);
const binding = id === null ? null : state.scope.get(id.name);
if (
binding !== null &&
(binding.kind === 'state' ||
binding.kind === 'frozen_state' ||
binding.declaration_kind === 'import' ||
binding.kind === 'legacy_reactive' ||
binding.kind === 'derived' ||
binding.kind === 'prop' ||
binding.kind === 'bindable_prop' ||
binding.kind === 'store_sub')
) {
handler = dynamic_handler();
} else {
handler = /** @type {Expression} */ (visit(handler));
}
} else if (
metadata?.contains_call_expression &&
!(
(handler.type === 'ArrowFunctionExpression' || handler.type === 'FunctionExpression') &&
@ -1193,6 +1175,24 @@ function serialize_event_handler(node, metadata, { state, visit }) {
)
])
);
} else if (handler.type === 'Identifier' || handler.type === 'MemberExpression') {
const id = object(handler);
const binding = id === null ? null : state.scope.get(id.name);
if (
binding !== null &&
(binding.kind === 'state' ||
binding.kind === 'frozen_state' ||
binding.declaration_kind === 'import' ||
binding.kind === 'legacy_reactive' ||
binding.kind === 'derived' ||
binding.kind === 'prop' ||
binding.kind === 'bindable_prop' ||
binding.kind === 'store_sub')
) {
handler = dynamic_handler();
} else {
handler = /** @type {Expression} */ (visit(handler));
}
} else if (handler.type === 'ConditionalExpression' || handler.type === 'LogicalExpression') {
handler = dynamic_handler();
} else {

@ -0,0 +1,26 @@
import { test } from '../../test';
export default test({
html: '<button>Tama</button><button>Pochi</button><br><button>Change Function</button>',
test({ assert, logs, target }) {
const [b1, b2, b3] = target.querySelectorAll('button');
b1?.click();
b2?.click();
b3?.click();
b1?.click();
b2?.click();
assert.deepEqual(logs, [
'creating "Hello" handler for Tama',
'Hello Tama',
'creating "Hello" handler for Pochi',
'Hello Pochi',
'creating "Bye" handler for Tama',
'Bye Tama',
'creating "Bye" handler for Pochi',
'Bye Pochi'
]);
}
});

@ -0,0 +1,19 @@
<script>
let saySomething = $state(name => {
console.log('creating "Hello" handler for ' + name);
return { handler: () => console.log('Hello ' + name) };
});
function change() {
saySomething = name => {
console.log('creating "Bye" handler for ' + name);
return { handler: () => console.log('Bye ' + name) };
}
}
</script>
<button onclick={saySomething('Tama').handler}>Tama</button>
<button onclick={saySomething('Pochi').handler}>Pochi</button>
<br>
<button onclick={change}>Change Function</button>
Loading…
Cancel
Save