fix: attach event handlers that are assigned after a top-level `await` in production (#18933)

Fixes #18932
pull/18821/merge
jarrednorris 14 hours ago committed by GitHub
parent 14136f88fc
commit 79a0c0d4d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: attach event handlers that are assigned after a top-level `await` in production

@ -119,8 +119,9 @@ export function build_event_handler(node, metadata, context) {
// local variable can be assigned directly
// except in dev mode where when need $.apply()
// in order to handle warnings.
if (!dev && binding?.declaration_kind !== 'import') {
// in order to handle warnings, or when it is
// assigned after a top-level `await`
if (!dev && binding?.declaration_kind !== 'import' && !binding?.blocker) {
return handler;
}
}

@ -0,0 +1,19 @@
import { tick } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['client', 'hydrate'],
async test({ assert, target, window, logs }) {
await new Promise((r) => setTimeout(r));
await tick();
const button = target.querySelector('button');
const div = target.querySelector('div');
button?.click();
div?.dispatchEvent(new window.MouseEvent('mouseenter'));
window.dispatchEvent(new window.Event('resize'));
assert.deepEqual(logs, ['click', 'mouseenter', 'resize']);
}
});

@ -0,0 +1,19 @@
<script>
// Wait a macrotask to make sure the handlers aren't read before the microtask-Promise.resolve() resolves, masking a bug
await new Promise((r) => setTimeout(r));
function create_handler(name) {
return () => {
console.log(name);
};
}
const onclick = create_handler('click');
const onmouseenter = create_handler('mouseenter');
const onresize = create_handler('resize');
</script>
<svelte:window {onresize} />
<button {onclick}>click</button>
<div {onmouseenter}>hover</div>
Loading…
Cancel
Save