002cd601ee5ad5b1479e7387fc2d6e385c76d2878cecfd5abe0fd25a5c58b21b2c306ac6fa37594b5be3d2443655565039695352783253bdf1e2610d5f7bb3 1012 B

1234567891011121314151617181920212223242526272829303132333435363738
  1. /* @flow */
  2. import VNode from '../vnode'
  3. import { createFnInvoker } from './update-listeners'
  4. import { remove, isDef, isUndef, isTrue } from 'shared/util'
  5. export function mergeVNodeHook (def: Object, hookKey: string, hook: Function) {
  6. if (def instanceof VNode) {
  7. def = def.data.hook || (def.data.hook = {})
  8. }
  9. let invoker
  10. const oldHook = def[hookKey]
  11. function wrappedHook () {
  12. hook.apply(this, arguments)
  13. // important: remove merged hook to ensure it's called only once
  14. // and prevent memory leak
  15. remove(invoker.fns, wrappedHook)
  16. }
  17. if (isUndef(oldHook)) {
  18. // no existing hook
  19. invoker = createFnInvoker([wrappedHook])
  20. } else {
  21. /* istanbul ignore if */
  22. if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {
  23. // already a merged invoker
  24. invoker = oldHook
  25. invoker.fns.push(wrappedHook)
  26. } else {
  27. // existing plain hook
  28. invoker = createFnInvoker([oldHook, wrappedHook])
  29. }
  30. }
  31. invoker.merged = true
  32. def[hookKey] = invoker
  33. }