UNPKG

modularjs

Version:

Library for building events based apps

248 lines (214 loc) 6.58 kB
var EventEmitter = function(){ function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } this.before = function(type, listener){ if (!this._before) this._before = {}; if (!this._before[type]) // Optimize the case of one listener. Don't need the extra array object. this._before[type] = listener; else if (isObject(this._before[type])) // If we've already got an array, just append. this._before[type].push(listener); else // Adding the second element, need to change to array. this._before[type] = [this._before[type], listener]; // Check for listener leak if (isObject(this._before[type]) && !this._before[type].warned) { var m; if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = this.defaultMaxListeners; } if (m && m > 0 && this._before[type].length > m) { this._before[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._before[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; this.after = function(type, listener){ if (!this._after) this._after = {}; if (!this._after[type]) // Optimize the case of one listener. Don't need the extra array object. this._after[type] = listener; else if (isObject(this._after[type])) // If we've already got an array, just append. this._after[type].push(listener); else // Adding the second element, need to change to array. this._after[type] = [this._after[type], listener]; // Check for listener leak if (isObject(this._after[type]) && !this._after[type].warned) { var m; if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = this.defaultMaxListeners; } if (m && m > 0 && this._after[type].length > m) { this._after[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._after[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; this.emit = function(type) { var er, handler, len, args, i, listeners, beforeHandler; if (!this._events) this._events = {}; if (!this._before) this._before = {}; if (!this._after) this._after = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } throw TypeError('Uncaught, unspecified "error" event.'); } } handler = this._events[type]; beforeHandler = this._before[type]; afterHandler = this._after[type]; if (isUndefined(handler)) return false; //Call before event if (!isUndefined(beforeHandler)){ if (isFunction(beforeHandler)) { switch (arguments.length) { // fast cases case 1: beforeHandler.call(this); break; case 2: beforeHandler.call(this, arguments[1]); break; case 3: beforeHandler.call(this, arguments[1], arguments[2]); break; // slower default: len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; beforeHandler.apply(this, args); } } else if (isObject(beforeHandler)) { len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; listeners = beforeHandler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } } //Call on event if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; handler.apply(this, args); } } else if (isObject(handler)) { len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } //Call after event if (!isUndefined(afterHandler)){ if (isFunction(afterHandler)) { switch (arguments.length) { // fast cases case 1: afterHandler.call(this); break; case 2: afterHandler.call(this, arguments[1]); break; case 3: afterHandler.call(this, arguments[1], arguments[2]); break; // slower default: len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; afterHandler.apply(this, args); } } else if (isObject(afterHandler)) { len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; listeners = afterHandler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } } return true; }; this._before = {}; this._after = {}; } var Events = require('events'); EventEmitter.prototype = new Events(); module.exports = new EventEmitter();