thoov/mock-socket

View on GitHub
src/event/target.js

Summary

Maintainability
A
0 mins
Test Coverage
import { reject, filter } from '../helpers/array-helpers';

/*
 * EventTarget is an interface implemented by objects that can
 * receive events and may have listeners for them.
 *
 * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
 */
class EventTarget {
  constructor() {
    this.listeners = {};
  }

  /*
   * Ties a listener function to an event type which can later be invoked via the
   * dispatchEvent method.
   *
   * @param {string} type - the type of event (ie: 'open', 'message', etc.)
   * @param {function} listener - callback function to invoke when an event is dispatched matching the type
   * @param {boolean} useCapture - N/A TODO: implement useCapture functionality
   */
  addEventListener(type, listener /* , useCapture */) {
    if (typeof listener === 'function') {
      if (!Array.isArray(this.listeners[type])) {
        this.listeners[type] = [];
      }

      // Only add the same function once
      if (filter(this.listeners[type], item => item === listener).length === 0) {
        this.listeners[type].push(listener);
      }
    }
  }

  /*
   * Removes the listener so it will no longer be invoked via the dispatchEvent method.
   *
   * @param {string} type - the type of event (ie: 'open', 'message', etc.)
   * @param {function} listener - callback function to invoke when an event is dispatched matching the type
   * @param {boolean} useCapture - N/A TODO: implement useCapture functionality
   */
  removeEventListener(type, removingListener /* , useCapture */) {
    const arrayOfListeners = this.listeners[type];
    this.listeners[type] = reject(arrayOfListeners, listener => listener === removingListener);
  }

  /*
   * Invokes all listener functions that are listening to the given event.type property. Each
   * listener will be passed the event as the first argument.
   *
   * @param {object} event - event object which will be passed to all listeners of the event.type property
   */
  dispatchEvent(event, ...customArguments) {
    const eventName = event.type;
    const listeners = this.listeners[eventName];

    if (!Array.isArray(listeners)) {
      return false;
    }

    listeners.forEach(listener => {
      if (customArguments.length > 0) {
        listener.apply(this, customArguments);
      } else {
        listener.call(this, event);
      }
    });

    return true;
  }
}

export default EventTarget;