180 lines
4.2 KiB
JavaScript
180 lines
4.2 KiB
JavaScript
'use strict';
|
|
|
|
var collectLanes = require('../util/LaneUtil').collectLanes;
|
|
|
|
var getLanesRoot = require('../util/LaneUtil').getLanesRoot;
|
|
|
|
var is = require('../../../util/ModelUtil').is;
|
|
|
|
var Collections = require('diagram-js/lib/util/Collections');
|
|
|
|
var asTRBL = require('diagram-js/lib/layout/LayoutUtil').asTRBL;
|
|
|
|
var FLOW_NODE_REFS_ATTR = 'flowNodeRef',
|
|
LANES_ATTR = 'lanes';
|
|
|
|
/**
|
|
* A handler that updates lane refs on changed elements
|
|
*/
|
|
function UpdateFlowNodeRefsHandler(elementRegistry) {
|
|
this._elementRegistry = elementRegistry;
|
|
}
|
|
|
|
UpdateFlowNodeRefsHandler.$inject = [ 'elementRegistry' ];
|
|
|
|
module.exports = UpdateFlowNodeRefsHandler;
|
|
|
|
|
|
UpdateFlowNodeRefsHandler.prototype.computeUpdates = function(flowNodeShapes, laneShapes) {
|
|
|
|
var handledNodes = {};
|
|
|
|
var updates = [];
|
|
|
|
var participantCache = {};
|
|
|
|
var allFlowNodeShapes = [];
|
|
|
|
function isInLaneShape(element, laneShape) {
|
|
|
|
var laneTrbl = asTRBL(laneShape);
|
|
|
|
var elementMid = {
|
|
x: element.x + element.width / 2,
|
|
y: element.y + element.height / 2
|
|
};
|
|
|
|
return elementMid.x > laneTrbl.left &&
|
|
elementMid.x < laneTrbl.right &&
|
|
elementMid.y > laneTrbl.top &&
|
|
elementMid.y < laneTrbl.bottom;
|
|
}
|
|
|
|
function addFlowNodeShape(flowNodeShape) {
|
|
if (!handledNodes[flowNodeShape.id]) {
|
|
allFlowNodeShapes.push(flowNodeShape);
|
|
handledNodes[flowNodeShape.id] = flowNodeShape;
|
|
}
|
|
}
|
|
|
|
function getAllLaneShapes(flowNodeShape) {
|
|
|
|
var root = getLanesRoot(flowNodeShape);
|
|
|
|
if (!participantCache[root.id]) {
|
|
participantCache[root.id] = collectLanes(root);
|
|
}
|
|
|
|
return participantCache[root.id];
|
|
}
|
|
|
|
function getNewLanes(flowNodeShape) {
|
|
if (!flowNodeShape.parent) {
|
|
return [];
|
|
}
|
|
|
|
var allLaneShapes = getAllLaneShapes(flowNodeShape);
|
|
|
|
return allLaneShapes.filter(function(l) {
|
|
return isInLaneShape(flowNodeShape, l);
|
|
}).map(function(shape) {
|
|
return shape.businessObject;
|
|
});
|
|
}
|
|
|
|
laneShapes.forEach(function(laneShape) {
|
|
var root = getLanesRoot(laneShape);
|
|
|
|
if (!root || handledNodes[root.id]) {
|
|
return;
|
|
}
|
|
|
|
var children = root.children.filter(function(c) {
|
|
return is(c, 'bpmn:FlowNode');
|
|
});
|
|
|
|
children.forEach(addFlowNodeShape);
|
|
|
|
handledNodes[root.id] = root;
|
|
});
|
|
|
|
flowNodeShapes.forEach(addFlowNodeShape);
|
|
|
|
|
|
allFlowNodeShapes.forEach(function(flowNodeShape) {
|
|
|
|
var flowNode = flowNodeShape.businessObject;
|
|
|
|
var lanes = flowNode.get(LANES_ATTR),
|
|
remove = lanes.slice(),
|
|
add = getNewLanes(flowNodeShape);
|
|
|
|
updates.push({ flowNode: flowNode, remove: remove, add: add });
|
|
});
|
|
|
|
laneShapes.forEach(function(laneShape) {
|
|
|
|
var lane = laneShape.businessObject;
|
|
|
|
// lane got removed XX-)
|
|
if (!laneShape.parent) {
|
|
lane.get(FLOW_NODE_REFS_ATTR).forEach(function(flowNode) {
|
|
updates.push({ flowNode: flowNode, remove: [ lane ], add: [] });
|
|
});
|
|
}
|
|
});
|
|
|
|
return updates;
|
|
};
|
|
|
|
UpdateFlowNodeRefsHandler.prototype.execute = function(context) {
|
|
|
|
var updates = context.updates;
|
|
|
|
if (!updates) {
|
|
updates = context.updates = this.computeUpdates(context.flowNodeShapes, context.laneShapes);
|
|
}
|
|
|
|
|
|
updates.forEach(function(update) {
|
|
|
|
var flowNode = update.flowNode,
|
|
lanes = flowNode.get(LANES_ATTR);
|
|
|
|
// unwire old
|
|
update.remove.forEach(function(oldLane) {
|
|
Collections.remove(lanes, oldLane);
|
|
Collections.remove(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode);
|
|
});
|
|
|
|
// wire new
|
|
update.add.forEach(function(newLane) {
|
|
Collections.add(lanes, newLane);
|
|
Collections.add(newLane.get(FLOW_NODE_REFS_ATTR), flowNode);
|
|
});
|
|
});
|
|
};
|
|
|
|
|
|
UpdateFlowNodeRefsHandler.prototype.revert = function(context) {
|
|
|
|
var updates = context.updates;
|
|
|
|
updates.forEach(function(update) {
|
|
|
|
var flowNode = update.flowNode,
|
|
lanes = flowNode.get(LANES_ATTR);
|
|
|
|
// unwire new
|
|
update.add.forEach(function(newLane) {
|
|
Collections.remove(lanes, newLane);
|
|
Collections.remove(newLane.get(FLOW_NODE_REFS_ATTR), flowNode);
|
|
});
|
|
|
|
// wire old
|
|
update.remove.forEach(function(oldLane) {
|
|
Collections.add(lanes, oldLane);
|
|
Collections.add(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode);
|
|
});
|
|
});
|
|
}; |