UNPKG

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