You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
4.2 KiB
193 lines
4.2 KiB
import { |
|
collectLanes, |
|
getLanesRoot |
|
} from '../util/LaneUtil'; |
|
|
|
import { |
|
is |
|
} from '../../../util/ModelUtil'; |
|
|
|
import { |
|
add as collectionAdd, |
|
remove as collectionRemove |
|
} from 'diagram-js/lib/util/Collections'; |
|
|
|
import { |
|
asTRBL |
|
} from 'diagram-js/lib/layout/LayoutUtil'; |
|
|
|
var FLOW_NODE_REFS_ATTR = 'flowNodeRef', |
|
LANES_ATTR = 'lanes'; |
|
|
|
|
|
/** |
|
* A handler that updates lane refs on changed elements |
|
*/ |
|
export default function UpdateFlowNodeRefsHandler(elementRegistry) { |
|
this._elementRegistry = elementRegistry; |
|
} |
|
|
|
UpdateFlowNodeRefsHandler.$inject = [ |
|
'elementRegistry' |
|
]; |
|
|
|
|
|
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.indexOf(flowNodeShape) === -1) { |
|
allFlowNodeShapes.push(flowNodeShape); |
|
handledNodes.push(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.indexOf(root) !== -1) { |
|
return; |
|
} |
|
|
|
var children = root.children.filter(function(c) { |
|
return is(c, 'bpmn:FlowNode'); |
|
}); |
|
|
|
children.forEach(addFlowNodeShape); |
|
|
|
handledNodes.push(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) { |
|
collectionRemove(lanes, oldLane); |
|
collectionRemove(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode); |
|
}); |
|
|
|
// wire new |
|
update.add.forEach(function(newLane) { |
|
collectionAdd(lanes, newLane); |
|
collectionAdd(newLane.get(FLOW_NODE_REFS_ATTR), flowNode); |
|
}); |
|
}); |
|
|
|
// TODO(nikku): return changed elements |
|
// return [ ... ]; |
|
}; |
|
|
|
|
|
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) { |
|
collectionRemove(lanes, newLane); |
|
collectionRemove(newLane.get(FLOW_NODE_REFS_ATTR), flowNode); |
|
}); |
|
|
|
// wire old |
|
update.remove.forEach(function(oldLane) { |
|
collectionAdd(lanes, oldLane); |
|
collectionAdd(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode); |
|
}); |
|
}); |
|
|
|
// TODO(nikku): return changed elements |
|
// return [ ... ]; |
|
};
|
|
|