You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.4 KiB
136 lines
3.4 KiB
/**
|
|
* Create an event emitter with namespaces
|
|
* @name createNamespaceEmitter
|
|
* @example
|
|
* var emitter = require('./index')()
|
|
*
|
|
* emitter.on('*', function () {
|
|
* console.log('all events emitted', this.event)
|
|
* })
|
|
*
|
|
* emitter.on('example', function () {
|
|
* console.log('example event emitted')
|
|
* })
|
|
*/
|
|
module.exports = function createNamespaceEmitter () {
|
|
var emitter = {}
|
|
var _fns = emitter._fns = {}
|
|
|
|
/**
|
|
* 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 `:`
|
|
* @name emit
|
|
* @param {String} event – the name of the event, with optional namespace
|
|
* @param {...*} data – up to 6 arguments that are passed to the event listener
|
|
* @example
|
|
* emitter.emit('example')
|
|
* emitter.emit('demo:test')
|
|
* emitter.emit('data', { example: true}, 'a string', 1)
|
|
*/
|
|
emitter.emit = function emit (event, arg1, arg2, arg3, arg4, arg5, arg6) {
|
|
var toEmit = getListeners(event)
|
|
|
|
if (toEmit.length) {
|
|
emitAll(event, toEmit, [arg1, arg2, arg3, arg4, arg5, arg6])
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create en event listener.
|
|
* @name on
|
|
* @param {String} event
|
|
* @param {Function} fn
|
|
* @example
|
|
* emitter.on('example', function () {})
|
|
* emitter.on('demo', function () {})
|
|
*/
|
|
emitter.on = function on (event, fn) {
|
|
if (!_fns[event]) {
|
|
_fns[event] = []
|
|
}
|
|
|
|
_fns[event].push(fn)
|
|
}
|
|
|
|
/**
|
|
* Create en event listener that fires once.
|
|
* @name once
|
|
* @param {String} event
|
|
* @param {Function} fn
|
|
* @example
|
|
* emitter.once('example', function () {})
|
|
* emitter.once('demo', function () {})
|
|
*/
|
|
emitter.once = function once (event, fn) {
|
|
function one () {
|
|
fn.apply(this, arguments)
|
|
emitter.off(event, one)
|
|
}
|
|
this.on(event, one)
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
* You must be explicit about what will be unsubscribed: `emitter.off('demo')` will unsubscribe an `emitter.on('demo')` listener,
|
|
* `emitter.off('demo:example')` will unsubscribe an `emitter.on('demo:example')` listener
|
|
* @name off
|
|
* @param {String} event
|
|
* @param {Function} [fn] – the specific handler
|
|
* @example
|
|
* emitter.off('example')
|
|
* emitter.off('demo', function () {})
|
|
*/
|
|
emitter.off = function off (event, fn) {
|
|
var keep = []
|
|
|
|
if (event && fn) {
|
|
var fns = this._fns[event]
|
|
var i = 0
|
|
var l = fns ? fns.length : 0
|
|
|
|
for (i; i < l; i++) {
|
|
if (fns[i] !== fn) {
|
|
keep.push(fns[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
keep.length ? this._fns[event] = keep : delete this._fns[event]
|
|
}
|
|
|
|
function getListeners (e) {
|
|
var out = _fns[e] ? _fns[e] : []
|
|
var idx = e.indexOf(':')
|
|
var args = (idx === -1) ? [e] : [e.substring(0, idx), e.substring(idx + 1)]
|
|
|
|
var keys = Object.keys(_fns)
|
|
var i = 0
|
|
var l = keys.length
|
|
|
|
for (i; i < l; i++) {
|
|
var key = keys[i]
|
|
if (key === '*') {
|
|
out = out.concat(_fns[key])
|
|
}
|
|
|
|
if (args.length === 2 && args[0] === key) {
|
|
out = out.concat(_fns[key])
|
|
break
|
|
}
|
|
}
|
|
|
|
return out
|
|
}
|
|
|
|
function emitAll (e, fns, args) {
|
|
var i = 0
|
|
var l = fns.length
|
|
|
|
for (i; i < l; i++) {
|
|
if (!fns[i]) break
|
|
fns[i].event = e
|
|
fns[i].apply(fns[i], args)
|
|
}
|
|
}
|
|
|
|
return emitter
|
|
}
|
|
|