185 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| /**
 | |
|  * Class representing an event.
 | |
|  *
 | |
|  * @private
 | |
|  */
 | |
| class Event {
 | |
|   /**
 | |
|    * Create a new `Event`.
 | |
|    *
 | |
|    * @param {String} type The name of the event
 | |
|    * @param {Object} target A reference to the target to which the event was
 | |
|    *     dispatched
 | |
|    */
 | |
|   constructor(type, target) {
 | |
|     this.target = target;
 | |
|     this.type = type;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Class representing a message event.
 | |
|  *
 | |
|  * @extends Event
 | |
|  * @private
 | |
|  */
 | |
| class MessageEvent extends Event {
 | |
|   /**
 | |
|    * Create a new `MessageEvent`.
 | |
|    *
 | |
|    * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data
 | |
|    * @param {WebSocket} target A reference to the target to which the event was
 | |
|    *     dispatched
 | |
|    */
 | |
|   constructor(data, target) {
 | |
|     super('message', target);
 | |
| 
 | |
|     this.data = data;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Class representing a close event.
 | |
|  *
 | |
|  * @extends Event
 | |
|  * @private
 | |
|  */
 | |
| class CloseEvent extends Event {
 | |
|   /**
 | |
|    * Create a new `CloseEvent`.
 | |
|    *
 | |
|    * @param {Number} code The status code explaining why the connection is being
 | |
|    *     closed
 | |
|    * @param {String} reason A human-readable string explaining why the
 | |
|    *     connection is closing
 | |
|    * @param {WebSocket} target A reference to the target to which the event was
 | |
|    *     dispatched
 | |
|    */
 | |
|   constructor(code, reason, target) {
 | |
|     super('close', target);
 | |
| 
 | |
|     this.wasClean = target._closeFrameReceived && target._closeFrameSent;
 | |
|     this.reason = reason;
 | |
|     this.code = code;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Class representing an open event.
 | |
|  *
 | |
|  * @extends Event
 | |
|  * @private
 | |
|  */
 | |
| class OpenEvent extends Event {
 | |
|   /**
 | |
|    * Create a new `OpenEvent`.
 | |
|    *
 | |
|    * @param {WebSocket} target A reference to the target to which the event was
 | |
|    *     dispatched
 | |
|    */
 | |
|   constructor(target) {
 | |
|     super('open', target);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Class representing an error event.
 | |
|  *
 | |
|  * @extends Event
 | |
|  * @private
 | |
|  */
 | |
| class ErrorEvent extends Event {
 | |
|   /**
 | |
|    * Create a new `ErrorEvent`.
 | |
|    *
 | |
|    * @param {Object} error The error that generated this event
 | |
|    * @param {WebSocket} target A reference to the target to which the event was
 | |
|    *     dispatched
 | |
|    */
 | |
|   constructor(error, target) {
 | |
|     super('error', target);
 | |
| 
 | |
|     this.message = error.message;
 | |
|     this.error = error;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 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} listener 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, listener, options) {
 | |
|     if (typeof listener !== 'function') return;
 | |
| 
 | |
|     function onMessage(data) {
 | |
|       listener.call(this, new MessageEvent(data, this));
 | |
|     }
 | |
| 
 | |
|     function onClose(code, message) {
 | |
|       listener.call(this, new CloseEvent(code, message, this));
 | |
|     }
 | |
| 
 | |
|     function onError(error) {
 | |
|       listener.call(this, new ErrorEvent(error, this));
 | |
|     }
 | |
| 
 | |
|     function onOpen() {
 | |
|       listener.call(this, new OpenEvent(this));
 | |
|     }
 | |
| 
 | |
|     const method = options && options.once ? 'once' : 'on';
 | |
| 
 | |
|     if (type === 'message') {
 | |
|       onMessage._listener = listener;
 | |
|       this[method](type, onMessage);
 | |
|     } else if (type === 'close') {
 | |
|       onClose._listener = listener;
 | |
|       this[method](type, onClose);
 | |
|     } else if (type === 'error') {
 | |
|       onError._listener = listener;
 | |
|       this[method](type, onError);
 | |
|     } else if (type === 'open') {
 | |
|       onOpen._listener = listener;
 | |
|       this[method](type, onOpen);
 | |
|     } else {
 | |
|       this[method](type, listener);
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   /**
 | |
|    * Remove an event listener.
 | |
|    *
 | |
|    * @param {String} type A string representing the event type to remove
 | |
|    * @param {Function} listener The listener to remove
 | |
|    * @public
 | |
|    */
 | |
|   removeEventListener(type, listener) {
 | |
|     const listeners = this.listeners(type);
 | |
| 
 | |
|     for (let i = 0; i < listeners.length; i++) {
 | |
|       if (listeners[i] === listener || listeners[i]._listener === listener) {
 | |
|         this.removeListener(type, listeners[i]);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| module.exports = EventTarget;
 |