events.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /**
  2. * Module exports.
  3. */
  4. exports.EventEmitter = EventEmitter;
  5. /**
  6. * Check if `obj` is an array.
  7. */
  8. function isArray(obj) {
  9. return '[object Array]' == {}.toString.call(obj);
  10. }
  11. /**
  12. * Event emitter constructor.
  13. *
  14. * @api public
  15. */
  16. function EventEmitter(){};
  17. /**
  18. * Adds a listener.
  19. *
  20. * @api public
  21. */
  22. EventEmitter.prototype.on = function (name, fn) {
  23. if (!this.$events) {
  24. this.$events = {};
  25. }
  26. if (!this.$events[name]) {
  27. this.$events[name] = fn;
  28. } else if (isArray(this.$events[name])) {
  29. this.$events[name].push(fn);
  30. } else {
  31. this.$events[name] = [this.$events[name], fn];
  32. }
  33. return this;
  34. };
  35. EventEmitter.prototype.addListener = EventEmitter.prototype.on;
  36. /**
  37. * Adds a volatile listener.
  38. *
  39. * @api public
  40. */
  41. EventEmitter.prototype.once = function (name, fn) {
  42. var self = this;
  43. function on () {
  44. self.removeListener(name, on);
  45. fn.apply(this, arguments);
  46. };
  47. on.listener = fn;
  48. this.on(name, on);
  49. return this;
  50. };
  51. /**
  52. * Removes a listener.
  53. *
  54. * @api public
  55. */
  56. EventEmitter.prototype.removeListener = function (name, fn) {
  57. if (this.$events && this.$events[name]) {
  58. var list = this.$events[name];
  59. if (isArray(list)) {
  60. var pos = -1;
  61. for (var i = 0, l = list.length; i < l; i++) {
  62. if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
  63. pos = i;
  64. break;
  65. }
  66. }
  67. if (pos < 0) {
  68. return this;
  69. }
  70. list.splice(pos, 1);
  71. if (!list.length) {
  72. delete this.$events[name];
  73. }
  74. } else if (list === fn || (list.listener && list.listener === fn)) {
  75. delete this.$events[name];
  76. }
  77. }
  78. return this;
  79. };
  80. /**
  81. * Removes all listeners for an event.
  82. *
  83. * @api public
  84. */
  85. EventEmitter.prototype.removeAllListeners = function (name) {
  86. if (name === undefined) {
  87. this.$events = {};
  88. return this;
  89. }
  90. if (this.$events && this.$events[name]) {
  91. this.$events[name] = null;
  92. }
  93. return this;
  94. };
  95. /**
  96. * Gets all listeners for a certain event.
  97. *
  98. * @api public
  99. */
  100. EventEmitter.prototype.listeners = function (name) {
  101. if (!this.$events) {
  102. this.$events = {};
  103. }
  104. if (!this.$events[name]) {
  105. this.$events[name] = [];
  106. }
  107. if (!isArray(this.$events[name])) {
  108. this.$events[name] = [this.$events[name]];
  109. }
  110. return this.$events[name];
  111. };
  112. /**
  113. * Emits an event.
  114. *
  115. * @api public
  116. */
  117. EventEmitter.prototype.emit = function (name) {
  118. if (!this.$events) {
  119. return false;
  120. }
  121. var handler = this.$events[name];
  122. if (!handler) {
  123. return false;
  124. }
  125. var args = [].slice.call(arguments, 1);
  126. if ('function' == typeof handler) {
  127. handler.apply(this, args);
  128. } else if (isArray(handler)) {
  129. var listeners = handler.slice();
  130. for (var i = 0, l = listeners.length; i < l; i++) {
  131. listeners[i].apply(this, args);
  132. }
  133. } else {
  134. return false;
  135. }
  136. return true;
  137. };