wip: handle suspense as component root el update
This commit is contained in:
parent
3959a2a2e1
commit
0fff3a6ef5
@ -613,12 +613,25 @@ export function createRenderer<
|
|||||||
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null = null
|
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null = null
|
||||||
) {
|
) {
|
||||||
if (n1 == null) {
|
if (n1 == null) {
|
||||||
function resolve() {
|
const suspense = (n2.suspense = createSuspenseBoundary(
|
||||||
|
n2,
|
||||||
|
parentSuspense,
|
||||||
|
hostCreateElement('div'),
|
||||||
|
resolveSuspense
|
||||||
|
))
|
||||||
|
|
||||||
|
function resolveSuspense() {
|
||||||
|
const { subTree, fallbackTree, bufferedJobs, vnode } = suspense
|
||||||
// unmount fallback tree
|
// unmount fallback tree
|
||||||
unmount(suspense.fallbackTree as HostVNode, parentComponent, true)
|
unmount(fallbackTree as HostVNode, parentComponent, true)
|
||||||
// move content from off-dom container to actual container
|
// move content from off-dom container to actual container
|
||||||
move(suspense.subTree as HostVNode, container, anchor)
|
move(subTree as HostVNode, container, anchor)
|
||||||
suspense.vnode.el = (suspense.subTree as HostVNode).el
|
const el = (vnode.el = (subTree as HostVNode).el as HostNode)
|
||||||
|
// suspense as the root node of a component...
|
||||||
|
if (parentComponent && parentComponent.subTree === vnode) {
|
||||||
|
parentComponent.vnode.el = el
|
||||||
|
updateHOCHostEl(parentComponent, el)
|
||||||
|
}
|
||||||
// check if there is a pending parent suspense
|
// check if there is a pending parent suspense
|
||||||
let parent = suspense.parent
|
let parent = suspense.parent
|
||||||
let hasUnresolvedAncestor = false
|
let hasUnresolvedAncestor = false
|
||||||
@ -626,24 +639,22 @@ export function createRenderer<
|
|||||||
if (!parent.isResolved) {
|
if (!parent.isResolved) {
|
||||||
// found a pending parent suspense, merge buffered post jobs
|
// found a pending parent suspense, merge buffered post jobs
|
||||||
// into that parent
|
// into that parent
|
||||||
parent.bufferedJobs.push(...suspense.bufferedJobs)
|
parent.bufferedJobs.push(...bufferedJobs)
|
||||||
hasUnresolvedAncestor = true
|
hasUnresolvedAncestor = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// no pending parent suspense, flush all jobs
|
// no pending parent suspense, flush all jobs
|
||||||
if (!hasUnresolvedAncestor) {
|
if (!hasUnresolvedAncestor) {
|
||||||
queuePostFlushCb(suspense.bufferedJobs)
|
queuePostFlushCb(bufferedJobs)
|
||||||
}
|
}
|
||||||
suspense.isResolved = true
|
suspense.isResolved = true
|
||||||
|
// invoke @resolve event
|
||||||
|
const onResolve = vnode.props && vnode.props.onResolve
|
||||||
|
if (isFunction(onResolve)) {
|
||||||
|
onResolve()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const suspense = (n2.suspense = createSuspenseBoundary(
|
|
||||||
n2,
|
|
||||||
parentSuspense,
|
|
||||||
hostCreateElement('div'),
|
|
||||||
resolve
|
|
||||||
))
|
|
||||||
|
|
||||||
// TODO pass it down as an arg instead
|
// TODO pass it down as an arg instead
|
||||||
if (parentComponent) {
|
if (parentComponent) {
|
||||||
@ -821,6 +832,7 @@ export function createRenderer<
|
|||||||
instance.asyncResolved = true
|
instance.asyncResolved = true
|
||||||
handleSetupResult(instance, asyncSetupResult)
|
handleSetupResult(instance, asyncSetupResult)
|
||||||
setupRenderEffect(instance, initialVNode, container, anchor, isSVG)
|
setupRenderEffect(instance, initialVNode, container, anchor, isSVG)
|
||||||
|
updateHOCHostEl(instance, initialVNode.el as HostNode)
|
||||||
if (suspense.deps === 0) {
|
if (suspense.deps === 0) {
|
||||||
suspense.resolve()
|
suspense.resolve()
|
||||||
}
|
}
|
||||||
@ -907,11 +919,7 @@ export function createRenderer<
|
|||||||
// self-triggered update. In case of HOC, update parent component
|
// self-triggered update. In case of HOC, update parent component
|
||||||
// vnode el. HOC is indicated by parent instance's subTree pointing
|
// vnode el. HOC is indicated by parent instance's subTree pointing
|
||||||
// to child component's vnode
|
// to child component's vnode
|
||||||
let parent = instance.parent
|
updateHOCHostEl(instance, nextTree.el)
|
||||||
while (parent && parent.subTree === current) {
|
|
||||||
;(current = parent.vnode).el = nextTree.el
|
|
||||||
parent = parent.parent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// upated hook
|
// upated hook
|
||||||
if (instance.u !== null) {
|
if (instance.u !== null) {
|
||||||
@ -925,6 +933,16 @@ export function createRenderer<
|
|||||||
}, __DEV__ ? createDevEffectOptions(instance) : prodEffectOptions)
|
}, __DEV__ ? createDevEffectOptions(instance) : prodEffectOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateHOCHostEl(
|
||||||
|
{ vnode, parent }: ComponentInternalInstance,
|
||||||
|
el: HostNode
|
||||||
|
) {
|
||||||
|
while (parent && parent.subTree === vnode) {
|
||||||
|
;(vnode = parent.vnode).el = el
|
||||||
|
parent = parent.parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function patchChildren(
|
function patchChildren(
|
||||||
n1: HostVNode | null,
|
n1: HostVNode | null,
|
||||||
n2: HostVNode,
|
n2: HostVNode,
|
||||||
|
Loading…
Reference in New Issue
Block a user