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.
169 lines
3.2 KiB
169 lines
3.2 KiB
/** |
|
* Initialize a new `Emitter`. |
|
* |
|
* @api public |
|
*/ |
|
|
|
export function Emitter(obj) { |
|
if (obj) return mixin(obj); |
|
} |
|
|
|
/** |
|
* Mixin the emitter properties. |
|
* |
|
* @param {Object} obj |
|
* @return {Object} |
|
* @api private |
|
*/ |
|
|
|
function mixin(obj) { |
|
for (var key in Emitter.prototype) { |
|
obj[key] = Emitter.prototype[key]; |
|
} |
|
return obj; |
|
} |
|
|
|
/** |
|
* Listen on the given `event` with `fn`. |
|
* |
|
* @param {String} event |
|
* @param {Function} fn |
|
* @return {Emitter} |
|
* @api public |
|
*/ |
|
|
|
Emitter.prototype.on = |
|
Emitter.prototype.addEventListener = function(event, fn){ |
|
this._callbacks = this._callbacks || {}; |
|
(this._callbacks['$' + event] = this._callbacks['$' + event] || []) |
|
.push(fn); |
|
return this; |
|
}; |
|
|
|
/** |
|
* Adds an `event` listener that will be invoked a single |
|
* time then automatically removed. |
|
* |
|
* @param {String} event |
|
* @param {Function} fn |
|
* @return {Emitter} |
|
* @api public |
|
*/ |
|
|
|
Emitter.prototype.once = function(event, fn){ |
|
function on() { |
|
this.off(event, on); |
|
fn.apply(this, arguments); |
|
} |
|
|
|
on.fn = fn; |
|
this.on(event, on); |
|
return this; |
|
}; |
|
|
|
/** |
|
* Remove the given callback for `event` or all |
|
* registered callbacks. |
|
* |
|
* @param {String} event |
|
* @param {Function} fn |
|
* @return {Emitter} |
|
* @api public |
|
*/ |
|
|
|
Emitter.prototype.off = |
|
Emitter.prototype.removeListener = |
|
Emitter.prototype.removeAllListeners = |
|
Emitter.prototype.removeEventListener = function(event, fn){ |
|
this._callbacks = this._callbacks || {}; |
|
|
|
// all |
|
if (0 == arguments.length) { |
|
this._callbacks = {}; |
|
return this; |
|
} |
|
|
|
// specific event |
|
var callbacks = this._callbacks['$' + event]; |
|
if (!callbacks) return this; |
|
|
|
// remove all handlers |
|
if (1 == arguments.length) { |
|
delete this._callbacks['$' + event]; |
|
return this; |
|
} |
|
|
|
// remove specific handler |
|
var cb; |
|
for (var i = 0; i < callbacks.length; i++) { |
|
cb = callbacks[i]; |
|
if (cb === fn || cb.fn === fn) { |
|
callbacks.splice(i, 1); |
|
break; |
|
} |
|
} |
|
|
|
// Remove event specific arrays for event types that no |
|
// one is subscribed for to avoid memory leak. |
|
if (callbacks.length === 0) { |
|
delete this._callbacks['$' + event]; |
|
} |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* Emit `event` with the given args. |
|
* |
|
* @param {String} event |
|
* @param {Mixed} ... |
|
* @return {Emitter} |
|
*/ |
|
|
|
Emitter.prototype.emit = function(event){ |
|
this._callbacks = this._callbacks || {}; |
|
|
|
var args = new Array(arguments.length - 1) |
|
, callbacks = this._callbacks['$' + event]; |
|
|
|
for (var i = 1; i < arguments.length; i++) { |
|
args[i - 1] = arguments[i]; |
|
} |
|
|
|
if (callbacks) { |
|
callbacks = callbacks.slice(0); |
|
for (var i = 0, len = callbacks.length; i < len; ++i) { |
|
callbacks[i].apply(this, args); |
|
} |
|
} |
|
|
|
return this; |
|
}; |
|
|
|
// alias used for reserved events (protected method) |
|
Emitter.prototype.emitReserved = Emitter.prototype.emit; |
|
|
|
/** |
|
* Return array of callbacks for `event`. |
|
* |
|
* @param {String} event |
|
* @return {Array} |
|
* @api public |
|
*/ |
|
|
|
Emitter.prototype.listeners = function(event){ |
|
this._callbacks = this._callbacks || {}; |
|
return this._callbacks['$' + event] || []; |
|
}; |
|
|
|
/** |
|
* Check if this emitter has `event` handlers. |
|
* |
|
* @param {String} event |
|
* @return {Boolean} |
|
* @api public |
|
*/ |
|
|
|
Emitter.prototype.hasListeners = function(event){ |
|
return !! this.listeners(event).length; |
|
};
|
|
|