/* @flow */
|
|
import VNode from '../vnode'
|
import { createFnInvoker } from './update-listeners'
|
import { remove, isDef, isUndef, isTrue } from 'shared/util'
|
|
export function mergeVNodeHook (def: Object, hookKey: string, hook: Function) {
|
if (def instanceof VNode) {
|
def = def.data.hook || (def.data.hook = {})
|
}
|
let invoker
|
const oldHook = def[hookKey]
|
|
function wrappedHook () {
|
hook.apply(this, arguments)
|
// important: remove merged hook to ensure it's called only once
|
// and prevent memory leak
|
remove(invoker.fns, wrappedHook)
|
}
|
|
if (isUndef(oldHook)) {
|
// no existing hook
|
invoker = createFnInvoker([wrappedHook])
|
} else {
|
/* istanbul ignore if */
|
if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {
|
// already a merged invoker
|
invoker = oldHook
|
invoker.fns.push(wrappedHook)
|
} else {
|
// existing plain hook
|
invoker = createFnInvoker([oldHook, wrappedHook])
|
}
|
}
|
|
invoker.merged = true
|
def[hookKey] = invoker
|
}
|