expect(container.innerHTML).toBe(`<div class="bar">bar</div>`)
})
+ // #7285
+ test('element with multiple continuous text vnodes', async () => {
+ // should no mismatch warning
+ const { container } = mountWithHydration('<div>fooo</div>', () =>
+ h('div', ['fo', createTextVNode('o'), 'o']),
+ )
+ expect(container.textContent).toBe('fooo')
+ })
+
test('element with elements children', async () => {
const msg = ref('foo')
const fn = vi.fn()
)
})
+ // #7285
+ test('Fragment (multiple continuous text vnodes)', async () => {
+ // should no mismatch warning
+ const { container } = mountWithHydration('<!--[-->fooo<!--]-->', () => [
+ 'fo',
+ createTextVNode('o'),
+ 'o',
+ ])
+ expect(container.textContent).toBe('fooo')
+ })
+
test('Teleport', async () => {
const msg = ref('foo')
const fn = vi.fn()
const vnode = optimized
? children[i]
: (children[i] = normalizeVNode(children[i]))
+ const isText = vnode.type === Text
if (node) {
+ if (isText && !optimized) {
+ // #7285 possible consecutive text vnodes from manual render fns or
+ // JSX-compiled fns, but on the client the browser parses only 1 text
+ // node.
+ // look ahead for next possible text vnode
+ let next = children[i + 1]
+ if (next && (next = normalizeVNode(next)).type === Text) {
+ // create an extra TextNode on the client for the next vnode to
+ // adopt
+ insert(
+ createText(
+ (node as Text).data.slice((vnode.children as string).length),
+ ),
+ container,
+ nextSibling(node),
+ )
+ ;(node as Text).data = vnode.children as string
+ }
+ }
node = hydrateNode(
node,
vnode,
slotScopeIds,
optimized,
)
- } else if (vnode.type === Text && !vnode.children) {
+ } else if (isText && !vnode.children) {
// #7215 create a TextNode for empty text node
// because server rendered HTML won't contain a text node
insert((vnode.el = createText('')), container)