Skip to content

Commit 5b9f0df

Browse files
fix: don't hoist listeners that access non hoistable snippets (#15534)
* fix: don't hoist listeners that access non hoistable snippets * chore: add comment * chore: fix auto import fumble
1 parent 74917ae commit 5b9f0df

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

.changeset/thick-pans-fold.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: don't hoist listeners that access non hoistable snippets

packages/svelte/src/compiler/phases/2-analyze/visitors/Attribute.js

+9
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,15 @@ function get_delegated_event(event_name, handler, context) {
183183
const binding = scope.get(reference);
184184
const local_binding = context.state.scope.get(reference);
185185

186+
// if the function access a snippet that can't be hoisted we bail out
187+
if (
188+
local_binding !== null &&
189+
local_binding.initial?.type === 'SnippetBlock' &&
190+
!local_binding.initial.metadata.can_hoist
191+
) {
192+
return unhoisted;
193+
}
194+
186195
// If we are referencing a binding that is shadowed in another scope then bail out.
187196
if (local_binding !== null && binding !== null && local_binding.node !== binding.node) {
188197
return unhoisted;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target, errors }) {
6+
const button = target.querySelector('button');
7+
flushSync(() => {
8+
button?.click();
9+
});
10+
assert.deepEqual(errors, []);
11+
}
12+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script>
2+
const log = () => {
3+
console.log(snip);
4+
}
5+
let x = $state(0);
6+
</script>
7+
8+
<button onclick={log}></button>
9+
10+
{#snippet snip()}
11+
snippet {x}
12+
{/snippet}

0 commit comments

Comments
 (0)