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;
 |