1+ // From https://github.com/primus/eventemitter3/
2+
3+ 'use strict' ;
4+
5+ var has = Object . prototype . hasOwnProperty
6+ , prefix = '~' ;
7+
8+ /**
9+ * Constructor to create a storage for our `EE` objects.
10+ * An `Events` instance is a plain object whose properties are event names.
11+ *
12+ * @constructor
13+ * @private
14+ */
15+ function Events ( ) { }
16+
17+ //
18+ // We try to not inherit from `Object.prototype`. In some engines creating an
19+ // instance in this way is faster than calling `Object.create(null)` directly.
20+ // If `Object.create(null)` is not supported we prefix the event names with a
21+ // character to make sure that the built-in object properties are not
22+ // overridden or used as an attack vector.
23+ //
24+ if ( Object . create ) {
25+ Events . prototype = Object . create ( null ) ;
26+
27+ //
28+ // This hack is needed because the `__proto__` property is still inherited in
29+ // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
30+ //
31+ if ( ! new Events ( ) . __proto__ ) prefix = false ;
32+ }
33+
34+ /**
35+ * Representation of a single event listener.
36+ *
37+ * @param {Function } fn The listener function.
38+ * @param {* } context The context to invoke the listener with.
39+ * @param {Boolean } [once=false] Specify if the listener is a one-time listener.
40+ * @constructor
41+ * @private
42+ */
43+ function EE ( fn , context , once ) {
44+ this . fn = fn ;
45+ this . context = context ;
46+ this . once = once || false ;
47+ }
48+
49+ /**
50+ * Add a listener for a given event.
51+ *
52+ * @param {EventEmitter } emitter Reference to the `EventEmitter` instance.
53+ * @param {(String|Symbol) } event The event name.
54+ * @param {Function } fn The listener function.
55+ * @param {* } context The context to invoke the listener with.
56+ * @param {Boolean } once Specify if the listener is a one-time listener.
57+ * @returns {EventEmitter }
58+ * @private
59+ */
60+ function addListener ( emitter , event , fn , context , once ) {
61+ if ( typeof fn !== 'function' ) {
62+ throw new TypeError ( 'The listener must be a function' ) ;
63+ }
64+
65+ var listener = new EE ( fn , context || emitter , once )
66+ , evt = prefix ? prefix + event : event ;
67+
68+ if ( ! emitter . _events [ evt ] ) emitter . _events [ evt ] = listener , emitter . _eventsCount ++ ;
69+ else if ( ! emitter . _events [ evt ] . fn ) emitter . _events [ evt ] . push ( listener ) ;
70+ else emitter . _events [ evt ] = [ emitter . _events [ evt ] , listener ] ;
71+
72+ return emitter ;
73+ }
74+
75+ /**
76+ * Clear event by name.
77+ *
78+ * @param {EventEmitter } emitter Reference to the `EventEmitter` instance.
79+ * @param {(String|Symbol) } evt The Event name.
80+ * @private
81+ */
82+ function clearEvent ( emitter , evt ) {
83+ if ( -- emitter . _eventsCount === 0 ) emitter . _events = new Events ( ) ;
84+ else delete emitter . _events [ evt ] ;
85+ }
86+
87+ /**
88+ * Minimal `EventEmitter` interface that is molded against the Node.js
89+ * `EventEmitter` interface.
90+ *
91+ * @constructor
92+ * @public
93+ */
94+ function EventEmitter ( ) {
95+ this . _events = new Events ( ) ;
96+ this . _eventsCount = 0 ;
97+ }
98+
99+ /**
100+ * Return an array listing the events for which the emitter has registered
101+ * listeners.
102+ *
103+ * @returns {Array }
104+ * @public
105+ */
106+ EventEmitter . prototype . eventNames = function eventNames ( ) {
107+ var names = [ ]
108+ , events
109+ , name ;
110+
111+ if ( this . _eventsCount === 0 ) return names ;
112+
113+ for ( name in ( events = this . _events ) ) {
114+ if ( has . call ( events , name ) ) names . push ( prefix ? name . slice ( 1 ) : name ) ;
115+ }
116+
117+ if ( Object . getOwnPropertySymbols ) {
118+ return names . concat ( Object . getOwnPropertySymbols ( events ) ) ;
119+ }
120+
121+ return names ;
122+ } ;
123+
124+ /**
125+ * Return the listeners registered for a given event.
126+ *
127+ * @param {(String|Symbol) } event The event name.
128+ * @returns {Array } The registered listeners.
129+ * @public
130+ */
131+ EventEmitter . prototype . listeners = function listeners ( event ) {
132+ var evt = prefix ? prefix + event : event
133+ , handlers = this . _events [ evt ] ;
134+
135+ if ( ! handlers ) return [ ] ;
136+ if ( handlers . fn ) return [ handlers . fn ] ;
137+
138+ for ( var i = 0 , l = handlers . length , ee = new Array ( l ) ; i < l ; i ++ ) {
139+ ee [ i ] = handlers [ i ] . fn ;
140+ }
141+
142+ return ee ;
143+ } ;
144+
145+ /**
146+ * Return the number of listeners listening to a given event.
147+ *
148+ * @param {(String|Symbol) } event The event name.
149+ * @returns {Number } The number of listeners.
150+ * @public
151+ */
152+ EventEmitter . prototype . listenerCount = function listenerCount ( event ) {
153+ var evt = prefix ? prefix + event : event
154+ , listeners = this . _events [ evt ] ;
155+
156+ if ( ! listeners ) return 0 ;
157+ if ( listeners . fn ) return 1 ;
158+ return listeners . length ;
159+ } ;
160+
161+ /**
162+ * Calls each of the listeners registered for a given event.
163+ *
164+ * @param {(String|Symbol) } event The event name.
165+ * @returns {Boolean } `true` if the event had listeners, else `false`.
166+ * @public
167+ */
168+ EventEmitter . prototype . emit = function emit ( event , a1 , a2 , a3 , a4 , a5 ) {
169+ var evt = prefix ? prefix + event : event ;
170+
171+ if ( ! this . _events [ evt ] ) return false ;
172+
173+ var listeners = this . _events [ evt ]
174+ , len = arguments . length
175+ , args
176+ , i ;
177+
178+ if ( listeners . fn ) {
179+ if ( listeners . once ) this . removeListener ( event , listeners . fn , undefined , true ) ;
180+
181+ switch ( len ) {
182+ case 1 : return listeners . fn . call ( listeners . context ) , true ;
183+ case 2 : return listeners . fn . call ( listeners . context , a1 ) , true ;
184+ case 3 : return listeners . fn . call ( listeners . context , a1 , a2 ) , true ;
185+ case 4 : return listeners . fn . call ( listeners . context , a1 , a2 , a3 ) , true ;
186+ case 5 : return listeners . fn . call ( listeners . context , a1 , a2 , a3 , a4 ) , true ;
187+ case 6 : return listeners . fn . call ( listeners . context , a1 , a2 , a3 , a4 , a5 ) , true ;
188+ }
189+
190+ for ( i = 1 , args = new Array ( len - 1 ) ; i < len ; i ++ ) {
191+ args [ i - 1 ] = arguments [ i ] ;
192+ }
193+
194+ listeners . fn . apply ( listeners . context , args ) ;
195+ } else {
196+ var length = listeners . length
197+ , j ;
198+
199+ for ( i = 0 ; i < length ; i ++ ) {
200+ if ( listeners [ i ] . once ) this . removeListener ( event , listeners [ i ] . fn , undefined , true ) ;
201+
202+ switch ( len ) {
203+ case 1 : listeners [ i ] . fn . call ( listeners [ i ] . context ) ; break ;
204+ case 2 : listeners [ i ] . fn . call ( listeners [ i ] . context , a1 ) ; break ;
205+ case 3 : listeners [ i ] . fn . call ( listeners [ i ] . context , a1 , a2 ) ; break ;
206+ case 4 : listeners [ i ] . fn . call ( listeners [ i ] . context , a1 , a2 , a3 ) ; break ;
207+ default :
208+ if ( ! args ) for ( j = 1 , args = new Array ( len - 1 ) ; j < len ; j ++ ) {
209+ args [ j - 1 ] = arguments [ j ] ;
210+ }
211+
212+ listeners [ i ] . fn . apply ( listeners [ i ] . context , args ) ;
213+ }
214+ }
215+ }
216+
217+ return true ;
218+ } ;
219+
220+ /**
221+ * Add a listener for a given event.
222+ *
223+ * @param {(String|Symbol) } event The event name.
224+ * @param {Function } fn The listener function.
225+ * @param {* } [context=this] The context to invoke the listener with.
226+ * @returns {EventEmitter } `this`.
227+ * @public
228+ */
229+ EventEmitter . prototype . on = function on ( event , fn , context ) {
230+ return addListener ( this , event , fn , context , false ) ;
231+ } ;
232+
233+ /**
234+ * Add a one-time listener for a given event.
235+ *
236+ * @param {(String|Symbol) } event The event name.
237+ * @param {Function } fn The listener function.
238+ * @param {* } [context=this] The context to invoke the listener with.
239+ * @returns {EventEmitter } `this`.
240+ * @public
241+ */
242+ EventEmitter . prototype . once = function once ( event , fn , context ) {
243+ return addListener ( this , event , fn , context , true ) ;
244+ } ;
245+
246+ /**
247+ * Remove the listeners of a given event.
248+ *
249+ * @param {(String|Symbol) } event The event name.
250+ * @param {Function } fn Only remove the listeners that match this function.
251+ * @param {* } context Only remove the listeners that have this context.
252+ * @param {Boolean } once Only remove one-time listeners.
253+ * @returns {EventEmitter } `this`.
254+ * @public
255+ */
256+ EventEmitter . prototype . removeListener = function removeListener ( event , fn , context , once ) {
257+ var evt = prefix ? prefix + event : event ;
258+
259+ if ( ! this . _events [ evt ] ) return this ;
260+ if ( ! fn ) {
261+ clearEvent ( this , evt ) ;
262+ return this ;
263+ }
264+
265+ var listeners = this . _events [ evt ] ;
266+
267+ if ( listeners . fn ) {
268+ if (
269+ listeners . fn === fn &&
270+ ( ! once || listeners . once ) &&
271+ ( ! context || listeners . context === context )
272+ ) {
273+ clearEvent ( this , evt ) ;
274+ }
275+ } else {
276+ for ( var i = 0 , events = [ ] , length = listeners . length ; i < length ; i ++ ) {
277+ if (
278+ listeners [ i ] . fn !== fn ||
279+ ( once && ! listeners [ i ] . once ) ||
280+ ( context && listeners [ i ] . context !== context )
281+ ) {
282+ events . push ( listeners [ i ] ) ;
283+ }
284+ }
285+
286+ //
287+ // Reset the array, or remove it completely if we have no more listeners.
288+ //
289+ if ( events . length ) this . _events [ evt ] = events . length === 1 ? events [ 0 ] : events ;
290+ else clearEvent ( this , evt ) ;
291+ }
292+
293+ return this ;
294+ } ;
295+
296+ /**
297+ * Remove all listeners, or those of the specified event.
298+ *
299+ * @param {(String|Symbol) } [event] The event name.
300+ * @returns {EventEmitter } `this`.
301+ * @public
302+ */
303+ EventEmitter . prototype . removeAllListeners = function removeAllListeners ( event ) {
304+ var evt ;
305+
306+ if ( event ) {
307+ evt = prefix ? prefix + event : event ;
308+ if ( this . _events [ evt ] ) clearEvent ( this , evt ) ;
309+ } else {
310+ this . _events = new Events ( ) ;
311+ this . _eventsCount = 0 ;
312+ }
313+
314+ return this ;
315+ } ;
316+
317+ //
318+ // Alias methods names because people roll like that.
319+ //
320+ EventEmitter . prototype . off = EventEmitter . prototype . removeListener ;
321+ EventEmitter . prototype . addListener = EventEmitter . prototype . on ;
322+
323+ //
324+ // Expose the prefix.
325+ //
326+ EventEmitter . prefixed = prefix ;
327+
328+ //
329+ // Allow `EventEmitter` to be imported as module namespace.
330+ //
331+ EventEmitter . EventEmitter = EventEmitter ;
332+
333+ //
334+ // Expose the module.
335+ //
336+ export { EventEmitter } ;
337+
338+ export default { EventEmitter } ;
0 commit comments