diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 8c2738a40c..682c7add46 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -1682,16 +1682,18 @@ export const template_visitors = { process_children(trimmed, expression, false, { ...context, state }); - let flags = TEMPLATE_FRAGMENT; - - if (state.metadata.context.template_needs_import_node) { - flags |= TEMPLATE_USE_IMPORT_NODE; - } - + /** + * If the first item in an effect is a static slot or render tag, it will clone + * a template but without creating a child effect. In these cases, we need to keep + * the current `effect.nodes.start` undefined, so that it can be populated by + * the item in question + * TODO come up with a better name than `unset` + */ + var unset = false; var first = trimmed[0]; if (first.type === 'SlotElement') { - flags |= TEMPLATE_UNSET_START; + unset = true; } if (first.type === 'Component') { @@ -1700,7 +1702,7 @@ export const template_visitors = { first.name.includes('.') ? first.name.slice(0, first.name.indexOf('.')) : first.name ); if (binding === null || binding.kind === 'normal') { - flags |= TEMPLATE_UNSET_START; + unset = true; } } @@ -1710,7 +1712,7 @@ export const template_visitors = { callee.type !== 'Identifier' || context.state.scope.get(callee.name)?.kind !== 'normal'; if (!is_reactive) { - flags |= TEMPLATE_UNSET_START; + unset = true; } } @@ -1718,8 +1720,18 @@ export const template_visitors = { if (use_comment_template) { // special case — we can use `$.comment` instead of creating a unique template - body.push(b.var(id, b.call('$.comment', flags !== 0 && b.literal(flags)))); + body.push(b.var(id, b.call('$.comment', unset && b.literal(unset)))); } else { + let flags = TEMPLATE_FRAGMENT; + + if (unset) { + flags |= TEMPLATE_UNSET_START; + } + + if (state.metadata.context.template_needs_import_node) { + flags |= TEMPLATE_USE_IMPORT_NODE; + } + add_template(template_name, [ b.template([b.quasi(state.template.join(''), true)], []), b.literal(flags) diff --git a/packages/svelte/src/internal/client/dom/template.js b/packages/svelte/src/internal/client/dom/template.js index 1cacbba53d..5247385241 100644 --- a/packages/svelte/src/internal/client/dom/template.js +++ b/packages/svelte/src/internal/client/dom/template.js @@ -238,9 +238,9 @@ export function text(anchor) { } /** - * @param {number} [flags] + * @param {boolean} unset */ -export function comment(flags = 0) { +export function comment(unset = false) { // we're not delegating to `template` here for performance reasons if (hydrating) { assign_nodes(get_start(), hydrate_nodes[hydrate_nodes.length - 1]); @@ -252,7 +252,7 @@ export function comment(flags = 0) { var anchor = empty(); frag.append(anchor); - assign_nodes((flags & TEMPLATE_UNSET_START) !== 0 ? undefined : null, anchor, anchor); + assign_nodes(unset ? undefined : null, anchor, anchor); return frag; } diff --git a/packages/svelte/tests/snapshot/samples/bind-this/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-this/_expected/client/index.svelte.js index 81a6af8b07..c1f5a2a309 100644 --- a/packages/svelte/tests/snapshot/samples/bind-this/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/bind-this/_expected/client/index.svelte.js @@ -2,7 +2,7 @@ import "svelte/internal/disclose-version"; import * as $ from "svelte/internal/client"; export default function Bind_this($$anchor) { - var fragment = $.comment(5); + var fragment = $.comment(true); var node = $.first_child(fragment); $.bind_this(Foo(node, { $$legacy: true }), ($$value) => foo = $$value, () => foo); 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 53b05995fa..5d5e47faf2 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 @@ -2,7 +2,7 @@ import "svelte/internal/disclose-version"; import * as $ from "svelte/internal/client"; export default function Each_string_template($$anchor) { - var fragment = $.comment(1); + var fragment = $.comment(); var node = $.first_child(fragment); $.each(node, 1, () => ['foo', 'bar', 'baz'], $.index, ($$anchor, thing, $$index) => { 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 1d983f34d0..2cf005abdf 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 @@ -9,7 +9,7 @@ export default function Function_prop_no_getter($$anchor) { } const plusOne = (num) => num + 1; - var fragment = $.comment(5); + var fragment = $.comment(true); var node = $.first_child(fragment); Button(node, { diff --git a/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js index 9c1fc48d06..a4bbea582b 100644 --- a/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js @@ -3,7 +3,7 @@ import * as $ from "svelte/internal/client"; export default function Svelte_element($$anchor, $$props) { let tag = $.prop($$props, "tag", 3, 'hr'); - var fragment = $.comment(1); + var fragment = $.comment(); var node = $.first_child(fragment); $.element(node, tag, false);