From c4404452da54eb75790fc9f17fa4a99a9338b0c4 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 7 Jul 2024 12:02:04 -0400 Subject: [PATCH] fix --- .../src/compiler/phases/3-transform/utils.js | 4 ++- .../src/internal/client/dom/blocks/if.js | 36 +++++++++++++++++-- .../client/dom/blocks/svelte-element.js | 8 ++--- packages/svelte/src/internal/client/render.js | 1 + 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/utils.js b/packages/svelte/src/compiler/phases/3-transform/utils.js index eac29f877c..83cfcf7b41 100644 --- a/packages/svelte/src/compiler/phases/3-transform/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/utils.js @@ -287,7 +287,9 @@ 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 const is_anchored = - parent.type === 'Fragment' && (first.type === 'Text' || first.type === 'ExpressionTag'); + parent.type === 'Fragment' && + first && + (first?.type === 'Text' || first?.type === 'ExpressionTag'); return { hoisted, trimmed, is_standalone: false, is_anchored }; } diff --git a/packages/svelte/src/internal/client/dom/blocks/if.js b/packages/svelte/src/internal/client/dom/blocks/if.js index 88be3744d3..66b3c7c5db 100644 --- a/packages/svelte/src/internal/client/dom/blocks/if.js +++ b/packages/svelte/src/internal/client/dom/blocks/if.js @@ -1,8 +1,13 @@ /** @import { TemplateNode } from '#client' */ import { EFFECT_TRANSPARENT } from '../../constants.js'; -import { hydrate_next, hydrate_node, hydrating, set_hydrating } from '../hydration.js'; +import { + hydrate_next, + hydrate_node, + hydrating, + set_hydrate_node, + set_hydrating +} from '../hydration.js'; import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js'; -import { HYDRATION_START_ELSE } from '../../../../constants.js'; /** * @param {TemplateNode} anchor @@ -46,7 +51,9 @@ export function if_block( if (condition === is_else) { // Hydration mismatch: remove everything inside the anchor and start fresh. // This could happen with `{#if browser}...{/if}`, for example - // remove(hydrate_nodes); + anchor = remove_nodes(); + + set_hydrate_node(anchor); set_hydrating(false); mismatch = true; } @@ -88,3 +95,26 @@ export function if_block( anchor = hydrate_node; } } + +// TODO share this logic with each.js — revert to `[` and `]` +function remove_nodes() { + var depth = 0; + var node = hydrate_node; + + while (node.nodeType !== 8 || (depth === 0 && /** @type {Comment} */ (node).data !== '/if')) { + if (node.nodeType === 8) { + var data = /** @type {Comment} */ (node).data; + if (data === '#if' || data === '#if!') { + depth += 1; + } else if (data === '/if') { + depth -= 1; + } + } + + var next = /** @type {TemplateNode} */ (node.nextSibling); + node.remove(); + node = next; + } + + return node; +} diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-element.js b/packages/svelte/src/internal/client/dom/blocks/svelte-element.js index 4358adb511..313b6559a5 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-element.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-element.js @@ -69,7 +69,7 @@ export function element(node, get_tag, is_svg, render_fn, get_namespace, locatio pause_effect(effect, () => { effect = null; current_tag = null; - element?.remove(); + // element?.remove(); }); } else if (next_tag === current_tag) { // same tag as is currently rendered — abort outro @@ -103,9 +103,9 @@ export function element(node, get_tag, is_svg, render_fn, get_namespace, locatio }; } - if (prev_element && !hydrating) { - prev_element.remove(); - } + // if (prev_element && !hydrating) { + // prev_element.remove(); + // } if (render_fn) { // If hydrating, use the existing ssr comment as the anchor so that the diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index cd0cc04c15..676fa9f9d3 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -165,6 +165,7 @@ export function hydrate(component, options) { hydrate_node.nodeType !== 8 || /** @type {Comment} */ (hydrate_node).data !== HYDRATION_END ) { + w.hydration_mismatch(); throw HYDRATION_ERROR; }