Skip to content

Commit 42ccdc1

Browse files
authored
fix: ensure snippets after empty text correctly hydrate (#13870)
1 parent b5750ac commit 42ccdc1

File tree

7 files changed

+32
-3
lines changed

7 files changed

+32
-3
lines changed

.changeset/plenty-plums-sparkle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ensure snippets after empty text correctly hydrate

packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ export function RegularElement(node, context) {
384384
arg = b.member(arg, 'content');
385385
}
386386

387-
process_children(trimmed, () => b.call('$.child', arg), true, {
387+
process_children(trimmed, (is_text) => b.call('$.child', arg, is_text && b.true), true, {
388388
...context,
389389
state: child_state
390390
});

packages/svelte/src/internal/client/dom/operations.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ export function get_next_sibling(node) {
9191
* Don't mark this as side-effect-free, hydration needs to walk all nodes
9292
* @template {Node} N
9393
* @param {N} node
94+
* @param {boolean} is_text
9495
* @returns {Node | null}
9596
*/
96-
export function child(node) {
97+
export function child(node, is_text) {
9798
if (!hydrating) {
9899
return get_first_child(node);
99100
}
@@ -103,6 +104,11 @@ export function child(node) {
103104
// Child can be null if we have an element with a single child, like `<p>{text}</p>`, where `text` is empty
104105
if (child === null) {
105106
child = hydrate_node.appendChild(create_text());
107+
} else if (is_text && child.nodeType !== 3) {
108+
var text = create_text();
109+
child?.before(text);
110+
set_hydrate_node(text);
111+
return text;
106112
}
107113

108114
set_hydrate_node(child);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let {prop = '', children} = $props()
3+
</script>
4+
5+
<div>{prop}{@render children()}</div>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
compileOptions: {
5+
dev: true // Render in dev mode to check that the validation error is not thrown
6+
},
7+
html: `<div>123</div`
8+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
import Child from './Child.svelte';
3+
</script>
4+
5+
<Child>123</Child>

packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default function Skip_static_subtree($$anchor, $$props) {
77
var fragment = root();
88
var main = $.sibling($.first_child(fragment), 2);
99
var h1 = $.child(main);
10-
var text = $.child(h1);
10+
var text = $.child(h1, true);
1111

1212
$.reset(h1);
1313

0 commit comments

Comments
 (0)