bus.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. (function(caller, bus) {
  2. if (typeof exports === "object" && typeof module === "object") {
  3. module.exports = bus();
  4. module.exports.default = module.exports
  5. } else if (typeof exports === "object") {
  6. exports.EventBus = bus()
  7. } else {
  8. caller.EventBus = bus()
  9. }
  10. })(this, function() {
  11. var EventBus = function() {
  12. this.listeners = {};
  13. this.registerListener = function(event, callback, number) {
  14. var type = event.constructor.name;
  15. number = this.validateNumber(number || "any");
  16. if (type !== "Array") {
  17. event = [event]
  18. }
  19. event.forEach(function(e) {
  20. if (e.constructor.name !== "String") {
  21. throw new Error("Only `String` and array of `String` are accepted for the event names!")
  22. }
  23. that.listeners[e] = that.listeners[e] || [];
  24. that.listeners[e].push({
  25. callback: callback,
  26. number: number
  27. })
  28. })
  29. };
  30. this.validateNumber = function(n) {
  31. var type = n.constructor.name;
  32. if (type === "Number") {
  33. return n
  34. } else if (type === "String" && n.toLowerCase() === "any") {
  35. return "any"
  36. }
  37. throw new Error("Only `Number` and `any` are accepted in the number of possible executions!")
  38. };
  39. this.toBeRemoved = function(info) {
  40. var number = info.number;
  41. info.execution = info.execution || 0;
  42. info.execution++;
  43. if (number === "any" || info.execution < number) {
  44. return false
  45. }
  46. return true
  47. };
  48. var that = this;
  49. return {
  50. on: function(eventName, callback) {
  51. that.registerListener.bind(that)(eventName, callback, "any")
  52. },
  53. once: function(eventName, callback) {
  54. that.registerListener.bind(that)(eventName, callback, 1)
  55. },
  56. exactly: function(number, eventName, callback) {
  57. that.registerListener.bind(that)(eventName, callback, number)
  58. },
  59. die: function(eventName) {
  60. delete that.listeners[eventName]
  61. },
  62. off: function(eventName) {
  63. this.die(eventName)
  64. },
  65. detach: function(eventName, callback) {
  66. if (callback === undefined) {
  67. that.listeners[eventName] = [];
  68. return true
  69. }
  70. for (var k in that.listeners[eventName]) {
  71. if (that.listeners[eventName].hasOwnProperty(k) && that.listeners[eventName][k].callback === callback) {
  72. that.listeners[eventName].splice(k, 1);
  73. return this.detach(eventName, callback)
  74. }
  75. }
  76. return true
  77. },
  78. detachAll: function() {
  79. for (var eventName in that.listeners) {
  80. if (that.listeners.hasOwnProperty(eventName)) {
  81. this.detach(eventName)
  82. }
  83. }
  84. },
  85. emit: function(eventName, context) {
  86. var listeners = [];
  87. for (var name in that.listeners) {
  88. if (that.listeners.hasOwnProperty(name)) {
  89. if (name === eventName) {
  90. Array.prototype.push.apply(listeners, that.listeners[name])
  91. }
  92. if (name.indexOf("*") >= 0) {
  93. var newName = name.replace(/\*\*/, "([^.]+.?)+");
  94. newName = newName.replace(/\*/g, "[^.]+");
  95. var match = eventName.match(newName);
  96. if (match && eventName === match[0]) {
  97. Array.prototype.push.apply(listeners, that.listeners[name])
  98. }
  99. }
  100. }
  101. }
  102. var parentArgs = arguments;
  103. context = context || this;
  104. listeners.forEach(function(info, index) {
  105. var callback = info.callback;
  106. var number = info.number;
  107. if (context) {
  108. callback = callback.bind(context)
  109. }
  110. var args = [];
  111. Object.keys(parentArgs).map(function(i) {
  112. if (i > 1) {
  113. args.push(parentArgs[i])
  114. }
  115. });
  116. if (that.toBeRemoved(info)) {
  117. that.listeners[eventName].splice(index, 1)
  118. }
  119. callback.apply(null, args)
  120. })
  121. }
  122. }
  123. };
  124. return EventBus
  125. });