547f0c6971a14b3afb94884af724f880a2efd247251b728b1b9319234055c050a5fec9196b5e7801faa28568b90ff0badd4121f61e5c3179f81869c8a75f50 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* @flow */
  2. import {
  3. warn,
  4. invokeWithErrorHandling
  5. } from 'core/util/index'
  6. import {
  7. cached,
  8. isUndef,
  9. isTrue,
  10. isPlainObject
  11. } from 'shared/util'
  12. const normalizeEvent = cached((name: string): {
  13. name: string,
  14. once: boolean,
  15. capture: boolean,
  16. passive: boolean,
  17. handler?: Function,
  18. params?: Array<any>
  19. } => {
  20. const passive = name.charAt(0) === '&'
  21. name = passive ? name.slice(1) : name
  22. const once = name.charAt(0) === '~' // Prefixed last, checked first
  23. name = once ? name.slice(1) : name
  24. const capture = name.charAt(0) === '!'
  25. name = capture ? name.slice(1) : name
  26. return {
  27. name,
  28. once,
  29. capture,
  30. passive
  31. }
  32. })
  33. export function createFnInvoker (fns: Function | Array<Function>, vm: ?Component): Function {
  34. function invoker () {
  35. const fns = invoker.fns
  36. if (Array.isArray(fns)) {
  37. const cloned = fns.slice()
  38. for (let i = 0; i < cloned.length; i++) {
  39. invokeWithErrorHandling(cloned[i], null, arguments, vm, `v-on handler`)
  40. }
  41. } else {
  42. // return handler return value for single handlers
  43. return invokeWithErrorHandling(fns, null, arguments, vm, `v-on handler`)
  44. }
  45. }
  46. invoker.fns = fns
  47. return invoker
  48. }
  49. export function updateListeners (
  50. on: Object,
  51. oldOn: Object,
  52. add: Function,
  53. remove: Function,
  54. createOnceHandler: Function,
  55. vm: Component
  56. ) {
  57. let name, def, cur, old, event
  58. for (name in on) {
  59. def = cur = on[name]
  60. old = oldOn[name]
  61. event = normalizeEvent(name)
  62. /* istanbul ignore if */
  63. if (__WEEX__ && isPlainObject(def)) {
  64. cur = def.handler
  65. event.params = def.params
  66. }
  67. if (isUndef(cur)) {
  68. process.env.NODE_ENV !== 'production' && warn(
  69. `Invalid handler for event "${event.name}": got ` + String(cur),
  70. vm
  71. )
  72. } else if (isUndef(old)) {
  73. if (isUndef(cur.fns)) {
  74. cur = on[name] = createFnInvoker(cur, vm)
  75. }
  76. if (isTrue(event.once)) {
  77. cur = on[name] = createOnceHandler(event.name, cur, event.capture)
  78. }
  79. add(event.name, cur, event.capture, event.passive, event.params)
  80. } else if (cur !== old) {
  81. old.fns = cur
  82. on[name] = old
  83. }
  84. }
  85. for (name in oldOn) {
  86. if (isUndef(on[name])) {
  87. event = normalizeEvent(name)
  88. remove(event.name, oldOn[name], event.capture)
  89. }
  90. }
  91. }