| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 | 
							- 'use strict';
 
- const { kForOnEventAttribute, kListener } = require('./constants');
 
- const kCode = Symbol('kCode');
 
- const kData = Symbol('kData');
 
- const kError = Symbol('kError');
 
- const kMessage = Symbol('kMessage');
 
- const kReason = Symbol('kReason');
 
- const kTarget = Symbol('kTarget');
 
- const kType = Symbol('kType');
 
- const kWasClean = Symbol('kWasClean');
 
- /**
 
-  * Class representing an event.
 
-  */
 
- class Event {
 
-   /**
 
-    * Create a new `Event`.
 
-    *
 
-    * @param {String} type The name of the event
 
-    * @throws {TypeError} If the `type` argument is not specified
 
-    */
 
-   constructor(type) {
 
-     this[kTarget] = null;
 
-     this[kType] = type;
 
-   }
 
-   /**
 
-    * @type {*}
 
-    */
 
-   get target() {
 
-     return this[kTarget];
 
-   }
 
-   /**
 
-    * @type {String}
 
-    */
 
-   get type() {
 
-     return this[kType];
 
-   }
 
- }
 
- Object.defineProperty(Event.prototype, 'target', { enumerable: true });
 
- Object.defineProperty(Event.prototype, 'type', { enumerable: true });
 
- /**
 
-  * Class representing a close event.
 
-  *
 
-  * @extends Event
 
-  */
 
- class CloseEvent extends Event {
 
-   /**
 
-    * Create a new `CloseEvent`.
 
-    *
 
-    * @param {String} type The name of the event
 
-    * @param {Object} [options] A dictionary object that allows for setting
 
-    *     attributes via object members of the same name
 
-    * @param {Number} [options.code=0] The status code explaining why the
 
-    *     connection was closed
 
-    * @param {String} [options.reason=''] A human-readable string explaining why
 
-    *     the connection was closed
 
-    * @param {Boolean} [options.wasClean=false] Indicates whether or not the
 
-    *     connection was cleanly closed
 
-    */
 
-   constructor(type, options = {}) {
 
-     super(type);
 
-     this[kCode] = options.code === undefined ? 0 : options.code;
 
-     this[kReason] = options.reason === undefined ? '' : options.reason;
 
-     this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;
 
-   }
 
-   /**
 
-    * @type {Number}
 
-    */
 
-   get code() {
 
-     return this[kCode];
 
-   }
 
-   /**
 
-    * @type {String}
 
-    */
 
-   get reason() {
 
-     return this[kReason];
 
-   }
 
-   /**
 
-    * @type {Boolean}
 
-    */
 
-   get wasClean() {
 
-     return this[kWasClean];
 
-   }
 
- }
 
- Object.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });
 
- Object.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });
 
- Object.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });
 
- /**
 
-  * Class representing an error event.
 
-  *
 
-  * @extends Event
 
-  */
 
- class ErrorEvent extends Event {
 
-   /**
 
-    * Create a new `ErrorEvent`.
 
-    *
 
-    * @param {String} type The name of the event
 
-    * @param {Object} [options] A dictionary object that allows for setting
 
-    *     attributes via object members of the same name
 
-    * @param {*} [options.error=null] The error that generated this event
 
-    * @param {String} [options.message=''] The error message
 
-    */
 
-   constructor(type, options = {}) {
 
-     super(type);
 
-     this[kError] = options.error === undefined ? null : options.error;
 
-     this[kMessage] = options.message === undefined ? '' : options.message;
 
-   }
 
-   /**
 
-    * @type {*}
 
-    */
 
-   get error() {
 
-     return this[kError];
 
-   }
 
-   /**
 
-    * @type {String}
 
-    */
 
-   get message() {
 
-     return this[kMessage];
 
-   }
 
- }
 
- Object.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });
 
- Object.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });
 
- /**
 
-  * Class representing a message event.
 
-  *
 
-  * @extends Event
 
-  */
 
- class MessageEvent extends Event {
 
-   /**
 
-    * Create a new `MessageEvent`.
 
-    *
 
-    * @param {String} type The name of the event
 
-    * @param {Object} [options] A dictionary object that allows for setting
 
-    *     attributes via object members of the same name
 
-    * @param {*} [options.data=null] The message content
 
-    */
 
-   constructor(type, options = {}) {
 
-     super(type);
 
-     this[kData] = options.data === undefined ? null : options.data;
 
-   }
 
-   /**
 
-    * @type {*}
 
-    */
 
-   get data() {
 
-     return this[kData];
 
-   }
 
- }
 
- Object.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });
 
- /**
 
-  * This provides methods for emulating the `EventTarget` interface. It's not
 
-  * meant to be used directly.
 
-  *
 
-  * @mixin
 
-  */
 
- const EventTarget = {
 
-   /**
 
-    * Register an event listener.
 
-    *
 
-    * @param {String} type A string representing the event type to listen for
 
-    * @param {(Function|Object)} handler The listener to add
 
-    * @param {Object} [options] An options object specifies characteristics about
 
-    *     the event listener
 
-    * @param {Boolean} [options.once=false] A `Boolean` indicating that the
 
-    *     listener should be invoked at most once after being added. If `true`,
 
-    *     the listener would be automatically removed when invoked.
 
-    * @public
 
-    */
 
-   addEventListener(type, handler, options = {}) {
 
-     for (const listener of this.listeners(type)) {
 
-       if (
 
-         !options[kForOnEventAttribute] &&
 
-         listener[kListener] === handler &&
 
-         !listener[kForOnEventAttribute]
 
-       ) {
 
-         return;
 
-       }
 
-     }
 
-     let wrapper;
 
-     if (type === 'message') {
 
-       wrapper = function onMessage(data, isBinary) {
 
-         const event = new MessageEvent('message', {
 
-           data: isBinary ? data : data.toString()
 
-         });
 
-         event[kTarget] = this;
 
-         callListener(handler, this, event);
 
-       };
 
-     } else if (type === 'close') {
 
-       wrapper = function onClose(code, message) {
 
-         const event = new CloseEvent('close', {
 
-           code,
 
-           reason: message.toString(),
 
-           wasClean: this._closeFrameReceived && this._closeFrameSent
 
-         });
 
-         event[kTarget] = this;
 
-         callListener(handler, this, event);
 
-       };
 
-     } else if (type === 'error') {
 
-       wrapper = function onError(error) {
 
-         const event = new ErrorEvent('error', {
 
-           error,
 
-           message: error.message
 
-         });
 
-         event[kTarget] = this;
 
-         callListener(handler, this, event);
 
-       };
 
-     } else if (type === 'open') {
 
-       wrapper = function onOpen() {
 
-         const event = new Event('open');
 
-         event[kTarget] = this;
 
-         callListener(handler, this, event);
 
-       };
 
-     } else {
 
-       return;
 
-     }
 
-     wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];
 
-     wrapper[kListener] = handler;
 
-     if (options.once) {
 
-       this.once(type, wrapper);
 
-     } else {
 
-       this.on(type, wrapper);
 
-     }
 
-   },
 
-   /**
 
-    * Remove an event listener.
 
-    *
 
-    * @param {String} type A string representing the event type to remove
 
-    * @param {(Function|Object)} handler The listener to remove
 
-    * @public
 
-    */
 
-   removeEventListener(type, handler) {
 
-     for (const listener of this.listeners(type)) {
 
-       if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {
 
-         this.removeListener(type, listener);
 
-         break;
 
-       }
 
-     }
 
-   }
 
- };
 
- module.exports = {
 
-   CloseEvent,
 
-   ErrorEvent,
 
-   Event,
 
-   EventTarget,
 
-   MessageEvent
 
- };
 
- /**
 
-  * Call an event listener
 
-  *
 
-  * @param {(Function|Object)} listener The listener to call
 
-  * @param {*} thisArg The value to use as `this`` when calling the listener
 
-  * @param {Event} event The event to pass to the listener
 
-  * @private
 
-  */
 
- function callListener(listener, thisArg, event) {
 
-   if (typeof listener === 'object' && listener.handleEvent) {
 
-     listener.handleEvent.call(listener, event);
 
-   } else {
 
-     listener.call(thisArg, event);
 
-   }
 
- }
 
 
  |