# All files / src event-handler.js

95.45% Statements 42/44
63.64% Branches 7/11
100% Functions 13/13
95.35% Lines 41/43

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86

    16x
    16x
    16x

    16x

    16x
    13907x
    2306x
    2306x
    2306x
    2306x

    2306x

    16x
    208x
    208x
    208x

    16x
    16x

    16x
    2514x

    16x
    2306x
    2306x
    13907x

    13907x

    16x
    208x
    208x
    1274x

    16x
    812x

    16x
    812x
    812x
    812x

    812x

    812x
    812x

    43x
    43x

    16x

    16x
     /*
    *
    * All objects in the event handling chain should inherit from this class
    *
    */

    import { logger } from './utils/logger';
    import { ErrorTypes, ErrorDetails } from './errors';
    import Event from './events';

    const FORBIDDEN_EVENT_NAMES = {
      'hlsEventGeneric': true,
      'hlsHandlerDestroying': true,
      'hlsHandlerDestroyed': true
    };

    class EventHandler {
      constructor (hls, ...events) {
        this.hls = hls;
        this.onEvent = this.onEvent.bind(this);
        this.handledEvents = events;
        this.useGenericHandler = true;

        this.registerListeners();
      }

      destroy () {
        this.onHandlerDestroying();
        this.unregisterListeners();
        this.onHandlerDestroyed();
      }

      onHandlerDestroying () {}
      onHandlerDestroyed () {}

      isEventHandler () {
        return typeof this.handledEvents === 'object' && this.handledEvents.length && typeof this.onEvent === 'function';
      }

      registerListeners () {
        Eif (this.isEventHandler()) {
          this.handledEvents.forEach(function (event) {
            Iif (FORBIDDEN_EVENT_NAMES[event]) {
              throw new Error('Forbidden event-name: ' + event);
            }

            this.hls.on(event, this.onEvent);
          }, this);
        }
      }

      unregisterListeners () {
        Eif (this.isEventHandler()) {
          this.handledEvents.forEach(function (event) {
            this.hls.off(event, this.onEvent);
          }, this);
        }
      }

      /**
       * arguments: event (string), data (any)
       */
      onEvent (event, data) {
        this.onEventGeneric(event, data);
      }

      onEventGeneric (event, data) {
        let eventToFunction = function (event, data) {
          let funcName = 'on' + event.replace('hls', '');
          Iif (typeof this[funcName] !== 'function') {
            throw new Error(`Event ${event} has no generic handler in this ${this.constructor.name} class (tried ${funcName})`);
          }

          return this[funcName].bind(this, data);
        };
        try {
          eventToFunction.call(this, event, data).call();
        } catch (err) {
          logger.error(`An internal error happened while handling event ${event}. Error message: "${err.message}". Here is a stacktrace:`, err);
          this.hls.trigger(Event.ERROR, { type: ErrorTypes.OTHER_ERROR, details: ErrorDetails.INTERNAL_EXCEPTION, fatal: false, event: event, err: err });
        }
      }
    }

    export default EventHandler;