From e9bd78259fb516554a6afab6cfa47b570fb98662 Mon Sep 17 00:00:00 2001 From: Jan Vogt Date: Thu, 26 Jun 2025 01:27:36 +0000 Subject: [PATCH] fix await blocks For some reason await blocks render html whitespace and their custom hydration error handling seems to depend on hydrating text nodes. --- .../src/internal/client/dom/blocks/await.js | 2 +- .../src/internal/client/dom/hydration.js | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index 47df5fc9a5..2c3e3af4a7 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -36,7 +36,7 @@ const CATCH = 2; */ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) { if (hydrating) { - hydrate_next(); + hydrate_next(true); } var anchor = node; diff --git a/packages/svelte/src/internal/client/dom/hydration.js b/packages/svelte/src/internal/client/dom/hydration.js index 5ecdb1c236..37492c80e2 100644 --- a/packages/svelte/src/internal/client/dom/hydration.js +++ b/packages/svelte/src/internal/client/dom/hydration.js @@ -40,9 +40,25 @@ export function set_hydrate_node(node) { return (hydrate_node = node); } -export function hydrate_next() { +/** + * Moove to the next node to be hydrated. Empty text nodes will be skipped, + * unless `allow_text` is set to true. + * + * Skipping whitespace helps to sucessful hydrate even if some middleware added + * arbitrary whitespace into the html. This was at least twice an issue: + * + * - https://github.com/sveltejs/svelte/issues/15819 + * - https://github.com/sveltejs/svelte/issues/16242 + * + * Removing empty text nodes should be finde, as required text nodes will be + * added on demand. Doing so is necessary because an empty text on the server + * side will result in a missing text nodes as well. + * + * @param {boolean} allow_text + */ +export function hydrate_next(allow_text = false) { var node = set_hydrate_node(/** @type {TemplateNode} */(get_next_sibling(hydrate_node))); - while (hydrate_node.nodeType === TEXT_NODE && !hydrate_node.nodeValue?.trim()) { + while (!allow_text && node.nodeType === TEXT_NODE && !node.nodeValue?.trim()) { var next_sibling = get_next_sibling(hydrate_node) hydrate_node.parentElement?.removeChild(hydrate_node) node = set_hydrate_node(/** @type {TemplateNode} */(next_sibling))