You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
3.8 KiB

4 years ago
  1. 'use strict';
  2. /**
  3. * Class representing an event.
  4. *
  5. * @private
  6. */
  7. class Event {
  8. /**
  9. * Create a new `Event`.
  10. *
  11. * @param {String} type The name of the event
  12. * @param {Object} target A reference to the target to which the event was dispatched
  13. */
  14. constructor(type, target) {
  15. this.target = target;
  16. this.type = type;
  17. }
  18. }
  19. /**
  20. * Class representing a message event.
  21. *
  22. * @extends Event
  23. * @private
  24. */
  25. class MessageEvent extends Event {
  26. /**
  27. * Create a new `MessageEvent`.
  28. *
  29. * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data
  30. * @param {WebSocket} target A reference to the target to which the event was dispatched
  31. */
  32. constructor(data, target) {
  33. super('message', target);
  34. this.data = data;
  35. }
  36. }
  37. /**
  38. * Class representing a close event.
  39. *
  40. * @extends Event
  41. * @private
  42. */
  43. class CloseEvent extends Event {
  44. /**
  45. * Create a new `CloseEvent`.
  46. *
  47. * @param {Number} code The status code explaining why the connection is being closed
  48. * @param {String} reason A human-readable string explaining why the connection is closing
  49. * @param {WebSocket} target A reference to the target to which the event was dispatched
  50. */
  51. constructor(code, reason, target) {
  52. super('close', target);
  53. this.wasClean = target._closeFrameReceived && target._closeFrameSent;
  54. this.reason = reason;
  55. this.code = code;
  56. }
  57. }
  58. /**
  59. * Class representing an open event.
  60. *
  61. * @extends Event
  62. * @private
  63. */
  64. class OpenEvent extends Event {
  65. /**
  66. * Create a new `OpenEvent`.
  67. *
  68. * @param {WebSocket} target A reference to the target to which the event was dispatched
  69. */
  70. constructor(target) {
  71. super('open', target);
  72. }
  73. }
  74. /**
  75. * Class representing an error event.
  76. *
  77. * @extends Event
  78. * @private
  79. */
  80. class ErrorEvent extends Event {
  81. /**
  82. * Create a new `ErrorEvent`.
  83. *
  84. * @param {Object} error The error that generated this event
  85. * @param {WebSocket} target A reference to the target to which the event was dispatched
  86. */
  87. constructor(error, target) {
  88. super('error', target);
  89. this.message = error.message;
  90. this.error = error;
  91. }
  92. }
  93. /**
  94. * This provides methods for emulating the `EventTarget` interface. It's not
  95. * meant to be used directly.
  96. *
  97. * @mixin
  98. */
  99. const EventTarget = {
  100. /**
  101. * Register an event listener.
  102. *
  103. * @param {String} method A string representing the event type to listen for
  104. * @param {Function} listener The listener to add
  105. * @public
  106. */
  107. addEventListener(method, listener) {
  108. if (typeof listener !== 'function') return;
  109. function onMessage(data) {
  110. listener.call(this, new MessageEvent(data, this));
  111. }
  112. function onClose(code, message) {
  113. listener.call(this, new CloseEvent(code, message, this));
  114. }
  115. function onError(error) {
  116. listener.call(this, new ErrorEvent(error, this));
  117. }
  118. function onOpen() {
  119. listener.call(this, new OpenEvent(this));
  120. }
  121. if (method === 'message') {
  122. onMessage._listener = listener;
  123. this.on(method, onMessage);
  124. } else if (method === 'close') {
  125. onClose._listener = listener;
  126. this.on(method, onClose);
  127. } else if (method === 'error') {
  128. onError._listener = listener;
  129. this.on(method, onError);
  130. } else if (method === 'open') {
  131. onOpen._listener = listener;
  132. this.on(method, onOpen);
  133. } else {
  134. this.on(method, listener);
  135. }
  136. },
  137. /**
  138. * Remove an event listener.
  139. *
  140. * @param {String} method A string representing the event type to remove
  141. * @param {Function} listener The listener to remove
  142. * @public
  143. */
  144. removeEventListener(method, listener) {
  145. const listeners = this.listeners(method);
  146. for (var i = 0; i < listeners.length; i++) {
  147. if (listeners[i] === listener || listeners[i]._listener === listener) {
  148. this.removeListener(method, listeners[i]);
  149. }
  150. }
  151. }
  152. };
  153. module.exports = EventTarget;