diff --git a/.changeset/six-files-speak.md b/.changeset/six-files-speak.md new file mode 100644 index 0000000000..1667b164c6 --- /dev/null +++ b/.changeset/six-files-speak.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: remove outer hydration markers diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index ecd22a1db6..f5e32a2196 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -120,19 +120,9 @@ export function hydrate(component, options) { set_hydrating(true); set_hydrate_node(/** @type {Comment} */ (anchor)); - hydrate_next(); const instance = _mount(component, { ...options, anchor }); - if ( - hydrate_node === null || - hydrate_node.nodeType !== COMMENT_NODE || - /** @type {Comment} */ (hydrate_node).data !== HYDRATION_END - ) { - w.hydration_mismatch(); - throw HYDRATION_ERROR; - } - set_hydrating(false); return /** @type {Exports} */ (instance); @@ -247,6 +237,15 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro if (hydrating) { /** @type {Effect} */ (active_effect).nodes_end = hydrate_node; + + if ( + hydrate_node === null || + hydrate_node.nodeType !== COMMENT_NODE || + /** @type {Comment} */ (hydrate_node).data !== HYDRATION_END + ) { + w.hydration_mismatch(); + throw HYDRATION_ERROR; + } } if (context) { diff --git a/packages/svelte/src/internal/server/renderer.js b/packages/svelte/src/internal/server/renderer.js index 21ae91fbb7..a77afd68b3 100644 --- a/packages/svelte/src/internal/server/renderer.js +++ b/packages/svelte/src/internal/server/renderer.js @@ -516,8 +516,7 @@ export class Renderer { } let head = content.head + renderer.global.get_title(); - - const body = BLOCK_OPEN + content.body + BLOCK_CLOSE; // this inserts a fake boundary so hydration matches + let body = content.body; for (const { hash, code } of renderer.global.css) { head += ``; diff --git a/packages/svelte/src/internal/server/renderer.test.ts b/packages/svelte/src/internal/server/renderer.test.ts index 2b2bf14cf7..7112bacd75 100644 --- a/packages/svelte/src/internal/server/renderer.test.ts +++ b/packages/svelte/src/internal/server/renderer.test.ts @@ -14,7 +14,7 @@ test('collects synchronous body content by default', () => { const { head, body } = Renderer.render(component as unknown as Component); expect(head).toBe(''); - expect(body).toBe('abc'); + expect(body).toBe('abc'); }); test('child type switches content area (head vs body)', () => { @@ -28,7 +28,7 @@ test('child type switches content area (head vs body)', () => { const { head, body } = Renderer.render(component as unknown as Component); expect(head).toBe('T'); - expect(body).toBe('ab'); + expect(body).toBe('ab'); }); test('child inherits parent type when not specified', () => { @@ -42,7 +42,7 @@ test('child inherits parent type when not specified', () => { }; const { head, body } = Renderer.render(component as unknown as Component); - expect(body).toBe(''); + expect(body).toBe(''); expect(head).toBe(''); }); @@ -101,7 +101,7 @@ test('compact synchronously aggregates a range and can transform into head/body' const { head, body } = Renderer.render(component as unknown as Component); expect(head).toBe('H'); - expect(body).toBe('abdc'); + expect(body).toBe('abdc'); }); test('local state is shallow-copied to children', () => { @@ -216,7 +216,7 @@ describe('async', () => { const result = await Renderer.render(component as unknown as Component); expect(result.head).toBe(''); - expect(result.body).toBe('123'); + expect(result.body).toBe('123'); expect(() => result.html).toThrow('html_deprecated'); }); @@ -239,7 +239,7 @@ describe('async', () => { const { body, head } = await Renderer.render(component as unknown as Component); expect(head).toBe(''); - expect(body).toBe('axb'); + expect(body).toBe('axb'); }); test('push accepts async functions in async context', async () => { @@ -254,7 +254,7 @@ describe('async', () => { const { head, body } = await Renderer.render(component as unknown as Component); expect(head).toBe(''); - expect(body).toBe('abc'); + expect(body).toBe('abc'); }); test('push handles async functions with different timing', async () => { @@ -272,7 +272,7 @@ describe('async', () => { const { head, body } = await Renderer.render(component as unknown as Component); expect(head).toBe(''); - expect(body).toBe('fastslowsync'); + expect(body).toBe('fastslowsync'); }); test('push async functions work with head content type', async () => { @@ -286,7 +286,7 @@ describe('async', () => { }; const { head, body } = await Renderer.render(component as unknown as Component); - expect(body).toBe(''); + expect(body).toBe(''); expect(head).toBe('Async Title'); }); @@ -305,7 +305,7 @@ describe('async', () => { const { head, body } = await Renderer.render(component as unknown as Component); expect(head).toBe(''); - expect(body).toBe('start-async-child--end'); + expect(body).toBe('start-async-child--end'); }); test('push async functions work with compact operations', async () => { @@ -324,7 +324,7 @@ describe('async', () => { const { head, body } = await Renderer.render(component as unknown as Component); expect(head).toBe(''); - expect(body).toBe('ABC'); + expect(body).toBe('ABC'); }); test('push async functions are not supported in sync context', () => { diff --git a/packages/svelte/tests/hydration/samples/binding-input/_expected.html b/packages/svelte/tests/hydration/samples/binding-input/_expected.html index 7a73053b82..e36735dc6b 100644 --- a/packages/svelte/tests/hydration/samples/binding-input/_expected.html +++ b/packages/svelte/tests/hydration/samples/binding-input/_expected.html @@ -1 +1 @@ -

Hello world!

+

Hello world!

diff --git a/packages/svelte/tests/hydration/samples/dynamic-text-changed/_expected.html b/packages/svelte/tests/hydration/samples/dynamic-text-changed/_expected.html index 04266bf7f3..11e3f55d6b 100644 --- a/packages/svelte/tests/hydration/samples/dynamic-text-changed/_expected.html +++ b/packages/svelte/tests/hydration/samples/dynamic-text-changed/_expected.html @@ -1 +1 @@ -

Hello everybody!

+

Hello everybody!

diff --git a/packages/svelte/tests/hydration/samples/each-block-0-on-server-more-on-client/_expected.html b/packages/svelte/tests/hydration/samples/each-block-0-on-server-more-on-client/_expected.html index 4b28b305d5..2b2a31b926 100644 --- a/packages/svelte/tests/hydration/samples/each-block-0-on-server-more-on-client/_expected.html +++ b/packages/svelte/tests/hydration/samples/each-block-0-on-server-more-on-client/_expected.html @@ -1 +1 @@ -
  • a
  • a
  • a
  • a
  • a
  • a
  • +
  • a
  • a
  • a
  • a
  • a
  • a
  • diff --git a/packages/svelte/tests/hydration/samples/each-block-fallback-mismatch/_expected.html b/packages/svelte/tests/hydration/samples/each-block-fallback-mismatch/_expected.html index 8ace6d0373..af66d98b25 100644 --- a/packages/svelte/tests/hydration/samples/each-block-fallback-mismatch/_expected.html +++ b/packages/svelte/tests/hydration/samples/each-block-fallback-mismatch/_expected.html @@ -1 +1 @@ -

    a

    empty

    +

    a

    empty

    diff --git a/packages/svelte/tests/hydration/samples/each-block-less-nodes-on-client/_expected.html b/packages/svelte/tests/hydration/samples/each-block-less-nodes-on-client/_expected.html index 4b28b305d5..2b2a31b926 100644 --- a/packages/svelte/tests/hydration/samples/each-block-less-nodes-on-client/_expected.html +++ b/packages/svelte/tests/hydration/samples/each-block-less-nodes-on-client/_expected.html @@ -1 +1 @@ -
  • a
  • a
  • a
  • a
  • a
  • a
  • +
  • a
  • a
  • a
  • a
  • a
  • a
  • diff --git a/packages/svelte/tests/hydration/samples/each-block-more-nodes-on-client/_expected.html b/packages/svelte/tests/hydration/samples/each-block-more-nodes-on-client/_expected.html index 89cbd0b466..fa72a80dcd 100644 --- a/packages/svelte/tests/hydration/samples/each-block-more-nodes-on-client/_expected.html +++ b/packages/svelte/tests/hydration/samples/each-block-more-nodes-on-client/_expected.html @@ -1 +1 @@ -
  • a
  • a
  • b
  • b
  • a
  • a
  • b
  • b
  • a
  • a
  • b
  • b
  • +
  • a
  • a
  • b
  • b
  • a
  • a
  • b
  • b
  • a
  • a
  • b
  • b
  • diff --git a/packages/svelte/tests/hydration/samples/element-attribute-added/_expected.html b/packages/svelte/tests/hydration/samples/element-attribute-added/_expected.html index 27f9299c54..7d8e91c757 100644 --- a/packages/svelte/tests/hydration/samples/element-attribute-added/_expected.html +++ b/packages/svelte/tests/hydration/samples/element-attribute-added/_expected.html @@ -1 +1 @@ -
    +
    diff --git a/packages/svelte/tests/hydration/samples/element-attribute-changed/_expected.html b/packages/svelte/tests/hydration/samples/element-attribute-changed/_expected.html index 27f9299c54..7d8e91c757 100644 --- a/packages/svelte/tests/hydration/samples/element-attribute-changed/_expected.html +++ b/packages/svelte/tests/hydration/samples/element-attribute-changed/_expected.html @@ -1 +1 @@ -
    +
    diff --git a/packages/svelte/tests/hydration/samples/element-attribute-removed/_expected.html b/packages/svelte/tests/hydration/samples/element-attribute-removed/_expected.html index 1a69c9fa30..a6c1be8b49 100644 --- a/packages/svelte/tests/hydration/samples/element-attribute-removed/_expected.html +++ b/packages/svelte/tests/hydration/samples/element-attribute-removed/_expected.html @@ -1 +1 @@ -
    +
    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 5620250623..08a3809de9 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 diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch/_expected.html b/packages/svelte/tests/hydration/samples/if-block-mismatch/_expected.html index 5ace45d895..79cf2cf35f 100644 --- a/packages/svelte/tests/hydration/samples/if-block-mismatch/_expected.html +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch/_expected.html @@ -1 +1 @@ -

    foo

    +

    foo

    diff --git a/packages/svelte/tests/hydration/samples/input-checked-attribute-sibling/_expected.html b/packages/svelte/tests/hydration/samples/input-checked-attribute-sibling/_expected.html index 521f9c52b8..bcd53f8783 100644 --- a/packages/svelte/tests/hydration/samples/input-checked-attribute-sibling/_expected.html +++ b/packages/svelte/tests/hydration/samples/input-checked-attribute-sibling/_expected.html @@ -1 +1 @@ -. +. diff --git a/packages/svelte/tests/hydration/samples/input-value-changed/_expected.html b/packages/svelte/tests/hydration/samples/input-value-changed/_expected.html index c9bc1409d7..c5384e717e 100644 --- a/packages/svelte/tests/hydration/samples/input-value-changed/_expected.html +++ b/packages/svelte/tests/hydration/samples/input-value-changed/_expected.html @@ -1 +1 @@ - + diff --git a/packages/svelte/tests/hydration/samples/noscript/_expected.html b/packages/svelte/tests/hydration/samples/noscript/_expected.html index a587a13af1..990ce87303 100644 --- a/packages/svelte/tests/hydration/samples/noscript/_expected.html +++ b/packages/svelte/tests/hydration/samples/noscript/_expected.html @@ -1 +1 @@ -

    Hello!

    Count: 1

    +

    Hello!

    Count: 1

    diff --git a/packages/svelte/tests/hydration/samples/pre-first-node-newline/_expected.html b/packages/svelte/tests/hydration/samples/pre-first-node-newline/_expected.html index a4d2df2147..26de34d1ed 100644 --- a/packages/svelte/tests/hydration/samples/pre-first-node-newline/_expected.html +++ b/packages/svelte/tests/hydration/samples/pre-first-node-newline/_expected.html @@ -1,7 +1,7 @@ -
    static content no line
    	static content ignored line
    +
    static content no line
    	static content ignored line
     
     	static content relevant line
     
     
    -
    +
    diff --git a/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_expected.html b/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_expected.html index 4af6885faf..cc789c8f51 100644 --- a/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_expected.html +++ b/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_expected.html @@ -1 +1 @@ -
    +
    diff --git a/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_expected.html b/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_expected.html index 1755e9bfe2..e1076af2ec 100644 --- a/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_expected.html +++ b/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_expected.html @@ -1 +1 @@ -foo foo +foo foo diff --git a/packages/svelte/tests/hydration/samples/safari-borking/_override.html b/packages/svelte/tests/hydration/samples/safari-borking/_override.html index b3665d1f80..876815e7a9 100644 --- a/packages/svelte/tests/hydration/samples/safari-borking/_override.html +++ b/packages/svelte/tests/hydration/samples/safari-borking/_override.html @@ -1 +1 @@ -

    call +636-555-3226 now!

    +

    call +636-555-3226 now!

    diff --git a/packages/svelte/tests/hydration/samples/script/_expected.html b/packages/svelte/tests/hydration/samples/script/_expected.html index ab881a6197..b3a4d92219 100644 --- a/packages/svelte/tests/hydration/samples/script/_expected.html +++ b/packages/svelte/tests/hydration/samples/script/_expected.html @@ -1 +1 @@ - + diff --git a/packages/svelte/tests/hydration/samples/snippet-raw-hydrate/_expected.html b/packages/svelte/tests/hydration/samples/snippet-raw-hydrate/_expected.html index 0629ab64c2..8d9dde52c1 100644 --- a/packages/svelte/tests/hydration/samples/snippet-raw-hydrate/_expected.html +++ b/packages/svelte/tests/hydration/samples/snippet-raw-hydrate/_expected.html @@ -1 +1 @@ -

    hydrated

    +

    hydrated

    diff --git a/packages/svelte/tests/hydration/samples/standalone-component/_expected.html b/packages/svelte/tests/hydration/samples/standalone-component/_expected.html index 119576aa73..96850f7bdf 100644 --- a/packages/svelte/tests/hydration/samples/standalone-component/_expected.html +++ b/packages/svelte/tests/hydration/samples/standalone-component/_expected.html @@ -1 +1 @@ -

    child

    child

    child

    child

    +

    child

    child

    child

    child

    diff --git a/packages/svelte/tests/hydration/samples/standalone-snippet/_expected.html b/packages/svelte/tests/hydration/samples/standalone-snippet/_expected.html index 61fc31a95e..acb14818c2 100644 --- a/packages/svelte/tests/hydration/samples/standalone-snippet/_expected.html +++ b/packages/svelte/tests/hydration/samples/standalone-snippet/_expected.html @@ -1 +1 @@ -

    thing

    thing

    thing

    thing

    +

    thing

    thing

    thing

    thing

    diff --git a/packages/svelte/tests/hydration/samples/surrounding-whitespace/_expected.html b/packages/svelte/tests/hydration/samples/surrounding-whitespace/_expected.html index 7b51bed662..e728b682d0 100644 --- a/packages/svelte/tests/hydration/samples/surrounding-whitespace/_expected.html +++ b/packages/svelte/tests/hydration/samples/surrounding-whitespace/_expected.html @@ -1,2 +1,2 @@ - hello + hello diff --git a/packages/svelte/tests/hydration/samples/surrounding-whitespace/_override.html b/packages/svelte/tests/hydration/samples/surrounding-whitespace/_override.html index 7b51bed662..e728b682d0 100644 --- a/packages/svelte/tests/hydration/samples/surrounding-whitespace/_override.html +++ b/packages/svelte/tests/hydration/samples/surrounding-whitespace/_override.html @@ -1,2 +1,2 @@ - hello + hello diff --git a/packages/svelte/tests/hydration/samples/text-empty-2/_expected.html b/packages/svelte/tests/hydration/samples/text-empty-2/_expected.html index e14014c2f0..ff12f10bfb 100644 --- a/packages/svelte/tests/hydration/samples/text-empty-2/_expected.html +++ b/packages/svelte/tests/hydration/samples/text-empty-2/_expected.html @@ -1 +1 @@ - + diff --git a/packages/svelte/tests/hydration/samples/text-empty/_expected.html b/packages/svelte/tests/hydration/samples/text-empty/_expected.html index c4d823410f..2e03580f42 100644 --- a/packages/svelte/tests/hydration/samples/text-empty/_expected.html +++ b/packages/svelte/tests/hydration/samples/text-empty/_expected.html @@ -1 +1 @@ -x +x diff --git a/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_override.html b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_override.html index 7402247877..24b6bae7b8 100644 --- a/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_override.html +++ b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_override.html @@ -1,2 +1,2 @@ - -

    nested

    \ No newline at end of file + +

    nested

    diff --git a/packages/svelte/tests/runtime-legacy/samples/textarea-content/_config.js b/packages/svelte/tests/runtime-legacy/samples/textarea-content/_config.js index dac6ee4fb8..7cd7c553e0 100644 --- a/packages/svelte/tests/runtime-legacy/samples/textarea-content/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/textarea-content/_config.js @@ -4,7 +4,7 @@ export default test({ withoutNormalizeHtml: true, // Unable to test `html` with `
    `, +multiple leading newlines`, test({ assert, target }) { // Test for