`"<!--[--><span></span>barAbarBbar<span></span><!--]-->"`,
)
})
+
+ test('empty text nodes', async () => {
+ const data = reactive({ txt: '' })
+ const { container } = await testHydration(
+ `<template><div>{{ data.txt }}</div></template>`,
+ undefined,
+ data,
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(`"<div> </div>"`)
+
+ data.txt = 'foo'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(`"<div>foo</div>"`)
+ })
})
describe('element', () => {
*/
/*! #__NO_SIDE_EFFECTS__ */
export function __child(node: ParentNode, offset?: number): Node {
- let n = offset ? __nthChild(node, offset) : node.firstChild!
-
- if (isComment(n, '[')) {
- n = locateEndAnchor(n)!.nextSibling!
+ // when offset is -1, it means we need to get the text node of this element
+ // since server-side rendering doesn't generate whitespace placeholder text nodes,
+ // if firstChild is null, manually insert a text node and return it
+ if (offset === -1 && !node.firstChild) {
+ node.textContent = ' '
+ return node.firstChild!
}
- while (n && isVaporAnchors(n)) {
- n = n.nextSibling!
+ let n = offset ? __nthChild(node, offset) : node.firstChild!
+ while (n && (isComment(n, '[') || isVaporAnchors(n))) {
+ if (isComment(n, '[')) {
+ n = locateEndAnchor(n)!.nextSibling!
+ } else {
+ n = n.nextSibling!
+ }
}
+
return n
}