fix(modeling/BpmnUpdater): ignore custom elements on canvas.updateRoot
Closes #559
This commit is contained in:
parent
f15647edfd
commit
7e93759a0d
|
@ -103,7 +103,9 @@ function BpmnUpdater(eventBus, bpmnFactory, connectionDocking, translate) {
|
|||
children = oldRoot.children;
|
||||
|
||||
forEach(children, function(child) {
|
||||
self.updateParent(child);
|
||||
if (is(child, 'bpmn:BaseElement')) {
|
||||
self.updateParent(child);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -539,7 +541,7 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent,
|
|||
diChildren = [];
|
||||
newParent.set(containment, diChildren);
|
||||
}
|
||||
|
||||
|
||||
diChildren.push(businessObject);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,17 +14,20 @@ var customElementsModules = require('./custom-elements'),
|
|||
|
||||
var testModules = [].concat(modelerModules, customModules);
|
||||
|
||||
var processDiagramXML = require('../fixtures/bpmn/simple.bpmn');
|
||||
|
||||
var collaborationDiagramXML = require('../fixtures/bpmn/collaboration.bpmn');
|
||||
|
||||
|
||||
describe('custom elements', function() {
|
||||
|
||||
var diagramXML = require('../fixtures/bpmn/simple.bpmn');
|
||||
|
||||
beforeEach(bootstrapModeler(diagramXML, {
|
||||
modules: testModules
|
||||
}));
|
||||
|
||||
describe('renderer', function () {
|
||||
|
||||
beforeEach(bootstrapModeler(processDiagramXML, {
|
||||
modules: testModules
|
||||
}));
|
||||
|
||||
|
||||
var triangle, circle;
|
||||
|
||||
beforeEach(inject(function(elementFactory, canvas) {
|
||||
|
@ -79,91 +82,140 @@ describe('custom elements', function() {
|
|||
|
||||
describe('integration', function () {
|
||||
|
||||
var triangle, circle;
|
||||
describe('process diagram', function() {
|
||||
|
||||
beforeEach(inject(function(elementFactory, canvas) {
|
||||
|
||||
circle = elementFactory.createShape({
|
||||
id: 'circle',
|
||||
type: 'custom:circle',
|
||||
x: 800, y: 100
|
||||
});
|
||||
|
||||
canvas.addShape(circle);
|
||||
|
||||
triangle = elementFactory.createShape({
|
||||
id: 'triangle',
|
||||
type: 'custom:triangle',
|
||||
x: 700, y: 100
|
||||
});
|
||||
|
||||
canvas.addShape(triangle);
|
||||
}));
|
||||
beforeEach(bootstrapModeler(processDiagramXML, {
|
||||
modules: testModules
|
||||
}));
|
||||
|
||||
|
||||
it('should allow moving a custom shape inside another one',
|
||||
inject(function(elementFactory, elementRegistry, dragging, move) {
|
||||
var triangle, circle;
|
||||
|
||||
// given
|
||||
var circleGfx = elementRegistry.getGraphics(circle);
|
||||
beforeEach(inject(function(elementFactory, canvas) {
|
||||
|
||||
// when
|
||||
move.start(canvasEvent({ x: 0, y: 0 }), triangle);
|
||||
circle = elementFactory.createShape({
|
||||
id: 'circle',
|
||||
type: 'custom:circle',
|
||||
x: 800, y: 100
|
||||
});
|
||||
|
||||
dragging.move(canvasEvent({ x: 100, y: 0 }));
|
||||
dragging.hover({ element: circle, gfx: circleGfx });
|
||||
dragging.move(canvasEvent({ x: 150, y: 50 }));
|
||||
canvas.addShape(circle);
|
||||
|
||||
dragging.end();
|
||||
triangle = elementFactory.createShape({
|
||||
id: 'triangle',
|
||||
type: 'custom:triangle',
|
||||
x: 700, y: 100
|
||||
});
|
||||
|
||||
// then
|
||||
expect(triangle.parent).to.equal(circle);
|
||||
}));
|
||||
canvas.addShape(triangle);
|
||||
}));
|
||||
|
||||
|
||||
it('should update the custom shape properties',
|
||||
inject(function(elementFactory, elementRegistry, dragging, move) {
|
||||
it('should allow moving a custom shape inside another one',
|
||||
inject(function(elementFactory, elementRegistry, dragging, move) {
|
||||
|
||||
// given
|
||||
var circleGfx = elementRegistry.getGraphics(circle);
|
||||
// given
|
||||
var circleGfx = elementRegistry.getGraphics(circle);
|
||||
|
||||
// when
|
||||
move.start(canvasEvent({ x: 0, y: 0 }), triangle);
|
||||
// when
|
||||
move.start(canvasEvent({ x: 0, y: 0 }), triangle);
|
||||
|
||||
dragging.move(canvasEvent({ x: 100, y: 0 }));
|
||||
dragging.hover({ element: circle, gfx: circleGfx });
|
||||
dragging.move(canvasEvent({ x: 150, y: 50 }));
|
||||
dragging.move(canvasEvent({ x: 100, y: 0 }));
|
||||
dragging.hover({ element: circle, gfx: circleGfx });
|
||||
dragging.move(canvasEvent({ x: 150, y: 50 }));
|
||||
|
||||
dragging.end();
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
expect(triangle.businessObject.leader).to.equal(circle);
|
||||
expect(circle.businessObject.companions).to.include(triangle);
|
||||
}));
|
||||
// then
|
||||
expect(triangle.parent).to.equal(circle);
|
||||
}));
|
||||
|
||||
|
||||
it('should connect a bpmn element to a custom one',
|
||||
inject(function(elementFactory, dragging, elementRegistry, connect) {
|
||||
it('should update the custom shape properties',
|
||||
inject(function(elementFactory, elementRegistry, dragging, move) {
|
||||
|
||||
// given
|
||||
var subProcess = elementRegistry.get('SubProcess_1'),
|
||||
triangleGfx = elementRegistry.getGraphics(triangle);
|
||||
// given
|
||||
var circleGfx = elementRegistry.getGraphics(circle);
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 590, y: 90 }), subProcess);
|
||||
// when
|
||||
move.start(canvasEvent({ x: 0, y: 0 }), triangle);
|
||||
|
||||
dragging.move(canvasEvent({ x: 700, y: 100 }));
|
||||
dragging.hover({ element: triangle, gfx: triangleGfx });
|
||||
dragging.move(canvasEvent({ x: 715, y: 115 }));
|
||||
dragging.move(canvasEvent({ x: 100, y: 0 }));
|
||||
dragging.hover({ element: circle, gfx: circleGfx });
|
||||
dragging.move(canvasEvent({ x: 150, y: 50 }));
|
||||
|
||||
dragging.end();
|
||||
dragging.end();
|
||||
|
||||
var connection = triangle.incoming[0];
|
||||
// then
|
||||
expect(triangle.businessObject.leader).to.equal(circle);
|
||||
expect(circle.businessObject.companions).to.include(triangle);
|
||||
}));
|
||||
|
||||
// then
|
||||
expect(connection.type).to.equal('bpmn:Association');
|
||||
expect(connection.source).to.equal(subProcess);
|
||||
}));
|
||||
|
||||
it('should connect a bpmn element to a custom one',
|
||||
inject(function(elementFactory, dragging, elementRegistry, connect) {
|
||||
|
||||
// given
|
||||
var subProcess = elementRegistry.get('SubProcess_1'),
|
||||
triangleGfx = elementRegistry.getGraphics(triangle);
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 590, y: 90 }), subProcess);
|
||||
|
||||
dragging.move(canvasEvent({ x: 700, y: 100 }));
|
||||
dragging.hover({ element: triangle, gfx: triangleGfx });
|
||||
dragging.move(canvasEvent({ x: 715, y: 115 }));
|
||||
|
||||
dragging.end();
|
||||
|
||||
var connection = triangle.incoming[0];
|
||||
|
||||
// then
|
||||
expect(connection.type).to.equal('bpmn:Association');
|
||||
expect(connection.source).to.equal(subProcess);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('collaboration diagram', function() {
|
||||
|
||||
beforeEach(bootstrapModeler(collaborationDiagramXML, {
|
||||
modules: testModules
|
||||
}));
|
||||
|
||||
|
||||
var triangle;
|
||||
|
||||
beforeEach(inject(function(elementFactory, canvas) {
|
||||
|
||||
triangle = elementFactory.createShape({
|
||||
id: 'triangle',
|
||||
type: 'custom:triangle',
|
||||
x: 700, y: 100
|
||||
});
|
||||
|
||||
canvas.addShape(triangle);
|
||||
}));
|
||||
|
||||
|
||||
it('should update parent when removing collaboration',
|
||||
inject(function(elementRegistry, modeling, canvas) {
|
||||
|
||||
// given
|
||||
var customTriangle = elementRegistry.get('triangle');
|
||||
|
||||
// when
|
||||
modeling.removeElements([
|
||||
elementRegistry.get('Participant_1'),
|
||||
elementRegistry.get('Participant_2')
|
||||
]);
|
||||
|
||||
// then
|
||||
expect(customTriangle.parent).to.eql(canvas.getRootElement());
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -8,6 +8,11 @@ var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
|
|||
|
||||
|
||||
function isCustom(element, type) {
|
||||
|
||||
if (!type) {
|
||||
return /custom:/.test(element.type);
|
||||
}
|
||||
|
||||
return element && element.type === type;
|
||||
}
|
||||
|
||||
|
@ -26,7 +31,7 @@ function ifCustomElement(fn) {
|
|||
* A handler responsible for updating the custom element's businessObject
|
||||
* once changes on the diagram happen
|
||||
*/
|
||||
function CustomUpdater(eventBus, bpmnFactory, connectionDocking) {
|
||||
function CustomUpdater(eventBus, modeling) {
|
||||
|
||||
CommandInterceptor.call(this, eventBus);
|
||||
|
||||
|
@ -82,10 +87,29 @@ function CustomUpdater(eventBus, bpmnFactory, connectionDocking) {
|
|||
'shape.create'
|
||||
], ifCustomElement(updateTriangle));
|
||||
|
||||
|
||||
/**
|
||||
* When morphing a Process into a Collaboration or vice-versa,
|
||||
* make sure that the existing custom elements get their parents updated.
|
||||
*/
|
||||
function updateCustomElementsRoot(event) {
|
||||
var context = event.context,
|
||||
oldRoot = context.oldRoot,
|
||||
newRoot = context.newRoot,
|
||||
children = oldRoot.children;
|
||||
|
||||
var customChildren = children.filter(isCustom);
|
||||
|
||||
if (customChildren.length) {
|
||||
modeling.moveElements(customChildren, { x: 0, y: 0 }, newRoot);
|
||||
}
|
||||
}
|
||||
|
||||
this.postExecute('canvas.updateRoot', updateCustomElementsRoot);
|
||||
}
|
||||
|
||||
inherits(CustomUpdater, CommandInterceptor);
|
||||
|
||||
module.exports = CustomUpdater;
|
||||
|
||||
CustomUpdater.$inject = [ 'eventBus' ];
|
||||
CustomUpdater.$inject = [ 'eventBus', 'modeling' ];
|
||||
|
|
Loading…
Reference in New Issue