UNPKG

diagram-js

Version:

A toolbox for displaying and modifying diagrams on the web

126 lines (95 loc) 2.63 kB
import { forEach } from 'min-dash'; import { closest as domClosest } from 'min-dom'; /** * @typedef {import('../../core/EventBus').default} EventBus * * @typedef {import('../../core/EventBus').Event} Event */ 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 {EventBus} eventBus */ export default function ToolManager(eventBus) { this._eventBus = eventBus; this._tools = []; this._active = null; } ToolManager.$inject = [ 'eventBus' ]; /** * Register a tool. * * @param {string} name * @param { { * tool: string; * } } events */ ToolManager.prototype.registerTool = function(name, events) { var tools = this._tools; if (!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; if (this._active !== tool) { this._active = tool; eventBus.fire('tool-manager.update', { tool: tool }); } }; ToolManager.prototype.bindEvents = function(name, events) { var eventBus = this._eventBus; var eventsToRegister = []; eventBus.on(events.tool + '.init', function(event) { var context = event.context; // Active tools that want to reactivate themselves must do this explicitly if (!context.reactivate && this.isActive(name)) { this.setActive(null); return; } this.setActive(name); }, this); // TODO: add test cases forEach(events, function(event) { eventsToRegister.push(event + '.ended'); eventsToRegister.push(event + '.canceled'); }); eventBus.on(eventsToRegister, LOW_PRIORITY, function(event) { // 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; } if (isPaletteClick(event)) { return; } this.setActive(null); }, this); }; // helpers /////////////// /** * Check if a given event is a palette click event. * * @param {Event} event * * @return {boolean} */ function isPaletteClick(event) { var target = event.originalEvent && event.originalEvent.target; return target && domClosest(target, '.group[data-group="tools"]'); }