import { ComponentInternalInstance } from './component'
import { invokeDirectiveHook } from './directives'
import { warn } from './warning'
-import { PatchFlags, ShapeFlags, isReservedProp, isOn } from '@vue/shared'
+import {
+ PatchFlags,
+ ShapeFlags,
+ isReservedProp,
+ isOn,
+ isString
+} from '@vue/shared'
import { RendererOptions, MountComponentFn } from './renderer'
export type RootHydrateFunction = (
}
// TODO handle mismatches
- // TODO SVG
- // TODO Suspense
const hydrateNode = (
node: Node,
vnode: VNode,
// back anchor as expected.
return anchor.nextSibling
case Portal:
- // TODO
- break
+ hydratePortal(vnode, parentComponent)
+ return node.nextSibling
default:
if (shapeFlag & ShapeFlags.ELEMENT) {
return hydrateElement(node as Element, vnode, parentComponent)
const subTree = vnode.component!.subTree
return (subTree.anchor || subTree.el).nextSibling
} else if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
- // TODO
+ // TODO Suspense
} else if (__DEV__) {
warn('Invalid HostVNode type:', type, `(${typeof type})`)
}
return node
}
+ const hydratePortal = (
+ vnode: VNode,
+ parentComponent: ComponentInternalInstance | null
+ ) => {
+ const targetSelector = vnode.props && vnode.props.target
+ const target = (vnode.target = isString(targetSelector)
+ ? document.querySelector(targetSelector)
+ : targetSelector)
+ if (target != null && vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
+ hydrateChildren(
+ target.firstChild,
+ vnode.children as VNode[],
+ parentComponent
+ )
+ }
+ }
+
return [hydrate, hydrateNode] as const
}