From 0203eb319b5d86138236158e3ae6ecf29e26864c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 29 Aug 2024 21:04:42 -0400 Subject: [PATCH] fix: insert comment before text in an each block, to prevent glued nodes (#13073) --- .changeset/orange-sheep-exist.md | 5 +++++ packages/svelte/src/compiler/phases/3-transform/utils.js | 3 ++- .../hydration/samples/each-preserve-whitespace/main.svelte | 5 +++++ .../tests/hydration/samples/each-text-only/main.svelte | 3 +++ .../each-string-template/_expected/client/index.svelte.js | 2 ++ .../each-string-template/_expected/server/index.svelte.js | 2 +- 6 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 .changeset/orange-sheep-exist.md create mode 100644 packages/svelte/tests/hydration/samples/each-preserve-whitespace/main.svelte create mode 100644 packages/svelte/tests/hydration/samples/each-text-only/main.svelte diff --git a/.changeset/orange-sheep-exist.md b/.changeset/orange-sheep-exist.md new file mode 100644 index 0000000000..fe10bb0132 --- /dev/null +++ b/.changeset/orange-sheep-exist.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: insert comment before text in an each block, to prevent glued nodes diff --git a/packages/svelte/src/compiler/phases/3-transform/utils.js b/packages/svelte/src/compiler/phases/3-transform/utils.js index d8b1bb9c5e..a1cefe90d8 100644 --- a/packages/svelte/src/compiler/phases/3-transform/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/utils.js @@ -287,10 +287,11 @@ export function clean_nodes( !first.attributes.some( (attribute) => attribute.type === 'Attribute' && attribute.name.startsWith('--') ))), - /** 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 */ + /** if a component/snippet/each block 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 === 'EachBlock' || parent.type === 'SvelteComponent' || parent.type === 'Component' || parent.type === 'SvelteSelf') && diff --git a/packages/svelte/tests/hydration/samples/each-preserve-whitespace/main.svelte b/packages/svelte/tests/hydration/samples/each-preserve-whitespace/main.svelte new file mode 100644 index 0000000000..1e70605d16 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/each-preserve-whitespace/main.svelte @@ -0,0 +1,5 @@ + + +{#each 'abc' as l} +
{l}
+{/each} diff --git a/packages/svelte/tests/hydration/samples/each-text-only/main.svelte b/packages/svelte/tests/hydration/samples/each-text-only/main.svelte new file mode 100644 index 0000000000..bb7d7b45cb --- /dev/null +++ b/packages/svelte/tests/hydration/samples/each-text-only/main.svelte @@ -0,0 +1,3 @@ +{#each 'abc' as l} + {l} +{/each} diff --git a/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client/index.svelte.js index 8152445ec3..81c06f23ec 100644 --- a/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client/index.svelte.js @@ -6,6 +6,8 @@ export default function Each_string_template($$anchor) { var node = $.first_child(fragment); $.each(node, 0, () => ['foo', 'bar', 'baz'], $.index, ($$anchor, thing) => { + $.next(); + var text = $.text(); $.template_effect(() => $.set_text(text, `${thing ?? ""}, `)); diff --git a/packages/svelte/tests/snapshot/samples/each-string-template/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/each-string-template/_expected/server/index.svelte.js index bb6b737b8e..577152729b 100644 --- a/packages/svelte/tests/snapshot/samples/each-string-template/_expected/server/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/each-string-template/_expected/server/index.svelte.js @@ -8,7 +8,7 @@ export default function Each_string_template($$payload) { for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) { const thing = each_array[$$index]; - $$payload.out += `${$.escape(thing)}, `; + $$payload.out += `${$.escape(thing)}, `; } $$payload.out += ``;