From 141e3e9f928641175ba02310997aa5c6dee057c0 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Tue, 16 Jul 2024 01:06:11 +0200 Subject: [PATCH] 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 --- .changeset/perfect-hats-dance.md | 5 +++++ packages/svelte/src/compiler/phases/3-transform/utils.js | 6 +++++- .../samples/component-dont-fuse-whitespace/Child.svelte | 5 +++++ .../samples/component-dont-fuse-whitespace/_config.js | 5 +++++ .../samples/component-dont-fuse-whitespace/main.svelte | 6 ++++++ .../_expected/client/index.svelte.js | 2 ++ .../_expected/server/index.svelte.js | 2 +- 7 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 .changeset/perfect-hats-dance.md create mode 100644 packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/Child.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/main.svelte diff --git a/.changeset/perfect-hats-dance.md b/.changeset/perfect-hats-dance.md new file mode 100644 index 0000000000..93cc4a14cf --- /dev/null +++ b/.changeset/perfect-hats-dance.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: prevent whitespaces merging across component boundaries diff --git a/packages/svelte/src/compiler/phases/3-transform/utils.js b/packages/svelte/src/compiler/phases/3-transform/utils.js index c396c5d753..d55c481f1f 100644 --- a/packages/svelte/src/compiler/phases/3-transform/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/utils.js @@ -288,7 +288,11 @@ export function clean_nodes( ))), /** 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 */ is_text_first: - (parent.type === 'Fragment' || parent.type === 'SnippetBlock') && + (parent.type === 'Fragment' || + parent.type === 'SnippetBlock' || + parent.type === 'SvelteComponent' || + parent.type === 'Component' || + parent.type === 'SvelteSelf') && first && (first?.type === 'Text' || first?.type === 'ExpressionTag') }; diff --git a/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/Child.svelte b/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/Child.svelte new file mode 100644 index 0000000000..e3e1a7ef6a --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/Child.svelte @@ -0,0 +1,5 @@ + + +

text before the render tag {@render children()}

diff --git a/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/_config.js b/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/_config.js new file mode 100644 index 0000000000..e362f4469a --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +export default test({ + html: `

text before the render tag dont fuse this text with the one from the child

` +}); diff --git a/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/main.svelte b/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/main.svelte new file mode 100644 index 0000000000..39e6d22c06 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/component-dont-fuse-whitespace/main.svelte @@ -0,0 +1,6 @@ + + +{text} diff --git a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js index 0515f1aa33..af1f6c4634 100644 --- a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js @@ -15,6 +15,8 @@ export default function Function_prop_no_getter($$anchor) { onmouseup, onmouseenter: () => $.set(count, $.proxy(plusOne($.get(count)))), children: ($$anchor, $$slotProps) => { + $.next(); + var text = $.text(); $.template_effect(() => $.set_text(text, `clicks: ${$.get(count) ?? ""}`)); diff --git a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/server/index.svelte.js index 8f90eaca2e..661c34a48d 100644 --- a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/server/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/server/index.svelte.js @@ -14,7 +14,7 @@ export default function Function_prop_no_getter($$payload) { onmouseup, onmouseenter: () => count = plusOne(count), children: ($$payload, $$slotProps) => { - $$payload.out += `clicks: ${$.escape(count)}`; + $$payload.out += `clicks: ${$.escape(count)}`; }, $$slots: { default: true } });