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.
178 lines
2.8 KiB
178 lines
2.8 KiB
|
|
/** |
|
* Module exports. |
|
*/ |
|
|
|
exports.EventEmitter = EventEmitter; |
|
|
|
/** |
|
* Check if `obj` is an array. |
|
*/ |
|
|
|
function isArray(obj) { |
|
return '[object Array]' == {}.toString.call(obj); |
|
} |
|
|
|
/** |
|
* Event emitter constructor. |
|
* |
|
* @api public. |
|
*/ |
|
|
|
function EventEmitter(){}; |
|
|
|
/** |
|
* Adds a listener. |
|
* |
|
* @api public |
|
*/ |
|
|
|
EventEmitter.prototype.on = function (name, fn) { |
|
if (!this.$events) { |
|
this.$events = {}; |
|
} |
|
|
|
if (!this.$events[name]) { |
|
this.$events[name] = fn; |
|
} else if (isArray(this.$events[name])) { |
|
this.$events[name].push(fn); |
|
} else { |
|
this.$events[name] = [this.$events[name], fn]; |
|
} |
|
|
|
return this; |
|
}; |
|
|
|
EventEmitter.prototype.addListener = EventEmitter.prototype.on; |
|
|
|
/** |
|
* Adds a volatile listener. |
|
* |
|
* @api public |
|
*/ |
|
|
|
EventEmitter.prototype.once = function (name, fn) { |
|
var self = this; |
|
|
|
function on () { |
|
self.removeListener(name, on); |
|
fn.apply(this, arguments); |
|
}; |
|
|
|
on.listener = fn; |
|
this.on(name, on); |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* Removes a listener. |
|
* |
|
* @api public |
|
*/ |
|
|
|
EventEmitter.prototype.removeListener = function (name, fn) { |
|
if (this.$events && this.$events[name]) { |
|
var list = this.$events[name]; |
|
|
|
if (isArray(list)) { |
|
var pos = -1; |
|
|
|
for (var i = 0, l = list.length; i < l; i++) { |
|
if (list[i] === fn || (list[i].listener && list[i].listener === fn)) { |
|
pos = i; |
|
break; |
|
} |
|
} |
|
|
|
if (pos < 0) { |
|
return this; |
|
} |
|
|
|
list.splice(pos, 1); |
|
|
|
if (!list.length) { |
|
delete this.$events[name]; |
|
} |
|
} else if (list === fn || (list.listener && list.listener === fn)) { |
|
delete this.$events[name]; |
|
} |
|
} |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* Removes all listeners for an event. |
|
* |
|
* @api public |
|
*/ |
|
|
|
EventEmitter.prototype.removeAllListeners = function (name) { |
|
if (name === undefined) { |
|
this.$events = {}; |
|
return this; |
|
} |
|
|
|
if (this.$events && this.$events[name]) { |
|
this.$events[name] = null; |
|
} |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* Gets all listeners for a certain event. |
|
* |
|
* @api publci |
|
*/ |
|
|
|
EventEmitter.prototype.listeners = function (name) { |
|
if (!this.$events) { |
|
this.$events = {}; |
|
} |
|
|
|
if (!this.$events[name]) { |
|
this.$events[name] = []; |
|
} |
|
|
|
if (!isArray(this.$events[name])) { |
|
this.$events[name] = [this.$events[name]]; |
|
} |
|
|
|
return this.$events[name]; |
|
}; |
|
|
|
/** |
|
* Emits an event. |
|
* |
|
* @api public |
|
*/ |
|
|
|
EventEmitter.prototype.emit = function (name) { |
|
if (!this.$events) { |
|
return false; |
|
} |
|
|
|
var handler = this.$events[name]; |
|
|
|
if (!handler) { |
|
return false; |
|
} |
|
|
|
var args = [].slice.call(arguments, 1); |
|
|
|
if ('function' == typeof handler) { |
|
handler.apply(this, args); |
|
} else if (isArray(handler)) { |
|
var listeners = handler.slice(); |
|
|
|
for (var i = 0, l = listeners.length; i < l; i++) { |
|
listeners[i].apply(this, args); |
|
} |
|
} else { |
|
return false; |
|
} |
|
|
|
return true; |
|
}; |