fix(modeling): handle close to {source,target} drop-on-flow
Closes https://github.com/bpmn-io/bpmn-js/issues/1541
This commit is contained in:
parent
756617c59b
commit
1ede893679
|
@ -59,12 +59,12 @@ export default function DropOnFlowBehavior(eventBus, bpmnRules, modeling) {
|
||||||
dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : mid;
|
dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : mid;
|
||||||
|
|
||||||
// if last waypointBefore is inside shape's bounds, ignore docking point
|
// if last waypointBefore is inside shape's bounds, ignore docking point
|
||||||
if (!isPointInsideBBox(shape, waypointsBefore[waypointsBefore.length-1])) {
|
if (waypointsBefore.length === 1 || !isPointInsideBBox(shape, waypointsBefore[waypointsBefore.length-1])) {
|
||||||
waypointsBefore.push(copy(dockingPoint));
|
waypointsBefore.push(copy(dockingPoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if first waypointAfter is inside shape's bounds, ignore docking point
|
// if first waypointAfter is inside shape's bounds, ignore docking point
|
||||||
if (!isPointInsideBBox(shape, waypointsAfter[0])) {
|
if (waypointsAfter.length === 1 || !isPointInsideBBox(shape, waypointsAfter[0])) {
|
||||||
waypointsAfter.unshift(copy(dockingPoint));
|
waypointsAfter.unshift(copy(dockingPoint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,60 +38,182 @@ describe('modeling/behavior - drop on connection', function() {
|
||||||
|
|
||||||
describe('create', function() {
|
describe('create', function() {
|
||||||
|
|
||||||
it('should connect start -> target -> end', inject(
|
describe('should connect start -> target -> end', function() {
|
||||||
function(modeling, elementRegistry, elementFactory) {
|
|
||||||
|
|
||||||
// given
|
it('connection middle', inject(
|
||||||
var intermediateThrowEvent = elementFactory.createShape({
|
function(modeling, elementRegistry, elementFactory) {
|
||||||
type: 'bpmn:IntermediateThrowEvent'
|
|
||||||
});
|
|
||||||
|
|
||||||
var startEvent = elementRegistry.get('StartEvent'),
|
// given
|
||||||
sequenceFlow = elementRegistry.get('SequenceFlow_1'),
|
var intermediateThrowEvent = elementFactory.createShape({
|
||||||
task = elementRegistry.get('Task_1');
|
type: 'bpmn:IntermediateThrowEvent'
|
||||||
|
});
|
||||||
|
|
||||||
var originalWaypoints = sequenceFlow.waypoints;
|
var startEvent = elementRegistry.get('StartEvent'),
|
||||||
|
sequenceFlow = elementRegistry.get('SequenceFlow_1'),
|
||||||
|
task = elementRegistry.get('Task_1');
|
||||||
|
|
||||||
var dropPosition = { x: 340, y: 120 }; // first bendpoint
|
var originalWaypoints = sequenceFlow.waypoints;
|
||||||
|
|
||||||
// when
|
var dropPosition = { x: 340, y: 120 }; // first bendpoint
|
||||||
var newShape = modeling.createShape(
|
|
||||||
intermediateThrowEvent,
|
|
||||||
dropPosition,
|
|
||||||
sequenceFlow
|
|
||||||
);
|
|
||||||
|
|
||||||
// then
|
// when
|
||||||
var targetConnection = newShape.outgoing[0];
|
var newShape = modeling.createShape(
|
||||||
|
intermediateThrowEvent,
|
||||||
|
dropPosition,
|
||||||
|
sequenceFlow
|
||||||
|
);
|
||||||
|
|
||||||
// new incoming connection
|
// then
|
||||||
expect(newShape.incoming).to.have.length(1);
|
var targetConnection = newShape.outgoing[0];
|
||||||
expect(newShape.incoming[0]).to.eql(sequenceFlow);
|
|
||||||
|
|
||||||
// new outgoing connection
|
// new incoming connection
|
||||||
expect(newShape.outgoing).to.have.length(1);
|
expect(newShape.incoming).to.have.length(1);
|
||||||
expect(targetConnection).to.exist;
|
expect(newShape.incoming[0]).to.eql(sequenceFlow);
|
||||||
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');
|
|
||||||
|
|
||||||
expect(startEvent.outgoing[0]).to.equal(newShape.incoming[0]);
|
// new outgoing connection
|
||||||
expect(task.incoming[1]).to.equal(newShape.outgoing[0]);
|
expect(newShape.outgoing).to.have.length(1);
|
||||||
|
expect(targetConnection).to.exist;
|
||||||
|
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');
|
||||||
|
|
||||||
// split target at insertion point
|
expect(startEvent.outgoing[0]).to.equal(newShape.incoming[0]);
|
||||||
expect(sequenceFlow).to.have.waypoints(flatten([
|
expect(task.incoming[1]).to.equal(newShape.outgoing[0]);
|
||||||
originalWaypoints.slice(0, 1),
|
|
||||||
{ x: 322, y: 120 }
|
|
||||||
]));
|
|
||||||
|
|
||||||
expect(sequenceFlow).to.have.endDocking(dropPosition);
|
// split target at insertion point
|
||||||
|
expect(sequenceFlow).to.have.waypoints(flatten([
|
||||||
|
originalWaypoints.slice(0, 1),
|
||||||
|
{ x: 322, y: 120 }
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(sequenceFlow).to.have.endDocking(dropPosition);
|
||||||
|
|
||||||
|
expect(targetConnection).to.have.waypoints(flatten([
|
||||||
|
{ x: 340, y: 138 },
|
||||||
|
originalWaypoints.slice(2)
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(targetConnection).to.have.startDocking(dropPosition);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
it('close to source', inject(
|
||||||
|
function(modeling, elementRegistry, elementFactory) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var dropElement = elementFactory.createShape({
|
||||||
|
type: 'bpmn:IntermediateThrowEvent'
|
||||||
|
});
|
||||||
|
|
||||||
|
var start = elementRegistry.get('Gateway_C'),
|
||||||
|
flow = elementRegistry.get('SequenceFlow_F'),
|
||||||
|
end = elementRegistry.get('Task_B');
|
||||||
|
|
||||||
|
var originalWaypoints = flow.waypoints.slice();
|
||||||
|
|
||||||
|
var dropPosition = { x: 495, y: 540 }; // overlapping source
|
||||||
|
|
||||||
|
// when
|
||||||
|
var newShape = modeling.createShape(
|
||||||
|
dropElement,
|
||||||
|
dropPosition,
|
||||||
|
flow
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
var targetConnection = newShape.outgoing[0];
|
||||||
|
|
||||||
|
// new incoming connection
|
||||||
|
expect(newShape.incoming).to.have.length(1);
|
||||||
|
expect(newShape.incoming[0]).to.equal(flow);
|
||||||
|
|
||||||
|
// new outgoing connection
|
||||||
|
expect(newShape.outgoing).to.have.length(1);
|
||||||
|
expect(targetConnection).to.exist;
|
||||||
|
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');
|
||||||
|
|
||||||
|
expect(start.outgoing[0]).to.equal(newShape.incoming[0]);
|
||||||
|
expect(end.incoming[0]).to.equal(newShape.outgoing[0]);
|
||||||
|
|
||||||
|
// split target at insertion point
|
||||||
|
expect(flow).to.have.waypoints(flatten([
|
||||||
|
originalWaypoints.slice(0, 1),
|
||||||
|
[
|
||||||
|
{ x: 477, y: 540 }
|
||||||
|
]
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(flow).to.have.endDocking(dropPosition);
|
||||||
|
|
||||||
|
expect(targetConnection).to.have.waypoints(flatten([
|
||||||
|
{ x: 513, y: 540 },
|
||||||
|
originalWaypoints.slice(1)
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(targetConnection).to.have.startDocking(dropPosition);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
it('close to target', inject(
|
||||||
|
function(modeling, elementRegistry, elementFactory) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var dropElement = elementFactory.createShape({
|
||||||
|
type: 'bpmn:IntermediateThrowEvent'
|
||||||
|
});
|
||||||
|
|
||||||
|
var start = elementRegistry.get('Gateway_C'),
|
||||||
|
flow = elementRegistry.get('SequenceFlow_F'),
|
||||||
|
end = elementRegistry.get('Task_B');
|
||||||
|
|
||||||
|
var originalWaypoints = flow.waypoints.slice();
|
||||||
|
|
||||||
|
var dropPosition = { x: 625, y: 540 }; // overlapping target
|
||||||
|
|
||||||
|
// when
|
||||||
|
var newShape = modeling.createShape(
|
||||||
|
dropElement,
|
||||||
|
dropPosition,
|
||||||
|
flow
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
var targetConnection = newShape.outgoing[0];
|
||||||
|
|
||||||
|
// new incoming connection
|
||||||
|
expect(newShape.incoming).to.have.length(1);
|
||||||
|
expect(newShape.incoming[0]).to.equal(flow);
|
||||||
|
|
||||||
|
// new outgoing connection
|
||||||
|
expect(newShape.outgoing).to.have.length(1);
|
||||||
|
expect(targetConnection).to.exist;
|
||||||
|
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');
|
||||||
|
|
||||||
|
expect(start.outgoing[0]).to.equal(newShape.incoming[0]);
|
||||||
|
expect(end.incoming[0]).to.equal(newShape.outgoing[0]);
|
||||||
|
|
||||||
|
// split target at insertion point
|
||||||
|
expect(flow).to.have.waypoints(flatten([
|
||||||
|
originalWaypoints.slice(0, 1),
|
||||||
|
[
|
||||||
|
{ x: 607, y: 540 }
|
||||||
|
]
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(flow).to.have.endDocking(dropPosition);
|
||||||
|
|
||||||
|
expect(targetConnection).to.have.waypoints(flatten([
|
||||||
|
{ x: 643, y: 540 },
|
||||||
|
originalWaypoints.slice(1)
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(targetConnection).to.have.startDocking(dropPosition);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
expect(targetConnection).to.have.waypoints(flatten([
|
|
||||||
{ x: 340, y: 138 },
|
|
||||||
originalWaypoints.slice(2)
|
|
||||||
]));
|
|
||||||
|
|
||||||
expect(targetConnection).to.have.startDocking(dropPosition);
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
it('should connect start -> target', inject(
|
it('should connect start -> target', inject(
|
||||||
|
|
Loading…
Reference in New Issue