From 5f7fe4d7afe95e46365b6bd640028c3b33d21cfe Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 22 Mar 2024 17:08:29 -0400 Subject: [PATCH] remove some indirection --- .../src/internal/client/dom/blocks/each.js | 8 +++++--- .../svelte/src/internal/client/dom/blocks/if.js | 6 +++--- .../svelte/src/internal/client/dom/hydration.js | 17 +++++++++++------ packages/svelte/src/internal/client/render.js | 9 ++++++--- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js index ce17cced94..672575e7a3 100644 --- a/packages/svelte/src/internal/client/dom/blocks/each.js +++ b/packages/svelte/src/internal/client/dom/blocks/each.js @@ -11,7 +11,8 @@ import { get_hydration_fragment, hydrate_block_anchor, hydrating, - set_current_hydration_fragment + set_current_hydration_fragment, + set_hydrating } from '../hydration.js'; import { empty } from '../operations.js'; import { insert, remove } from '../reconciler.js'; @@ -104,7 +105,7 @@ function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, re if (is_else !== (length === 0)) { // hydration mismatch — remove the server-rendered DOM and start over remove(current_hydration_fragment); - set_current_hydration_fragment(null); + set_hydrating(false); mismatch = true; } else if (is_else) { // Remove the each_else comment node or else it will confuse the subsequent hydration algorithm @@ -129,6 +130,7 @@ function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, re // If fragment is null, then that means that the server rendered less items than what // the client code specifies -> break out and continue with client-side node creation mismatch = true; + set_hydrating(false); break; } @@ -176,7 +178,7 @@ function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, re if (mismatch) { // Set a fragment so that Svelte continues to operate in hydration mode - set_current_hydration_fragment([]); + set_hydrating(true); } }); diff --git a/packages/svelte/src/internal/client/dom/blocks/if.js b/packages/svelte/src/internal/client/dom/blocks/if.js index 217ccac00d..84f2f435bc 100644 --- a/packages/svelte/src/internal/client/dom/blocks/if.js +++ b/packages/svelte/src/internal/client/dom/blocks/if.js @@ -3,7 +3,7 @@ import { current_hydration_fragment, hydrate_block_anchor, hydrating, - set_current_hydration_fragment + set_hydrating } from '../hydration.js'; import { remove } from '../reconciler.js'; import { @@ -50,7 +50,7 @@ export function if_block(anchor, get_condition, consequent_fn, alternate_fn, els // Hydration mismatch: remove everything inside the anchor and start fresh. // This could happen using when `{#if browser} .. {/if}` in SvelteKit. remove(current_hydration_fragment); - set_current_hydration_fragment(null); + set_hydrating(false); mismatch = true; } else { // Remove the ssr:if comment node or else it will confuse the subsequent hydration algorithm @@ -86,7 +86,7 @@ export function if_block(anchor, get_condition, consequent_fn, alternate_fn, els if (mismatch) { // Set fragment so that Svelte continues to operate in hydration mode - set_current_hydration_fragment([]); + set_hydrating(true); } }); diff --git a/packages/svelte/src/internal/client/dom/hydration.js b/packages/svelte/src/internal/client/dom/hydration.js index c896454659..1466f91f86 100644 --- a/packages/svelte/src/internal/client/dom/hydration.js +++ b/packages/svelte/src/internal/client/dom/hydration.js @@ -9,31 +9,36 @@ import { empty } from './operations.js'; */ export let hydrating = false; +/** @param {boolean} value */ +export function set_hydrating(value) { + hydrating = value; +} + /** * Array of nodes to traverse for hydration. This will be null if we're not hydrating, but for * the sake of simplicity we're not going to use `null` checks everywhere and instead rely on * the `hydrating` flag to tell whether or not we're in hydration mode at which point this is set. - * @type {import('../types.js').TemplateNode[]} + * @type {import('#client').TemplateNode[]} */ export let current_hydration_fragment = /** @type {any} */ (null); /** - * @param {null | import('../types.js').TemplateNode[]} fragment + * @param {null | import('#client').TemplateNode[]} fragment * @returns {void} */ export function set_current_hydration_fragment(fragment) { - hydrating = fragment !== null; - current_hydration_fragment = /** @type {import('../types.js').TemplateNode[]} */ (fragment); + // hydrating = fragment !== null; + current_hydration_fragment = /** @type {import('#client').TemplateNode[]} */ (fragment); } /** * Returns all nodes between the first `` comment tag pair encountered. * @param {Node | null} node * @param {boolean} [insert_text] Whether to insert an empty text node if the fragment is empty - * @returns {import('../types.js').TemplateNode[] | null} + * @returns {import('#client').TemplateNode[] | null} */ export function get_hydration_fragment(node, insert_text = false) { - /** @type {import('../types.js').TemplateNode[]} */ + /** @type {import('#client').TemplateNode[]} */ const fragment = []; /** @type {null | Node} */ diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 7c3151e773..4259b4436d 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -9,7 +9,8 @@ import { get_hydration_fragment, hydrate_block_anchor, hydrating, - set_current_hydration_fragment + set_current_hydration_fragment, + set_hydrating } from './dom/hydration.js'; import { array_from } from './utils.js'; import { handle_event_propagation } from './dom/elements/events.js'; @@ -146,6 +147,7 @@ export function hydrate(component, options) { const hydration_fragment = get_hydration_fragment(first_child, true); const previous_hydration_fragment = current_hydration_fragment; set_current_hydration_fragment(hydration_fragment); + set_hydrating(true); /** @type {null | Text} */ let anchor = null; @@ -162,7 +164,7 @@ export function hydrate(component, options) { const instance = _mount(component, { ...options, anchor }); // flush_sync will run this callback and then synchronously run any pending effects, // which don't belong to the hydration phase anymore - therefore reset it here - set_current_hydration_fragment(null); + set_hydrating(false); finished_hydrating = true; return instance; }, false); @@ -179,12 +181,13 @@ export function hydrate(component, options) { remove(hydration_fragment); first_child.remove(); hydration_fragment[hydration_fragment.length - 1]?.nextSibling?.remove(); - set_current_hydration_fragment(null); + set_hydrating(false); return mount(component, options); } else { throw error; } } finally { + set_hydrating(!!previous_hydration_fragment); set_current_hydration_fragment(previous_hydration_fragment); } }