# all files / diagram-js/lib/features/tool-manager/ ToolManager.js

85.71% Statements 36/42
75% Branches 12/16
88.89% Functions 8/9
85.71% Lines 36/42

    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
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102

    1×

    1189×
    1189×

    1189×
    1189×

    1×

    1×
    1403×

    1403×

    1403×

    1403×

    1×
    7×

    1×

    1×
    9×

    9×
    9×

    9×

    1×
    1403×
    1403×

    1403×

    1403×
    8×

    8×

    8×

    1403×
    2806×
    2806×

    1403×
    2×

    2×
    1×

    1×

    1×

     import {
      forEach
    } from 'min-dash';

    import {
      closest as domClosest
    } from 'min-dom';

    var LOW_PRIORITY = 250;

    /**
     * The tool manager acts as middle-man between the available tool's and the Palette,
     * it takes care of making sure that the correct active state is set.
     *
     * @param  {Object}    eventBus
     * @param  {Object}    dragging
     */
    export default function ToolManager(eventBus, dragging) {
      this._eventBus = eventBus;
      this._dragging = dragging;

      this._tools = [];
      this._active = null;
    }

    ToolManager.$inject = [ 'eventBus', 'dragging' ];

    ToolManager.prototype.registerTool = function(name, events) {
      var tools = this._tools;

      Iif (!events) {
        throw new Error('A tool has to be registered with it\'s "events"');
      }

      tools.push(name);

      this.bindEvents(name, events);
    };

    ToolManager.prototype.isActive = function(tool) {
      return tool && this._active === tool;
    };

    ToolManager.prototype.length = function(tool) {
      return this._tools.length;
    };

    ToolManager.prototype.setActive = function(tool) {
      var eventBus = this._eventBus;

      Eif (this._active !== tool) {
        this._active = tool;

        eventBus.fire('tool-manager.update', { tool: tool });
      }
    };

    ToolManager.prototype.bindEvents = function(name, events) {
      var eventBus = this._eventBus,
          dragging = this._dragging;

      var eventsToRegister = [];

      eventBus.on(events.tool + '.init', function(event) {
        var context = event.context;

        // Active tools that want to reactivate themselves must do this explicitly
        Iif (!context.reactivate && this.isActive(name)) {
          this.setActive(null);

          dragging.cancel();
          return;
        }

        this.setActive(name);

      }, this);

      // Todo[ricardo]: add test cases
      forEach(events, function(event) {
        eventsToRegister.push(event + '.ended');
        eventsToRegister.push(event + '.canceled');
      });

      eventBus.on(eventsToRegister, LOW_PRIORITY, function(event) {
        var originalEvent = event.originalEvent;

        // We defer the de-activation of the tool to the .activate phase,
        // so we're able to check if we want to toggle off the current
        // active tool or switch to a new one
        if (!this._active) {
          return;
        }

        Iif (originalEvent && domClosest(originalEvent.target, '.group[data-group="tools"]')) {
          return;
        }

        this.setActive(null);
      }, this);
    };