Skip to content

Commit c8cb320

Browse files
committed
fix: ensure snippets after empty text correctly hydrate
1 parent 04c38b0 commit c8cb320

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
@@ -390,7 +390,7 @@ export function RegularElement(node, context) {
390390
arg = b.member(arg, 'content');
391391
}
392392

393-
process_children(trimmed, () => b.call('$.child', arg), true, {
393+
process_children(trimmed, (is_text) => b.call('$.child', arg, is_text && b.true), true, {
394394
...context,
395395
state: child_state
396396
});

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ export function get_next_sibling(node) {
8989
* Don't mark this as side-effect-free, hydration needs to walk all nodes
9090
* @template {Node} N
9191
* @param {N} node
92+
* @param {boolean} is_text
9293
* @returns {Node | null}
9394
*/
94-
export function child(node) {
95+
export function child(node, is_text) {
9596
if (!hydrating) {
9697
return get_first_child(node);
9798
}
@@ -101,6 +102,11 @@ export function child(node) {
101102
// Child can be null if we have an element with a single child, like `<p>{text}</p>`, where `text` is empty
102103
if (child === null) {
103104
child = hydrate_node.appendChild(create_text());
105+
} else if (is_text && child.nodeType !== 3) {
106+
var text = create_text();
107+
child?.before(text);
108+
set_hydrate_node(text);
109+
return text;
104110
}
105111

106112
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)