fix: ensure event handlers referencing $host are not hoisted (#12775)

safari-borking-2
Dominic Gannaway 3 months ago committed by GitHub
parent 9ff33f1346
commit c32a91891f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure event handlers referencing $host are not hoisted

@ -155,8 +155,8 @@ function get_delegated_event(event_name, handler, context) {
const visited_references = new Set(); const visited_references = new Set();
const scope = target_function.metadata.scope; const scope = target_function.metadata.scope;
for (const [reference] of scope.references) { for (const [reference] of scope.references) {
// Bail out if the arguments keyword is used // Bail out if the arguments keyword is used or $host is referenced
if (reference === 'arguments') return unhoisted; if (reference === 'arguments' || reference === '$host') return unhoisted;
// Bail out if references a store subscription // Bail out if references a store subscription
if (scope.get(`$${reference}`)?.kind === 'store_sub') return unhoisted; if (scope.get(`$${reference}`)?.kind === 'store_sub') return unhoisted;

@ -14,11 +14,13 @@ export default test({
await tick(); await tick();
el.shadowRoot.querySelector('button').click(); el.shadowRoot.querySelectorAll('button')[0].click();
assert.deepEqual(events, ['greeting', 'hello']); el.shadowRoot.querySelectorAll('button')[1].click();
assert.deepEqual(events, ['greeting', 'hello', 'greeting', 'welcome']);
el.removeEventListener('greeting', handle_evt); el.removeEventListener('greeting', handle_evt);
el.shadowRoot.querySelector('button').click(); el.shadowRoot.querySelectorAll('button')[0].click();
assert.deepEqual(events, ['greeting', 'hello']); el.shadowRoot.querySelectorAll('button')[1].click();
assert.deepEqual(events, ['greeting', 'hello', 'greeting', 'welcome']);
} }
}); });

@ -4,6 +4,11 @@
function greet(greeting) { function greet(greeting) {
$host().dispatchEvent(new CustomEvent('greeting', { detail: greeting })) $host().dispatchEvent(new CustomEvent('greeting', { detail: greeting }))
} }
function welcome() {
$host().dispatchEvent(new CustomEvent('greeting', { detail: 'welcome' }))
}
</script> </script>
<button onclick={() => greet('hello')}>say hello</button> <button onclick={() => greet('hello')}>say hello</button>
<button onclick={welcome}>say welcome</button>

Loading…
Cancel
Save