From 67efffafc3a62e072e7476c4b93b345bc3abb356 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 6 Dec 2024 16:22:35 -0500 Subject: [PATCH 1/2] fix: always run `if` block code the first time --- .changeset/rare-cheetahs-laugh.md | 5 +++++ .../svelte/src/internal/client/dom/blocks/if.js | 8 ++++---- .../samples/if-block-mismatch-2/_config.js | 15 +++++++++++++++ .../samples/if-block-mismatch-2/_expected.html | 1 + .../samples/if-block-mismatch-2/main.svelte | 13 +++++++++++++ .../samples/if-block-mismatch/_expected.html | 1 + .../samples/if-block-mismatch/main.svelte | 2 +- 7 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 .changeset/rare-cheetahs-laugh.md create mode 100644 packages/svelte/tests/hydration/samples/if-block-mismatch-2/_config.js create mode 100644 packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html create mode 100644 packages/svelte/tests/hydration/samples/if-block-mismatch-2/main.svelte create mode 100644 packages/svelte/tests/hydration/samples/if-block-mismatch/_expected.html diff --git a/.changeset/rare-cheetahs-laugh.md b/.changeset/rare-cheetahs-laugh.md new file mode 100644 index 000000000000..2637b50b3c38 --- /dev/null +++ b/.changeset/rare-cheetahs-laugh.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: always run `if` block code the first time diff --git a/packages/svelte/src/internal/client/dom/blocks/if.js b/packages/svelte/src/internal/client/dom/blocks/if.js index 6a880f28bc98..36790c05c135 100644 --- a/packages/svelte/src/internal/client/dom/blocks/if.js +++ b/packages/svelte/src/internal/client/dom/blocks/if.js @@ -9,7 +9,7 @@ import { set_hydrating } from '../hydration.js'; import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js'; -import { HYDRATION_START_ELSE } from '../../../../constants.js'; +import { HYDRATION_START_ELSE, UNINITIALIZED } from '../../../../constants.js'; /** * @param {TemplateNode} node @@ -30,8 +30,8 @@ export function if_block(node, fn, elseif = false) { /** @type {Effect | null} */ var alternate_effect = null; - /** @type {boolean | null} */ - var condition = null; + /** @type {UNINITIALIZED | boolean | null} */ + var condition = UNINITIALIZED; var flags = elseif ? EFFECT_TRANSPARENT : 0; @@ -54,7 +54,7 @@ export function if_block(node, fn, elseif = false) { if (hydrating) { const is_else = /** @type {Comment} */ (anchor).data === HYDRATION_START_ELSE; - if (condition === is_else) { + if (!!condition === is_else) { // Hydration mismatch: remove everything inside the anchor and start fresh. // This could happen with `{#if browser}...{/if}`, for example anchor = remove_nodes(); diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_config.js b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_config.js new file mode 100644 index 000000000000..ffde9ee303b5 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_config.js @@ -0,0 +1,15 @@ +import { test } from '../../test'; + +// even {#if true} or {#if false} should be kept as an if block, because it could be {#if browser} originally, +// which is then different between client and server. +export default test({ + server_props: { + condition: true + }, + + props: { + condition: false + }, + + trim_whitespace: false +}); diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html new file mode 100644 index 000000000000..25b0d820f4b7 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html @@ -0,0 +1 @@ +
hello diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch-2/main.svelte b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/main.svelte new file mode 100644 index 000000000000..3136406698b3 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/main.svelte @@ -0,0 +1,13 @@ + + +{#if condition} + +{/if} + +
+ +
+ +hello diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch/_expected.html b/packages/svelte/tests/hydration/samples/if-block-mismatch/_expected.html new file mode 100644 index 000000000000..79cf2cf35f0f --- /dev/null +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch/_expected.html @@ -0,0 +1 @@ +

foo

diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch/main.svelte b/packages/svelte/tests/hydration/samples/if-block-mismatch/main.svelte index c6799c5f95fc..552c43410162 100644 --- a/packages/svelte/tests/hydration/samples/if-block-mismatch/main.svelte +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch/main.svelte @@ -2,7 +2,7 @@ let { condition } = $props(); -{#if true} +{#if condition}

foo

{:else}

bar

From a4c4de592c79ff21845627658c7f30f842f3544c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 6 Dec 2024 16:27:10 -0500 Subject: [PATCH 2/2] fix --- .../tests/hydration/samples/if-block-mismatch-2/_expected.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html index 25b0d820f4b7..08a3809de9cc 100644 --- a/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html @@ -1 +1 @@ -
hello +
hello