Skip to content

Commit f5c813e

Browse files
dummdidummtrueadm
authored andcommitted
fix: prevent whitespaces merging across component boundaries (#12449)
* fix: prevent whitespaces merging across component boundaries The logic that was there didn't take components into account. The underlying problem is that the parent isn't properly set to `Fragment` in all cases because of nested `visit` calls we do in some places. Fixes #12447 * update test
1 parent 89fea31 commit f5c813e

File tree

7 files changed

+29
-2
lines changed

7 files changed

+29
-2
lines changed

.changeset/perfect-hats-dance.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: prevent whitespaces merging across component boundaries

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,11 @@ export function clean_nodes(
288288
))),
289289
/** if a component or snippet starts with text, we need to add an anchor comment so that its text node doesn't get fused with its surroundings */
290290
is_text_first:
291-
(parent.type === 'Fragment' || parent.type === 'SnippetBlock') &&
291+
(parent.type === 'Fragment' ||
292+
parent.type === 'SnippetBlock' ||
293+
parent.type === 'SvelteComponent' ||
294+
parent.type === 'Component' ||
295+
parent.type === 'SvelteSelf') &&
292296
first &&
293297
(first?.type === 'Text' || first?.type === 'ExpressionTag')
294298
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
const { children } = $props();
3+
</script>
4+
5+
<p>text before the render tag {@render children()}</p>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
html: `<p>text before the render tag dont fuse this text with the one from the child</p>`
5+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
import Child from './Child.svelte';
3+
let text = $state('dont fuse this text with the one from the child');
4+
</script>
5+
6+
<Child>{text}</Child>

packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export default function Function_prop_no_getter($$anchor) {
1515
onmouseup,
1616
onmouseenter: () => $.set(count, $.proxy(plusOne($.get(count)))),
1717
children: ($$anchor, $$slotProps) => {
18+
$.next();
19+
1820
var text = $.text();
1921

2022
$.template_effect(() => $.set_text(text, `clicks: ${$.get(count) ?? ""}`));

packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/server/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function Function_prop_no_getter($$payload) {
1414
onmouseup,
1515
onmouseenter: () => count = plusOne(count),
1616
children: ($$payload, $$slotProps) => {
17-
$$payload.out += `clicks: ${$.escape(count)}`;
17+
$$payload.out += `<!---->clicks: ${$.escape(count)}`;
1818
},
1919
$$slots: { default: true }
2020
});

0 commit comments

Comments
 (0)