|
|
@@ -412,12 +412,30 @@ function hydrateTeleport(
|
|
|
optimized: boolean,
|
|
|
) => Node | null,
|
|
|
): Node | null {
|
|
|
- function hydrateDisabledTeleport(
|
|
|
- node: Node,
|
|
|
- vnode: VNode,
|
|
|
- targetStart: Node | null,
|
|
|
- targetAnchor: Node | null,
|
|
|
+ // lookahead until we find the target anchor
|
|
|
+ // we cannot rely on return value of hydrateChildren() because there
|
|
|
+ // could be nested teleports
|
|
|
+ function hydrateAnchor(
|
|
|
+ target: TeleportTargetElement,
|
|
|
+ targetNode: Node | null,
|
|
|
) {
|
|
|
+ let targetAnchor = targetNode
|
|
|
+ while (targetAnchor) {
|
|
|
+ if (targetAnchor && targetAnchor.nodeType === 8) {
|
|
|
+ if ((targetAnchor as Comment).data === 'teleport start anchor') {
|
|
|
+ vnode.targetStart = targetAnchor
|
|
|
+ } else if ((targetAnchor as Comment).data === 'teleport anchor') {
|
|
|
+ vnode.targetAnchor = targetAnchor
|
|
|
+ target._lpa =
|
|
|
+ vnode.targetAnchor && nextSibling(vnode.targetAnchor as Node)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ targetAnchor = nextSibling(targetAnchor)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function hydrateDisabledTeleport(node: Node, vnode: VNode) {
|
|
|
vnode.anchor = hydrateChildren(
|
|
|
nextSibling(node),
|
|
|
vnode,
|
|
|
@@ -427,8 +445,6 @@ function hydrateTeleport(
|
|
|
slotScopeIds,
|
|
|
optimized,
|
|
|
)
|
|
|
- vnode.targetStart = targetStart
|
|
|
- vnode.targetAnchor = targetAnchor
|
|
|
}
|
|
|
|
|
|
const target = (vnode.target = resolveTarget<Element>(
|
|
|
@@ -443,33 +459,22 @@ function hydrateTeleport(
|
|
|
(target as TeleportTargetElement)._lpa || target.firstChild
|
|
|
if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
|
|
|
if (disabled) {
|
|
|
- hydrateDisabledTeleport(
|
|
|
- node,
|
|
|
- vnode,
|
|
|
- targetNode,
|
|
|
- targetNode && nextSibling(targetNode),
|
|
|
- )
|
|
|
+ hydrateDisabledTeleport(node, vnode)
|
|
|
+ hydrateAnchor(target as TeleportTargetElement, targetNode)
|
|
|
+ if (!vnode.targetAnchor) {
|
|
|
+ prepareAnchor(
|
|
|
+ target,
|
|
|
+ vnode,
|
|
|
+ createText,
|
|
|
+ insert,
|
|
|
+ // if target is the same as the main view, insert anchors before current node
|
|
|
+ // to avoid hydrating mismatch
|
|
|
+ parentNode(node)! === target ? node : null,
|
|
|
+ )
|
|
|
+ }
|
|
|
} else {
|
|
|
vnode.anchor = nextSibling(node)
|
|
|
-
|
|
|
- // lookahead until we find the target anchor
|
|
|
- // we cannot rely on return value of hydrateChildren() because there
|
|
|
- // could be nested teleports
|
|
|
- let targetAnchor = targetNode
|
|
|
- while (targetAnchor) {
|
|
|
- if (targetAnchor && targetAnchor.nodeType === 8) {
|
|
|
- if ((targetAnchor as Comment).data === 'teleport start anchor') {
|
|
|
- vnode.targetStart = targetAnchor
|
|
|
- } else if ((targetAnchor as Comment).data === 'teleport anchor') {
|
|
|
- vnode.targetAnchor = targetAnchor
|
|
|
- ;(target as TeleportTargetElement)._lpa =
|
|
|
- vnode.targetAnchor && nextSibling(vnode.targetAnchor as Node)
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- targetAnchor = nextSibling(targetAnchor)
|
|
|
- }
|
|
|
-
|
|
|
+ hydrateAnchor(target as TeleportTargetElement, targetNode)
|
|
|
// #11400 if the HTML corresponding to Teleport is not embedded in the
|
|
|
// correct position on the final page during SSR. the targetAnchor will
|
|
|
// always be null, we need to manually add targetAnchor to ensure
|
|
|
@@ -492,7 +497,9 @@ function hydrateTeleport(
|
|
|
updateCssVars(vnode, disabled)
|
|
|
} else if (disabled) {
|
|
|
if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
|
|
|
- hydrateDisabledTeleport(node, vnode, node, nextSibling(node))
|
|
|
+ hydrateDisabledTeleport(node, vnode)
|
|
|
+ vnode.targetStart = node
|
|
|
+ vnode.targetAnchor = nextSibling(node)
|
|
|
}
|
|
|
}
|
|
|
return vnode.anchor && nextSibling(vnode.anchor as Node)
|
|
|
@@ -535,6 +542,7 @@ function prepareAnchor(
|
|
|
vnode: TeleportVNode,
|
|
|
createText: RendererOptions['createText'],
|
|
|
insert: RendererOptions['insert'],
|
|
|
+ anchor: RendererNode | null = null,
|
|
|
) {
|
|
|
const targetStart = (vnode.targetStart = createText(''))
|
|
|
const targetAnchor = (vnode.targetAnchor = createText(''))
|
|
|
@@ -544,8 +552,8 @@ function prepareAnchor(
|
|
|
targetStart[TeleportEndKey] = targetAnchor
|
|
|
|
|
|
if (target) {
|
|
|
- insert(targetStart, target)
|
|
|
- insert(targetAnchor, target)
|
|
|
+ insert(targetStart, target, anchor)
|
|
|
+ insert(targetAnchor, target, anchor)
|
|
|
}
|
|
|
|
|
|
return targetAnchor
|