# All files / src event-handler.ts

93.33% Statements 28/30
63.64% Branches 7/11
100% Functions 12/12
93.1% Lines 27/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    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
    87
    88
    89
    90
    91

    1x

    16775x
    2760x
    2760x
    2760x
    2760x

    2760x

    256x
    256x
    256x

    3016x

    2760x
    2760x
    16775x

    16775x

    256x
    256x
    1584x

    957x

    957x
    957x
    957x

    957x

    957x
    957x

    54x
    54x

     /*
    *
    * 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';
    import Hls from './hls';

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

    class EventHandler {
      hls: Hls;
      handledEvents: any[];
      useGenericHandler: boolean;

      constructor (hls: Hls, ...events: any[]) {
        this.hls = hls;
        this.onEvent = this.onEvent.bind(this);
        this.handledEvents = events;
        this.useGenericHandler = true;

        this.registerListeners();
      }

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

      protected onHandlerDestroying () {}
      protected 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: string, data: any) {
        this.onEventGeneric(event, data);
      }

      onEventGeneric (event: string, data: any) {
        let eventToFunction = function (event: string, data: any) {
          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;