isUnmounting: boolean
// Track pending leave callbacks for children of the same key.
// This is used to force remove leaving a child when a new copy is entering.
- leavingVNodes: Map<any, Record<string, any>>
+ leavingNodes: Map<any, Record<string, any>>
}
export interface TransitionElement {
isMounted: false,
isLeaving: false,
isUnmounting: false,
- leavingVNodes: new Map(),
+ leavingNodes: new Map(),
}
onMounted(() => {
state.isMounted = true
state: TransitionState,
vnode: VNode,
): Record<string, VNode> {
- const { leavingVNodes } = state
- let leavingVNodesCache = leavingVNodes.get(vnode.type)!
+ const { leavingNodes } = state
+ let leavingVNodesCache = leavingNodes.get(vnode.type)!
if (!leavingVNodesCache) {
leavingVNodesCache = Object.create(null)
- leavingVNodes.set(vnode.type, leavingVNodesCache)
+ leavingNodes.set(vnode.type, leavingVNodesCache)
}
return leavingVNodesCache
}
TransitionBlock
export interface VaporTransitionHooks extends TransitionHooks {
- state?: TransitionState
- props?: TransitionProps
+ state: TransitionState
+ props: TransitionProps
}
export type TransitionBlock = {
pauseTracking()
const parent = this.anchor.parentNode
+ const transition = this.transition
const renderBranch = () => {
if (render) {
- const transition = this.transition
this.scope = new EffectScope()
this.nodes = this.scope.run(render) || []
if (transition) {
this.transitionChild = applyTransitionEnterHooks(
this.nodes,
- transition.state!,
- transition.props!,
transition,
)
}
// teardown previous branch
if (this.scope) {
this.scope.stop()
- const mode = this.transition && this.transition.mode
+ const mode = transition && transition.mode
if (mode) {
- applyTransitionLeaveHooks(
- this.nodes,
- this.transition!.state!,
- this.transition!.props!,
- renderBranch,
- this.transition,
- )
+ applyTransitionLeaveHooks(this.nodes, transition, renderBranch)
parent && remove(this.nodes, parent)
if (mode === 'out-in') {
resetTracking()
warn(`invalid <transition> mode: ${mode}`)
}
- applyTransitionEnterHooks(
- children,
- useTransitionState(),
+ applyTransitionEnterHooks(children, {
+ state: useTransitionState(),
props,
- undefined,
- false,
- )
+ } as VaporTransitionHooks)
return children
},
}
const getTransitionHooksContext = (
- key: string,
- block: Block,
+ key: String,
props: TransitionProps,
state: TransitionState,
instance: GenericComponentInstance,
postClone: ((hooks: TransitionHooks) => void) | undefined,
) => {
+ const { leavingNodes } = state
const context: TransitionHooksContext = {
setLeavingNodeCache: el => {
- const leavingNodeCache = getLeavingNodesForBlock(state, block)
- leavingNodeCache[key] = el
+ leavingNodes.set(key, el)
},
unsetLeavingNodeCache: el => {
- const leavingNodeCache = getLeavingNodesForBlock(state, block)
- if (leavingNodeCache[key] === el) {
- delete leavingNodeCache[key]
+ const leavingNode = leavingNodes.get(key)
+ if (leavingNode === el) {
+ leavingNodes.delete(key)
}
},
earlyRemove: () => {
- const leavingNodeCache = getLeavingNodesForBlock(state, block)
- const leavingNode = leavingNodeCache[key]
+ const leavingNode = leavingNodes.get(key)
if (leavingNode && (leavingNode as TransitionElement)[leaveCbKey]) {
// force early removal (not cancelled)
;(leavingNode as TransitionElement)[leaveCbKey]!()
instance: GenericComponentInstance,
postClone?: (hooks: TransitionHooks) => void,
): VaporTransitionHooks {
- const key = String(block.key)
const context = getTransitionHooksContext(
- key,
- block,
+ String(block.key),
props,
state,
instance,
postClone,
)
- const hooks: VaporTransitionHooks = baseResolveTransitionHooks(
+ const hooks = baseResolveTransitionHooks(
context,
props,
state,
instance,
- )
+ ) as VaporTransitionHooks
hooks.state = state
hooks.props = props
return hooks
}
-function getLeavingNodesForBlock(
- state: TransitionState,
- block: Block,
-): Record<string, Block> {
- const { leavingVNodes } = state
- let leavingNodesCache = leavingVNodes.get(block)!
- if (!leavingNodesCache) {
- leavingNodesCache = Object.create(null)
- leavingVNodes.set(block, leavingNodesCache)
- }
- return leavingNodesCache
-}
-
function setTransitionHooks(block: Block, hooks: VaporTransitionHooks) {
if (!isFragment(block)) {
block.transition = hooks
export function applyTransitionEnterHooks(
block: Block,
- state: TransitionState,
- props: TransitionProps,
- enterHooks?: VaporTransitionHooks,
- clone: boolean = true,
+ hooks: VaporTransitionHooks,
): Block | undefined {
const child = findElementChild(block)
if (child) {
- if (!enterHooks) {
- enterHooks = resolveTransitionHooks(
- child,
- props,
- state,
- currentInstance!,
- hooks => (enterHooks = hooks),
- )
- }
-
- setTransitionHooks(
+ const { props, state, delayedLeave } = hooks
+ let enterHooks = resolveTransitionHooks(
child,
- clone ? enterHooks.clone(child as any) : enterHooks,
+ props,
+ state,
+ currentInstance!,
+ hooks => (enterHooks = hooks as VaporTransitionHooks),
)
-
+ enterHooks.delayedLeave = delayedLeave
+ setTransitionHooks(child, enterHooks)
if (isFragment(block)) {
block.transitionChild = child
}
export function applyTransitionLeaveHooks(
block: Block,
- state: TransitionState,
- props: TransitionProps,
+ enterHooks: VaporTransitionHooks,
afterLeaveCb: () => void,
- enterHooks: TransitionHooks,
): void {
const leavingBlock = findElementChild(block)
if (!leavingBlock) return undefined
- let leavingHooks = resolveTransitionHooks(
+ const { props, state } = enterHooks
+ const leavingHooks = resolveTransitionHooks(
leavingBlock,
props,
state,
earlyRemove,
delayedLeave,
) => {
- const leavingNodeCache = getLeavingNodesForBlock(state, leavingBlock)
- leavingNodeCache[String(leavingBlock.key)] = leavingBlock
+ state.leavingNodes.set(String(leavingBlock.key), leavingBlock)
// early removal callback
block[leaveCbKey] = () => {
earlyRemove()