index.js (3181B)
1 2 /** 3 * Expose `Emitter`. 4 */ 5 6 if (typeof module !== 'undefined') { 7 module.exports = Emitter; 8 } 9 10 /** 11 * Initialize a new `Emitter`. 12 * 13 * @api public 14 */ 15 16 function Emitter(obj) { 17 if (obj) return mixin(obj); 18 }; 19 20 /** 21 * Mixin the emitter properties. 22 * 23 * @param {Object} obj 24 * @return {Object} 25 * @api private 26 */ 27 28 function mixin(obj) { 29 for (var key in Emitter.prototype) { 30 obj[key] = Emitter.prototype[key]; 31 } 32 return obj; 33 } 34 35 /** 36 * Listen on the given `event` with `fn`. 37 * 38 * @param {String} event 39 * @param {Function} fn 40 * @return {Emitter} 41 * @api public 42 */ 43 44 Emitter.prototype.on = 45 Emitter.prototype.addEventListener = function(event, fn){ 46 this._callbacks = this._callbacks || {}; 47 (this._callbacks['$' + event] = this._callbacks['$' + event] || []) 48 .push(fn); 49 return this; 50 }; 51 52 /** 53 * Adds an `event` listener that will be invoked a single 54 * time then automatically removed. 55 * 56 * @param {String} event 57 * @param {Function} fn 58 * @return {Emitter} 59 * @api public 60 */ 61 62 Emitter.prototype.once = function(event, fn){ 63 function on() { 64 this.off(event, on); 65 fn.apply(this, arguments); 66 } 67 68 on.fn = fn; 69 this.on(event, on); 70 return this; 71 }; 72 73 /** 74 * Remove the given callback for `event` or all 75 * registered callbacks. 76 * 77 * @param {String} event 78 * @param {Function} fn 79 * @return {Emitter} 80 * @api public 81 */ 82 83 Emitter.prototype.off = 84 Emitter.prototype.removeListener = 85 Emitter.prototype.removeAllListeners = 86 Emitter.prototype.removeEventListener = function(event, fn){ 87 this._callbacks = this._callbacks || {}; 88 89 // all 90 if (0 == arguments.length) { 91 this._callbacks = {}; 92 return this; 93 } 94 95 // specific event 96 var callbacks = this._callbacks['$' + event]; 97 if (!callbacks) return this; 98 99 // remove all handlers 100 if (1 == arguments.length) { 101 delete this._callbacks['$' + event]; 102 return this; 103 } 104 105 // remove specific handler 106 var cb; 107 for (var i = 0; i < callbacks.length; i++) { 108 cb = callbacks[i]; 109 if (cb === fn || cb.fn === fn) { 110 callbacks.splice(i, 1); 111 break; 112 } 113 } 114 return this; 115 }; 116 117 /** 118 * Emit `event` with the given args. 119 * 120 * @param {String} event 121 * @param {Mixed} ... 122 * @return {Emitter} 123 */ 124 125 Emitter.prototype.emit = function(event){ 126 this._callbacks = this._callbacks || {}; 127 var args = [].slice.call(arguments, 1) 128 , callbacks = this._callbacks['$' + event]; 129 130 if (callbacks) { 131 callbacks = callbacks.slice(0); 132 for (var i = 0, len = callbacks.length; i < len; ++i) { 133 callbacks[i].apply(this, args); 134 } 135 } 136 137 return this; 138 }; 139 140 /** 141 * Return array of callbacks for `event`. 142 * 143 * @param {String} event 144 * @return {Array} 145 * @api public 146 */ 147 148 Emitter.prototype.listeners = function(event){ 149 this._callbacks = this._callbacks || {}; 150 return this._callbacks['$' + event] || []; 151 }; 152 153 /** 154 * Check if this emitter has `event` handlers. 155 * 156 * @param {String} event 157 * @return {Boolean} 158 * @api public 159 */ 160 161 Emitter.prototype.hasListeners = function(event){ 162 return !! this.listeners(event).length; 163 };