diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/SvelteBoundary.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/SvelteBoundary.js index 7e96ed8a41..35af96ba12 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/SvelteBoundary.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/SvelteBoundary.js @@ -14,10 +14,6 @@ export function SvelteBoundary(node, context) { e.svelte_boundary_invalid_attribute(attribute); } - if (attribute.name === 'pending') { - node.metadata.pending = attribute; - } - if ( attribute.value === true || (Array.isArray(attribute.value) && @@ -27,12 +23,5 @@ export function SvelteBoundary(node, context) { } } - node.metadata.pending ??= - /** @type {AST.SnippetBlock | undefined} */ ( - node.fragment.nodes.find( - (node) => node.type === 'SnippetBlock' && node.expression.name === 'pending' - ) - ) ?? null; - context.next(); } diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/EachBlock.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/EachBlock.js index a060fdf6b4..7878ccf23a 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/EachBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/EachBlock.js @@ -1,9 +1,8 @@ /** @import { BlockStatement, Expression, Statement } from 'estree' */ /** @import { AST } from '#compiler' */ /** @import { ComponentContext } from '../types.js' */ -import { BLOCK_OPEN_ELSE } from '../../../../../internal/server/hydration.js'; import * as b from '#compiler/builders'; -import { block_close, block_open } from './shared/utils.js'; +import { block_close, block_open, block_open_else } from './shared/utils.js'; /** * @param {AST.EachBlock} node @@ -49,7 +48,7 @@ export function EachBlock(node, context) { const fallback = /** @type {BlockStatement} */ (context.visit(node.fallback)); fallback.body.unshift( - b.stmt(b.call(b.member(b.id('$$payload'), b.id('push')), b.literal(BLOCK_OPEN_ELSE))) + b.stmt(b.call(b.member(b.id('$$payload'), b.id('push')), block_open_else)) ); state.template.push( diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/IfBlock.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/IfBlock.js index ad2058a34e..2ebf74a8e0 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/IfBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/IfBlock.js @@ -1,9 +1,8 @@ /** @import { BlockStatement, Expression } from 'estree' */ /** @import { AST } from '#compiler' */ /** @import { ComponentContext } from '../types.js' */ -import { BLOCK_OPEN_ELSE } from '../../../../../internal/server/hydration.js'; import * as b from '#compiler/builders'; -import { block_close, block_open } from './shared/utils.js'; +import { block_close, block_open, block_open_else } from './shared/utils.js'; /** * @param {AST.IfBlock} node @@ -20,7 +19,7 @@ export function IfBlock(node, context) { consequent.body.unshift(b.stmt(b.call(b.member(b.id('$$payload'), b.id('push')), block_open))); alternate.body.unshift( - b.stmt(b.call(b.member(b.id('$$payload'), b.id('push')), b.literal(BLOCK_OPEN_ELSE))) + b.stmt(b.call(b.member(b.id('$$payload'), b.id('push')), block_open_else)) ); context.state.template.push(b.if(test, consequent, alternate), block_close); diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js index 69dbc5a530..355b33aea7 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js @@ -1,36 +1,36 @@ /** @import { BlockStatement } from 'estree' */ /** @import { AST } from '#compiler' */ /** @import { ComponentContext } from '../types' */ -import { - BLOCK_CLOSE, - BLOCK_OPEN, - BLOCK_OPEN_ELSE -} from '../../../../../internal/server/hydration.js'; import * as b from '#compiler/builders'; -import { build_attribute_value } from './shared/utils.js'; +import { block_close, block_open, block_open_else, build_attribute_value } from './shared/utils.js'; /** * @param {AST.SvelteBoundary} node * @param {ComponentContext} context */ export function SvelteBoundary(node, context) { - const pending_snippet = node.metadata.pending; + // if this has a `pending` snippet, render it + const pending_attribute = /** @type {AST.Attribute} */ ( + node.attributes.find((node) => node.type === 'Attribute' && node.name === 'pending') + ); - if (pending_snippet) { - context.state.template.push(b.literal(BLOCK_OPEN_ELSE)); + const pending_snippet = /** @type {AST.SnippetBlock} */ ( + node.fragment.nodes.find( + (node) => node.type === 'SnippetBlock' && node.expression.name === 'pending' + ) + ); - if (pending_snippet.type === 'Attribute') { - const value = build_attribute_value(pending_snippet.value, context, false, true); - context.state.template.push(b.call(value, b.id('$$payload'))); - } else if (pending_snippet.type === 'SnippetBlock') { - context.state.template.push( - /** @type {BlockStatement} */ (context.visit(pending_snippet.body)) - ); - } + if (pending_attribute || pending_snippet) { + const pending = pending_attribute + ? b.call( + build_attribute_value(pending_attribute.value, context, false, true), + b.id('$$payload') + ) + : /** @type {BlockStatement} */ (context.visit(pending_snippet.body)); + + context.state.template.push(block_open_else, pending, block_close); } else { - context.state.template.push(b.literal(BLOCK_OPEN)); - context.state.template.push(/** @type {BlockStatement} */ (context.visit(node.fragment))); + const block = /** @type {BlockStatement} */ (context.visit(node.fragment)); + context.state.template.push(block_open, block, block_close); } - - context.state.template.push(b.literal(BLOCK_CLOSE)); } diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js index dd754900be..db708b7a6b 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js @@ -6,6 +6,7 @@ import { escape_html } from '../../../../../../escaping.js'; import { BLOCK_CLOSE, BLOCK_OPEN, + BLOCK_OPEN_ELSE, EMPTY_COMMENT } from '../../../../../../internal/server/hydration.js'; import * as b from '#compiler/builders'; @@ -16,6 +17,9 @@ import { has_await } from '../../../../../utils/ast.js'; /** Opens an if/each block, so that we can remove nodes in the case of a mismatch */ export const block_open = b.literal(BLOCK_OPEN); +/** Opens an if/each block, so that we can remove nodes in the case of a mismatch */ +export const block_open_else = b.literal(BLOCK_OPEN_ELSE); + /** Closes an if/each block, so that we can remove nodes in the case of a mismatch. Also serves as an anchor for these blocks */ export const block_close = b.literal(BLOCK_CLOSE); diff --git a/packages/svelte/src/compiler/types/template.d.ts b/packages/svelte/src/compiler/types/template.d.ts index 5c99e7d34e..3f87b0b631 100644 --- a/packages/svelte/src/compiler/types/template.d.ts +++ b/packages/svelte/src/compiler/types/template.d.ts @@ -409,10 +409,6 @@ export namespace AST { export interface SvelteBoundary extends BaseElement { type: 'SvelteBoundary'; name: 'svelte:boundary'; - /** @internal */ - metadata: { - pending: SnippetBlock | Attribute | null; - }; } export interface SvelteHead extends BaseElement {