Skip to content

Commit f8c83c8

Browse files
committed
fix: don't hoist listeners that access non hoistable snippets
1 parent 74917ae commit f8c83c8

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

.changeset/thick-pans-fold.md

Lines changed: 5 additions & 0 deletions
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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** @import { ArrowFunctionExpression, Expression, FunctionDeclaration, FunctionExpression } from 'estree' */
22
/** @import { AST, DelegatedEvent } from '#compiler' */
33
/** @import { Context } from '../types' */
4+
import exp from 'node:constants';
45
import { cannot_be_set_statically, is_capture_event, is_delegated } from '../../../../utils.js';
56
import {
67
get_attribute_chunks,
@@ -183,6 +184,14 @@ function get_delegated_event(event_name, handler, context) {
183184
const binding = scope.get(reference);
184185
const local_binding = context.state.scope.get(reference);
185186

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;
Lines changed: 12 additions & 0 deletions
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+
});
Lines changed: 12 additions & 0 deletions
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)