Spaces:
Building
Building
| ; | |
| var has = Object.prototype.hasOwnProperty; | |
| // | |
| // We store our EE objects in a plain object whose properties are event names. | |
| // If `Object.create(null)` is not supported we prefix the event names with a | |
| // `~` to make sure that the built-in object properties are not overridden or | |
| // used as an attack vector. | |
| // We also assume that `Object.create(null)` is available when the event name | |
| // is an ES6 Symbol. | |
| // | |
| var prefix = typeof Object.create !== 'function' ? '~' : false; | |
| /** | |
| * Representation of a single EventEmitter function. | |
| * | |
| * @param {Function} fn Event handler to be called. | |
| * @param {Mixed} context Context for function execution. | |
| * @param {Boolean} [once=false] Only emit once | |
| * @api private | |
| */ | |
| function EE(fn, context, once) { | |
| this.fn = fn; | |
| this.context = context; | |
| this.once = once || false; | |
| } | |
| /** | |
| * Minimal EventEmitter interface that is molded against the Node.js | |
| * EventEmitter interface. | |
| * | |
| * @constructor | |
| * @api public | |
| */ | |
| function EventEmitter() { /* Nothing to set */ } | |
| /** | |
| * Hold the assigned EventEmitters by name. | |
| * | |
| * @type {Object} | |
| * @private | |
| */ | |
| EventEmitter.prototype._events = undefined; | |
| /** | |
| * Return an array listing the events for which the emitter has registered | |
| * listeners. | |
| * | |
| * @returns {Array} | |
| * @api public | |
| */ | |
| EventEmitter.prototype.eventNames = function eventNames() { | |
| var events = this._events | |
| , names = [] | |
| , name; | |
| if (!events) return names; | |
| for (name in events) { | |
| if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); | |
| } | |
| if (Object.getOwnPropertySymbols) { | |
| return names.concat(Object.getOwnPropertySymbols(events)); | |
| } | |
| return names; | |
| }; | |
| /** | |
| * Return a list of assigned event listeners. | |
| * | |
| * @param {String} event The events that should be listed. | |
| * @param {Boolean} exists We only need to know if there are listeners. | |
| * @returns {Array|Boolean} | |
| * @api public | |
| */ | |
| EventEmitter.prototype.listeners = function listeners(event, exists) { | |
| var evt = prefix ? prefix + event : event | |
| , available = this._events && this._events[evt]; | |
| if (exists) return !!available; | |
| if (!available) return []; | |
| if (available.fn) return [available.fn]; | |
| for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) { | |
| ee[i] = available[i].fn; | |
| } | |
| return ee; | |
| }; | |
| /** | |
| * Emit an event to all registered event listeners. | |
| * | |
| * @param {String} event The name of the event. | |
| * @returns {Boolean} Indication if we've emitted an event. | |
| * @api public | |
| */ | |
| EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { | |
| var evt = prefix ? prefix + event : event; | |
| if (!this._events || !this._events[evt]) return false; | |
| var listeners = this._events[evt] | |
| , len = arguments.length | |
| , args | |
| , i; | |
| if ('function' === typeof listeners.fn) { | |
| if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); | |
| switch (len) { | |
| case 1: return listeners.fn.call(listeners.context), true; | |
| case 2: return listeners.fn.call(listeners.context, a1), true; | |
| case 3: return listeners.fn.call(listeners.context, a1, a2), true; | |
| case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; | |
| case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; | |
| case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; | |
| } | |
| for (i = 1, args = new Array(len -1); i < len; i++) { | |
| args[i - 1] = arguments[i]; | |
| } | |
| listeners.fn.apply(listeners.context, args); | |
| } else { | |
| var length = listeners.length | |
| , j; | |
| for (i = 0; i < length; i++) { | |
| if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); | |
| switch (len) { | |
| case 1: listeners[i].fn.call(listeners[i].context); break; | |
| case 2: listeners[i].fn.call(listeners[i].context, a1); break; | |
| case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; | |
| default: | |
| if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { | |
| args[j - 1] = arguments[j]; | |
| } | |
| listeners[i].fn.apply(listeners[i].context, args); | |
| } | |
| } | |
| } | |
| return true; | |
| }; | |
| /** | |
| * Register a new EventListener for the given event. | |
| * | |
| * @param {String} event Name of the event. | |
| * @param {Function} fn Callback function. | |
| * @param {Mixed} [context=this] The context of the function. | |
| * @api public | |
| */ | |
| EventEmitter.prototype.on = function on(event, fn, context) { | |
| var listener = new EE(fn, context || this) | |
| , evt = prefix ? prefix + event : event; | |
| if (!this._events) this._events = prefix ? {} : Object.create(null); | |
| if (!this._events[evt]) this._events[evt] = listener; | |
| else { | |
| if (!this._events[evt].fn) this._events[evt].push(listener); | |
| else this._events[evt] = [ | |
| this._events[evt], listener | |
| ]; | |
| } | |
| return this; | |
| }; | |
| /** | |
| * Add an EventListener that's only called once. | |
| * | |
| * @param {String} event Name of the event. | |
| * @param {Function} fn Callback function. | |
| * @param {Mixed} [context=this] The context of the function. | |
| * @api public | |
| */ | |
| EventEmitter.prototype.once = function once(event, fn, context) { | |
| var listener = new EE(fn, context || this, true) | |
| , evt = prefix ? prefix + event : event; | |
| if (!this._events) this._events = prefix ? {} : Object.create(null); | |
| if (!this._events[evt]) this._events[evt] = listener; | |
| else { | |
| if (!this._events[evt].fn) this._events[evt].push(listener); | |
| else this._events[evt] = [ | |
| this._events[evt], listener | |
| ]; | |
| } | |
| return this; | |
| }; | |
| /** | |
| * Remove event listeners. | |
| * | |
| * @param {String} event The event we want to remove. | |
| * @param {Function} fn The listener that we need to find. | |
| * @param {Mixed} context Only remove listeners matching this context. | |
| * @param {Boolean} once Only remove once listeners. | |
| * @api public | |
| */ | |
| EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { | |
| var evt = prefix ? prefix + event : event; | |
| if (!this._events || !this._events[evt]) return this; | |
| var listeners = this._events[evt] | |
| , events = []; | |
| if (fn) { | |
| if (listeners.fn) { | |
| if ( | |
| listeners.fn !== fn | |
| || (once && !listeners.once) | |
| || (context && listeners.context !== context) | |
| ) { | |
| events.push(listeners); | |
| } | |
| } else { | |
| for (var i = 0, length = listeners.length; i < length; i++) { | |
| if ( | |
| listeners[i].fn !== fn | |
| || (once && !listeners[i].once) | |
| || (context && listeners[i].context !== context) | |
| ) { | |
| events.push(listeners[i]); | |
| } | |
| } | |
| } | |
| } | |
| // | |
| // Reset the array, or remove it completely if we have no more listeners. | |
| // | |
| if (events.length) { | |
| this._events[evt] = events.length === 1 ? events[0] : events; | |
| } else { | |
| delete this._events[evt]; | |
| } | |
| return this; | |
| }; | |
| /** | |
| * Remove all listeners or only the listeners for the specified event. | |
| * | |
| * @param {String} event The event want to remove all listeners for. | |
| * @api public | |
| */ | |
| EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { | |
| if (!this._events) return this; | |
| if (event) delete this._events[prefix ? prefix + event : event]; | |
| else this._events = prefix ? {} : Object.create(null); | |
| return this; | |
| }; | |
| // | |
| // Alias methods names because people roll like that. | |
| // | |
| EventEmitter.prototype.off = EventEmitter.prototype.removeListener; | |
| EventEmitter.prototype.addListener = EventEmitter.prototype.on; | |
| // | |
| // This function doesn't apply anymore. | |
| // | |
| EventEmitter.prototype.setMaxListeners = function setMaxListeners() { | |
| return this; | |
| }; | |
| // | |
| // Expose the prefix. | |
| // | |
| EventEmitter.prefixed = prefix; | |
| // | |
| // Expose the module. | |
| // | |
| if ('undefined' !== typeof module) { | |
| module.exports = EventEmitter; | |
| } | |