Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50641 views
1
;!function(exports, undefined) {
2
3
var isArray = Array.isArray ? Array.isArray : function _isArray(obj) {
4
return Object.prototype.toString.call(obj) === "[object Array]";
5
};
6
var defaultMaxListeners = 10;
7
8
function init() {
9
this._events = new Object;
10
}
11
12
function configure(conf) {
13
if (conf) {
14
conf.delimiter && (this.delimiter = conf.delimiter);
15
conf.wildcard && (this.wildcard = conf.wildcard);
16
if (this.wildcard) {
17
this.listenerTree = new Object;
18
}
19
}
20
}
21
22
function EventEmitter(conf) {
23
this._events = new Object;
24
configure.call(this, conf);
25
}
26
27
//
28
// Attention, function return type now is array, always !
29
// It has zero elements if no any matches found and one or more
30
// elements (leafs) if there are matches
31
//
32
function searchListenerTree(handlers, type, tree, i) {
33
if (!tree) {
34
return [];
35
}
36
var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached,
37
typeLength = type.length, currentType = type[i], nextType = type[i+1];
38
if (i === typeLength && tree._listeners) {
39
//
40
// If at the end of the event(s) list and the tree has listeners
41
// invoke those listeners.
42
//
43
if (typeof tree._listeners === 'function') {
44
handlers && handlers.push(tree._listeners);
45
return [tree];
46
} else {
47
for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) {
48
handlers && handlers.push(tree._listeners[leaf]);
49
}
50
return [tree];
51
}
52
}
53
54
if ((currentType === '*' || currentType === '**') || tree[currentType]) {
55
//
56
// If the event emitted is '*' at this part
57
// or there is a concrete match at this patch
58
//
59
if (currentType === '*') {
60
for (branch in tree) {
61
if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
62
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1));
63
}
64
}
65
return listeners;
66
} else if(currentType === '**') {
67
endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*'));
68
if(endReached && tree._listeners) {
69
// The next element has a _listeners, add it to the handlers.
70
listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength));
71
}
72
73
for (branch in tree) {
74
if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
75
if(branch === '*' || branch === '**') {
76
if(tree[branch]._listeners && !endReached) {
77
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength));
78
}
79
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
80
} else if(branch === nextType) {
81
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2));
82
} else {
83
// No match on this one, shift into the tree but not in the type array.
84
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
85
}
86
}
87
}
88
return listeners;
89
}
90
91
listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1));
92
}
93
94
xTree = tree['*'];
95
if (xTree) {
96
//
97
// If the listener tree will allow any match for this part,
98
// then recursively explore all branches of the tree
99
//
100
searchListenerTree(handlers, type, xTree, i+1);
101
}
102
103
xxTree = tree['**'];
104
if(xxTree) {
105
if(i < typeLength) {
106
if(xxTree._listeners) {
107
// If we have a listener on a '**', it will catch all, so add its handler.
108
searchListenerTree(handlers, type, xxTree, typeLength);
109
}
110
111
// Build arrays of matching next branches and others.
112
for(branch in xxTree) {
113
if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) {
114
if(branch === nextType) {
115
// We know the next element will match, so jump twice.
116
searchListenerTree(handlers, type, xxTree[branch], i+2);
117
} else if(branch === currentType) {
118
// Current node matches, move into the tree.
119
searchListenerTree(handlers, type, xxTree[branch], i+1);
120
} else {
121
isolatedBranch = {};
122
isolatedBranch[branch] = xxTree[branch];
123
searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1);
124
}
125
}
126
}
127
} else if(xxTree._listeners) {
128
// We have reached the end and still on a '**'
129
searchListenerTree(handlers, type, xxTree, typeLength);
130
} else if(xxTree['*'] && xxTree['*']._listeners) {
131
searchListenerTree(handlers, type, xxTree['*'], typeLength);
132
}
133
}
134
135
return listeners;
136
}
137
138
function growListenerTree(type, listener) {
139
140
type = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
141
142
//
143
// Looks for two consecutive '**', if so, don't add the event at all.
144
//
145
for(var i = 0, len = type.length; i+1 < len; i++) {
146
if(type[i] === '**' && type[i+1] === '**') {
147
return;
148
}
149
}
150
151
var tree = this.listenerTree;
152
var name = type.shift();
153
154
while (name) {
155
156
if (!tree[name]) {
157
tree[name] = new Object;
158
}
159
160
tree = tree[name];
161
162
if (type.length === 0) {
163
164
if (!tree._listeners) {
165
tree._listeners = listener;
166
}
167
else if(typeof tree._listeners === 'function') {
168
tree._listeners = [tree._listeners, listener];
169
}
170
else if (isArray(tree._listeners)) {
171
172
tree._listeners.push(listener);
173
174
if (!tree._listeners.warned) {
175
176
var m = defaultMaxListeners;
177
178
if (typeof this._events.maxListeners !== 'undefined') {
179
m = this._events.maxListeners;
180
}
181
182
if (m > 0 && tree._listeners.length > m) {
183
184
tree._listeners.warned = true;
185
console.error('(node) warning: possible EventEmitter memory ' +
186
'leak detected. %d listeners added. ' +
187
'Use emitter.setMaxListeners() to increase limit.',
188
tree._listeners.length);
189
console.trace();
190
}
191
}
192
}
193
return true;
194
}
195
name = type.shift();
196
}
197
return true;
198
};
199
200
// By default EventEmitters will print a warning if more than
201
// 10 listeners are added to it. This is a useful default which
202
// helps finding memory leaks.
203
//
204
// Obviously not all Emitters should be limited to 10. This function allows
205
// that to be increased. Set to zero for unlimited.
206
207
EventEmitter.prototype.delimiter = '.';
208
209
EventEmitter.prototype.setMaxListeners = function(n) {
210
this._events || init.call(this);
211
this._events.maxListeners = n;
212
};
213
214
EventEmitter.prototype.event = '';
215
216
EventEmitter.prototype.once = function(event, fn) {
217
this.many(event, 1, fn);
218
return this;
219
};
220
221
EventEmitter.prototype.many = function(event, ttl, fn) {
222
var self = this;
223
224
if (typeof fn !== 'function') {
225
throw new Error('many only accepts instances of Function');
226
}
227
228
function listener() {
229
if (--ttl === 0) {
230
self.off(event, listener);
231
}
232
fn.apply(this, arguments);
233
};
234
235
listener._origin = fn;
236
237
this.on(event, listener);
238
239
return self;
240
};
241
242
EventEmitter.prototype.emit = function() {
243
this._events || init.call(this);
244
245
var type = arguments[0];
246
247
if (type === 'newListener') {
248
if (!this._events.newListener) { return false; }
249
}
250
251
// Loop through the *_all* functions and invoke them.
252
if (this._all) {
253
var l = arguments.length;
254
var args = new Array(l - 1);
255
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
256
for (i = 0, l = this._all.length; i < l; i++) {
257
this.event = type;
258
this._all[i].apply(this, args);
259
}
260
}
261
262
// If there is no 'error' event listener then throw.
263
if (type === 'error') {
264
265
if (!this._all &&
266
!this._events.error &&
267
!(this.wildcard && this.listenerTree.error)) {
268
269
if (arguments[1] instanceof Error) {
270
throw arguments[1]; // Unhandled 'error' event
271
} else {
272
throw new Error("Uncaught, unspecified 'error' event.");
273
}
274
return false;
275
}
276
}
277
278
var handler;
279
280
if(this.wildcard) {
281
handler = [];
282
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
283
searchListenerTree.call(this, handler, ns, this.listenerTree, 0);
284
}
285
else {
286
handler = this._events[type];
287
}
288
289
if (typeof handler === 'function') {
290
this.event = type;
291
if (arguments.length === 1) {
292
handler.call(this);
293
}
294
else if (arguments.length > 1)
295
switch (arguments.length) {
296
case 2:
297
handler.call(this, arguments[1]);
298
break;
299
case 3:
300
handler.call(this, arguments[1], arguments[2]);
301
break;
302
// slower
303
default:
304
var l = arguments.length;
305
var args = new Array(l - 1);
306
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
307
handler.apply(this, args);
308
}
309
return true;
310
}
311
else if (handler) {
312
var l = arguments.length;
313
var args = new Array(l - 1);
314
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
315
316
var listeners = handler.slice();
317
for (var i = 0, l = listeners.length; i < l; i++) {
318
this.event = type;
319
listeners[i].apply(this, args);
320
}
321
return (listeners.length > 0) || this._all;
322
}
323
else {
324
return this._all;
325
}
326
327
};
328
329
EventEmitter.prototype.on = function(type, listener) {
330
331
if (typeof type === 'function') {
332
this.onAny(type);
333
return this;
334
}
335
336
if (typeof listener !== 'function') {
337
throw new Error('on only accepts instances of Function');
338
}
339
this._events || init.call(this);
340
341
// To avoid recursion in the case that type == "newListeners"! Before
342
// adding it to the listeners, first emit "newListeners".
343
this.emit('newListener', type, listener);
344
345
if(this.wildcard) {
346
growListenerTree.call(this, type, listener);
347
return this;
348
}
349
350
if (!this._events[type]) {
351
// Optimize the case of one listener. Don't need the extra array object.
352
this._events[type] = listener;
353
}
354
else if(typeof this._events[type] === 'function') {
355
// Adding the second element, need to change to array.
356
this._events[type] = [this._events[type], listener];
357
}
358
else if (isArray(this._events[type])) {
359
// If we've already got an array, just append.
360
this._events[type].push(listener);
361
362
// Check for listener leak
363
if (!this._events[type].warned) {
364
365
var m = defaultMaxListeners;
366
367
if (typeof this._events.maxListeners !== 'undefined') {
368
m = this._events.maxListeners;
369
}
370
371
if (m > 0 && this._events[type].length > m) {
372
373
this._events[type].warned = true;
374
console.error('(node) warning: possible EventEmitter memory ' +
375
'leak detected. %d listeners added. ' +
376
'Use emitter.setMaxListeners() to increase limit.',
377
this._events[type].length);
378
console.trace();
379
}
380
}
381
}
382
return this;
383
};
384
385
EventEmitter.prototype.onAny = function(fn) {
386
387
if(!this._all) {
388
this._all = [];
389
}
390
391
if (typeof fn !== 'function') {
392
throw new Error('onAny only accepts instances of Function');
393
}
394
395
// Add the function to the event listener collection.
396
this._all.push(fn);
397
return this;
398
};
399
400
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
401
402
EventEmitter.prototype.off = function(type, listener) {
403
if (typeof listener !== 'function') {
404
throw new Error('removeListener only takes instances of Function');
405
}
406
407
var handlers,leafs=[];
408
409
if(this.wildcard) {
410
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
411
leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
412
}
413
else {
414
// does not use listeners(), so no side effect of creating _events[type]
415
if (!this._events[type]) return this;
416
handlers = this._events[type];
417
leafs.push({_listeners:handlers});
418
}
419
420
for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
421
var leaf = leafs[iLeaf];
422
handlers = leaf._listeners;
423
if (isArray(handlers)) {
424
425
var position = -1;
426
427
for (var i = 0, length = handlers.length; i < length; i++) {
428
if (handlers[i] === listener ||
429
(handlers[i].listener && handlers[i].listener === listener) ||
430
(handlers[i]._origin && handlers[i]._origin === listener)) {
431
position = i;
432
break;
433
}
434
}
435
436
if (position < 0) {
437
return this;
438
}
439
440
if(this.wildcard) {
441
leaf._listeners.splice(position, 1)
442
}
443
else {
444
this._events[type].splice(position, 1);
445
}
446
447
if (handlers.length === 0) {
448
if(this.wildcard) {
449
delete leaf._listeners;
450
}
451
else {
452
delete this._events[type];
453
}
454
}
455
}
456
else if (handlers === listener ||
457
(handlers.listener && handlers.listener === listener) ||
458
(handlers._origin && handlers._origin === listener)) {
459
if(this.wildcard) {
460
delete leaf._listeners;
461
}
462
else {
463
delete this._events[type];
464
}
465
}
466
}
467
468
return this;
469
};
470
471
EventEmitter.prototype.offAny = function(fn) {
472
var i = 0, l = 0, fns;
473
if (fn && this._all && this._all.length > 0) {
474
fns = this._all;
475
for(i = 0, l = fns.length; i < l; i++) {
476
if(fn === fns[i]) {
477
fns.splice(i, 1);
478
return this;
479
}
480
}
481
} else {
482
this._all = [];
483
}
484
return this;
485
};
486
487
EventEmitter.prototype.removeListener = EventEmitter.prototype.off;
488
489
EventEmitter.prototype.removeAllListeners = function(type) {
490
if (arguments.length === 0) {
491
!this._events || init.call(this);
492
return this;
493
}
494
495
if(this.wildcard) {
496
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
497
var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
498
499
for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
500
var leaf = leafs[iLeaf];
501
leaf._listeners = null;
502
}
503
}
504
else {
505
if (!this._events[type]) return this;
506
this._events[type] = null;
507
}
508
return this;
509
};
510
511
EventEmitter.prototype.listeners = function(type) {
512
if(this.wildcard) {
513
var handlers = [];
514
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
515
searchListenerTree.call(this, handlers, ns, this.listenerTree, 0);
516
return handlers;
517
}
518
519
this._events || init.call(this);
520
521
if (!this._events[type]) this._events[type] = [];
522
if (!isArray(this._events[type])) {
523
this._events[type] = [this._events[type]];
524
}
525
return this._events[type];
526
};
527
528
EventEmitter.prototype.listenersAny = function() {
529
530
if(this._all) {
531
return this._all;
532
}
533
else {
534
return [];
535
}
536
537
};
538
539
if (typeof define === 'function' && define.amd) {
540
define(function() {
541
return EventEmitter;
542
});
543
} else {
544
exports.EventEmitter2 = EventEmitter;
545
}
546
547
}(typeof process !== 'undefined' && typeof process.title !== 'undefined' && typeof exports !== 'undefined' ? exports : window);
548
549