index.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /**
  2. * Create an event emitter with namespaces
  3. * @name createNamespaceEmitter
  4. * @example
  5. * var emitter = require('./index')()
  6. *
  7. * emitter.on('*', function () {
  8. * console.log('all events emitted', this.event)
  9. * })
  10. *
  11. * emitter.on('example', function () {
  12. * console.log('example event emitted')
  13. * })
  14. */
  15. module.exports = function createNamespaceEmitter () {
  16. var emitter = {}
  17. var _fns = emitter._fns = {}
  18. /**
  19. * Emit an event. Optionally namespace the event. Handlers are fired in the order in which they were added with exact matches taking precedence. Separate the namespace and event with a `:`
  20. * @name emit
  21. * @param {String} event – the name of the event, with optional namespace
  22. * @param {...*} data – up to 6 arguments that are passed to the event listener
  23. * @example
  24. * emitter.emit('example')
  25. * emitter.emit('demo:test')
  26. * emitter.emit('data', { example: true}, 'a string', 1)
  27. */
  28. emitter.emit = function emit (event, arg1, arg2, arg3, arg4, arg5, arg6) {
  29. var toEmit = getListeners(event)
  30. if (toEmit.length) {
  31. emitAll(event, toEmit, [arg1, arg2, arg3, arg4, arg5, arg6])
  32. }
  33. }
  34. /**
  35. * Create en event listener.
  36. * @name on
  37. * @param {String} event
  38. * @param {Function} fn
  39. * @example
  40. * emitter.on('example', function () {})
  41. * emitter.on('demo', function () {})
  42. */
  43. emitter.on = function on (event, fn) {
  44. if (!_fns[event]) {
  45. _fns[event] = []
  46. }
  47. _fns[event].push(fn)
  48. }
  49. /**
  50. * Create en event listener that fires once.
  51. * @name once
  52. * @param {String} event
  53. * @param {Function} fn
  54. * @example
  55. * emitter.once('example', function () {})
  56. * emitter.once('demo', function () {})
  57. */
  58. emitter.once = function once (event, fn) {
  59. function one () {
  60. fn.apply(this, arguments)
  61. emitter.off(event, one)
  62. }
  63. this.on(event, one)
  64. }
  65. /**
  66. * Stop listening to an event. Stop all listeners on an event by only passing the event name. Stop a single listener by passing that event handler as a callback.
  67. * You must be explicit about what will be unsubscribed: `emitter.off('demo')` will unsubscribe an `emitter.on('demo')` listener,
  68. * `emitter.off('demo:example')` will unsubscribe an `emitter.on('demo:example')` listener
  69. * @name off
  70. * @param {String} event
  71. * @param {Function} [fn] – the specific handler
  72. * @example
  73. * emitter.off('example')
  74. * emitter.off('demo', function () {})
  75. */
  76. emitter.off = function off (event, fn) {
  77. var keep = []
  78. if (event && fn) {
  79. var fns = this._fns[event]
  80. var i = 0
  81. var l = fns ? fns.length : 0
  82. for (i; i < l; i++) {
  83. if (fns[i] !== fn) {
  84. keep.push(fns[i])
  85. }
  86. }
  87. }
  88. keep.length ? this._fns[event] = keep : delete this._fns[event]
  89. }
  90. function getListeners (e) {
  91. var out = _fns[e] ? _fns[e] : []
  92. var idx = e.indexOf(':')
  93. var args = (idx === -1) ? [e] : [e.substring(0, idx), e.substring(idx + 1)]
  94. var keys = Object.keys(_fns)
  95. var i = 0
  96. var l = keys.length
  97. for (i; i < l; i++) {
  98. var key = keys[i]
  99. if (key === '*') {
  100. out = out.concat(_fns[key])
  101. }
  102. if (args.length === 2 && args[0] === key) {
  103. out = out.concat(_fns[key])
  104. break
  105. }
  106. }
  107. return out
  108. }
  109. function emitAll (e, fns, args) {
  110. var i = 0
  111. var l = fns.length
  112. for (i; i < l; i++) {
  113. if (!fns[i]) break
  114. fns[i].event = e
  115. fns[i].apply(fns[i], args)
  116. }
  117. }
  118. return emitter
  119. }