Skip to content

Commit 2416587

Browse files
authored
fix: ensure implicit children snippet renders correctly (#9706)
place anchors around render tags, not snippet tags fixes #9678
1 parent bde42d5 commit 2416587

File tree

5 files changed

+53
-13
lines changed

5 files changed

+53
-13
lines changed

.changeset/famous-knives-sneeze.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: ensure implicit children snippet renders correctly

packages/svelte/src/compiler/phases/3-transform/server/transform-server.js

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,11 +1125,17 @@ const template_visitors = {
11251125
);
11261126
},
11271127
RenderTag(node, context) {
1128-
const snippet_function = context.state.options.dev
1128+
const state = context.state;
1129+
const [anchor, anchor_id] = serialize_anchor(state);
1130+
1131+
state.init.push(anchor);
1132+
state.template.push(t_expression(anchor_id));
1133+
1134+
const snippet_function = state.options.dev
11291135
? b.call('$.validate_snippet', node.expression)
11301136
: node.expression;
11311137
if (node.argument) {
1132-
context.state.template.push(
1138+
state.template.push(
11331139
t_statement(
11341140
b.stmt(
11351141
b.call(
@@ -1141,8 +1147,10 @@ const template_visitors = {
11411147
)
11421148
);
11431149
} else {
1144-
context.state.template.push(t_statement(b.stmt(b.call(snippet_function, b.id('$$payload')))));
1150+
state.template.push(t_statement(b.stmt(b.call(snippet_function, b.id('$$payload')))));
11451151
}
1152+
1153+
state.template.push(t_expression(anchor_id));
11461154
},
11471155
ClassDirective(node) {
11481156
error(node, 'INTERNAL', 'Node should have been handled elsewhere');
@@ -1435,27 +1443,18 @@ const template_visitors = {
14351443
state.template.push(t_expression(id));
14361444
},
14371445
SnippetBlock(node, context) {
1438-
const [dec, id] = serialize_anchor(context.state);
1439-
14401446
// TODO hoist where possible
14411447
/** @type {import('estree').Pattern[]} */
14421448
const args = [b.id('$$payload')];
14431449
if (node.context) {
14441450
args.push(node.context);
14451451
}
14461452

1447-
const out = b.member_id('$$payload.out');
1448-
14491453
context.state.init.push(
14501454
b.function_declaration(
14511455
node.expression,
14521456
args,
1453-
b.block([
1454-
dec,
1455-
b.stmt(b.assignment('+=', out, id)),
1456-
.../** @type {import('estree').BlockStatement} */ (context.visit(node.body)).body,
1457-
b.stmt(b.assignment('+=', out, id))
1458-
])
1457+
/** @type {import('estree').BlockStatement} */ (context.visit(node.body))
14591458
)
14601459
);
14611460
if (context.state.options.dev) {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
const { children, change } = $props();
3+
</script>
4+
5+
<button onclick={change}>
6+
{@render children()}
7+
</button>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
html: `<button><span>hidden</span></button>`,
6+
7+
async test({ assert, target }) {
8+
const [b1] = target.querySelectorAll('button');
9+
10+
flushSync(() => {
11+
b1?.click();
12+
});
13+
14+
assert.htmlEqual(target.innerHTML, `<button><span>showing</span></button>`);
15+
}
16+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
import Button from "./Button.svelte";
3+
4+
let show = $state(false);
5+
</script>
6+
7+
<Button change={() => show = true}>
8+
{#if show}
9+
<span>showing</span>
10+
{:else}
11+
<span>hidden</span>
12+
{/if}
13+
</Button>

0 commit comments

Comments
 (0)