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