Source: utils/EventEmitter.js

  1. (function() {
  2. /**
  3. * EventEmitter utility.
  4. * @constructor
  5. */
  6. tracking.EventEmitter = function() {};
  7. /**
  8. * Holds event listeners scoped by event type.
  9. * @type {object}
  10. * @private
  11. */
  12. tracking.EventEmitter.prototype.events_ = null;
  13. /**
  14. * Adds a listener to the end of the listeners array for the specified event.
  15. * @param {string} event
  16. * @param {function} listener
  17. * @return {object} Returns emitter, so calls can be chained.
  18. */
  19. tracking.EventEmitter.prototype.addListener = function(event, listener) {
  20. if (typeof listener !== 'function') {
  21. throw new TypeError('Listener must be a function');
  22. }
  23. if (!this.events_) {
  24. this.events_ = {};
  25. }
  26. this.emit('newListener', event, listener);
  27. if (!this.events_[event]) {
  28. this.events_[event] = [];
  29. }
  30. this.events_[event].push(listener);
  31. return this;
  32. };
  33. /**
  34. * Returns an array of listeners for the specified event.
  35. * @param {string} event
  36. * @return {array} Array of listeners.
  37. */
  38. tracking.EventEmitter.prototype.listeners = function(event) {
  39. return this.events_ && this.events_[event];
  40. };
  41. /**
  42. * Execute each of the listeners in order with the supplied arguments.
  43. * @param {string} event
  44. * @param {*} opt_args [arg1], [arg2], [...]
  45. * @return {boolean} Returns true if event had listeners, false otherwise.
  46. */
  47. tracking.EventEmitter.prototype.emit = function(event) {
  48. var listeners = this.listeners(event);
  49. if (listeners) {
  50. var args = Array.prototype.slice.call(arguments, 1);
  51. for (var i = 0; i < listeners.length; i++) {
  52. if (listeners[i]) {
  53. listeners[i].apply(this, args);
  54. }
  55. }
  56. return true;
  57. }
  58. return false;
  59. };
  60. /**
  61. * Adds a listener to the end of the listeners array for the specified event.
  62. * @param {string} event
  63. * @param {function} listener
  64. * @return {object} Returns emitter, so calls can be chained.
  65. */
  66. tracking.EventEmitter.prototype.on = tracking.EventEmitter.prototype.addListener;
  67. /**
  68. * Adds a one time listener for the event. This listener is invoked only the
  69. * next time the event is fired, after which it is removed.
  70. * @param {string} event
  71. * @param {function} listener
  72. * @return {object} Returns emitter, so calls can be chained.
  73. */
  74. tracking.EventEmitter.prototype.once = function(event, listener) {
  75. var self = this;
  76. self.on(event, function handlerInternal() {
  77. self.removeListener(event, handlerInternal);
  78. listener.apply(this, arguments);
  79. });
  80. };
  81. /**
  82. * Removes all listeners, or those of the specified event. It's not a good
  83. * idea to remove listeners that were added elsewhere in the code,
  84. * especially when it's on an emitter that you didn't create.
  85. * @param {string} event
  86. * @return {object} Returns emitter, so calls can be chained.
  87. */
  88. tracking.EventEmitter.prototype.removeAllListeners = function(opt_event) {
  89. if (!this.events_) {
  90. return this;
  91. }
  92. if (opt_event) {
  93. delete this.events_[opt_event];
  94. } else {
  95. delete this.events_;
  96. }
  97. return this;
  98. };
  99. /**
  100. * Remove a listener from the listener array for the specified event.
  101. * Caution: changes array indices in the listener array behind the listener.
  102. * @param {string} event
  103. * @param {function} listener
  104. * @return {object} Returns emitter, so calls can be chained.
  105. */
  106. tracking.EventEmitter.prototype.removeListener = function(event, listener) {
  107. if (typeof listener !== 'function') {
  108. throw new TypeError('Listener must be a function');
  109. }
  110. if (!this.events_) {
  111. return this;
  112. }
  113. var listeners = this.listeners(event);
  114. if (Array.isArray(listeners)) {
  115. var i = listeners.indexOf(listener);
  116. if (i < 0) {
  117. return this;
  118. }
  119. listeners.splice(i, 1);
  120. }
  121. return this;
  122. };
  123. /**
  124. * By default EventEmitters will print a warning if more than 10 listeners
  125. * are added for a particular event. This is a useful default which helps
  126. * finding memory leaks. Obviously not all Emitters should be limited to 10.
  127. * This function allows that to be increased. Set to zero for unlimited.
  128. * @param {number} n The maximum number of listeners.
  129. */
  130. tracking.EventEmitter.prototype.setMaxListeners = function() {
  131. throw new Error('Not implemented');
  132. };
  133. }());