import inherits from 'inherits'; import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; import { is } from '../../../util/ModelUtil'; var LOW_PRIORITY = 500, HIGH_PRIORITY = 5000; /** * BPMN specific delete lane behavior */ export default function UpdateFlowNodeRefsBehavior(eventBus, modeling, translate) { CommandInterceptor.call(this, eventBus); /** * Ok, this is it: * * We have to update the Lane#flowNodeRefs _and_ * FlowNode#lanes with every FlowNode move/resize and * Lane move/resize. * * We want to group that stuff to recompute containments * as efficient as possible. * * Yea! */ // the update context var context; function initContext() { context = context || new UpdateContext(); context.enter(); return context; } function getContext() { if (!context) { throw new Error(translate('out of bounds release')); } return context; } function releaseContext() { if (!context) { throw new Error(translate('out of bounds release')); } var triggerUpdate = context.leave(); if (triggerUpdate) { modeling.updateLaneRefs(context.flowNodes, context.lanes); context = null; } return triggerUpdate; } var laneRefUpdateEvents = [ 'spaceTool', 'lane.add', 'lane.resize', 'lane.split', 'elements.create', 'elements.delete', 'elements.move', 'shape.create', 'shape.delete', 'shape.move', 'shape.resize' ]; // listen to a lot of stuff to group lane updates this.preExecute(laneRefUpdateEvents, HIGH_PRIORITY, function(event) { initContext(); }); this.postExecuted(laneRefUpdateEvents, LOW_PRIORITY, function(event) { releaseContext(); }); // Mark flow nodes + lanes that need an update this.preExecute([ 'shape.create', 'shape.move', 'shape.delete', 'shape.resize' ], function(event) { var context = event.context, shape = context.shape; var updateContext = getContext(); // no need to update labels if (shape.labelTarget) { return; } if (is(shape, 'bpmn:Lane')) { updateContext.addLane(shape); } if (is(shape, 'bpmn:FlowNode')) { updateContext.addFlowNode(shape); } }); } UpdateFlowNodeRefsBehavior.$inject = [ 'eventBus', 'modeling' , 'translate' ]; inherits(UpdateFlowNodeRefsBehavior, CommandInterceptor); function UpdateContext() { this.flowNodes = []; this.lanes = []; this.counter = 0; this.addLane = function(lane) { this.lanes.push(lane); }; this.addFlowNode = function(flowNode) { this.flowNodes.push(flowNode); }; this.enter = function() { this.counter++; }; this.leave = function() { this.counter--; return !this.counter; }; }