diff --git a/lib/features/modeling/behavior/UnclaimIdBehavior.js b/lib/features/modeling/behavior/UnclaimIdBehavior.js index ada3355e..7e3560df 100644 --- a/lib/features/modeling/behavior/UnclaimIdBehavior.js +++ b/lib/features/modeling/behavior/UnclaimIdBehavior.js @@ -1,33 +1,56 @@ -import { - forEach -} from 'min-dash'; - import inherits from 'inherits'; import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; +import { is } from '../../../util/ModelUtil'; +import { isExpanded } from '../../../util/DiUtil'; +import { isLabel } from '../../../util/LabelUtil'; + /** * Unclaims model IDs on element deletion. * - * @param {EventBus} eventBus + * @param {Canvas} canvas + * @param {Injector} injector + * @param {Moddle} moddle * @param {Modeling} modeling */ -export default function UnclaimIdBehavior(eventBus, modeling) { +export default function UnclaimIdBehavior(canvas, injector, moddle, modeling) { + injector.invoke(CommandInterceptor, this); - CommandInterceptor.call(this, eventBus); - - this.preExecute('elements.delete', function(event) { + this.preExecute('shape.delete', function(event) { var context = event.context, - elements = context.elements; + shape = context.shape, + shapeBo = shape.businessObject; - forEach(elements, function(element) { - modeling.unclaimId(element.businessObject.id, element.businessObject); - }); + if (isLabel(shape)) { + return; + } + if (is(shape, 'bpmn:Participant') && isExpanded(shape)) { + moddle.ids.unclaim(shapeBo.processRef.id); + } + + modeling.unclaimId(shapeBo.id, shapeBo); + }); + + + this.preExecute('connection.delete', function(event) { + var context = event.context, + connection = context.connection, + connectionBo = connection.businessObject; + + modeling.unclaimId(connectionBo.id, connectionBo); + }); + + this.preExecute('canvas.updateRoot', function() { + var rootElement = canvas.getRootElement(), + rootElementBo = rootElement.businessObject; + + moddle.ids.unclaim(rootElementBo.id); }); } inherits(UnclaimIdBehavior, CommandInterceptor); -UnclaimIdBehavior.$inject = [ 'eventBus', 'modeling' ]; \ No newline at end of file +UnclaimIdBehavior.$inject = [ 'canvas', 'injector', 'moddle', 'modeling' ]; \ No newline at end of file diff --git a/lib/features/popup-menu/ReplaceMenuProvider.js b/lib/features/popup-menu/ReplaceMenuProvider.js index e7602391..851bdf0d 100644 --- a/lib/features/popup-menu/ReplaceMenuProvider.js +++ b/lib/features/popup-menu/ReplaceMenuProvider.js @@ -484,9 +484,15 @@ ReplaceMenuProvider.prototype._getAdHocEntry = function(element) { active: isAdHoc, action: function(event, entry) { if (isAdHoc) { - return replaceElement(element, { type: 'bpmn:SubProcess' }); + return replaceElement(element, { type: 'bpmn:SubProcess' }, { + autoResize: false, + layoutConnection: false + }); } else { - return replaceElement(element, { type: 'bpmn:AdHocSubProcess' }); + return replaceElement(element, { type: 'bpmn:AdHocSubProcess' }, { + autoResize: false, + layoutConnection: false + }); } } }; diff --git a/test/spec/features/modeling/behavior/UnclaimIdBehaviorSpec.bpmn b/test/spec/features/modeling/behavior/UnclaimIdBehaviorSpec.bpmn new file mode 100644 index 00000000..c0368cbf --- /dev/null +++ b/test/spec/features/modeling/behavior/UnclaimIdBehaviorSpec.bpmn @@ -0,0 +1,32 @@ + + + + + + + + SequenceFlow_1 + + + SequenceFlow_1 + + + + + + + + + + + + + + + + + + + + + diff --git a/test/spec/features/modeling/behavior/UnclaimIdBehaviorSpec.js b/test/spec/features/modeling/behavior/UnclaimIdBehaviorSpec.js new file mode 100644 index 00000000..ed62fef7 --- /dev/null +++ b/test/spec/features/modeling/behavior/UnclaimIdBehaviorSpec.js @@ -0,0 +1,85 @@ +import { + bootstrapModeler, + inject +} from 'test/TestHelper'; + +import coreModule from 'lib/core'; +import modelingModule from 'lib/features/modeling'; + + +describe('features/modeling - unclaim id', function() { + + var testModules = [ coreModule, modelingModule ]; + + var diagramXML = require('./UnclaimIdBehaviorSpec.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { modules: testModules })); + + + it('should unclaim ID of shape', inject(function(elementRegistry, moddle, modeling) { + + // given + var startEvent = elementRegistry.get('StartEvent_1'); + + // when + modeling.removeElements([ startEvent ]); + + // then + expect(moddle.ids.assigned('StartEvent_1')).to.be.false; + })); + + + it('should unclaim ID of process', inject(function(elementRegistry, moddle, modeling) { + + // given + var participant = elementRegistry.get('Participant_1'); + + // when + modeling.removeElements([ participant ]); + + // then + expect(moddle.ids.assigned('Process_1')).to.be.false; + })); + + + it('should unclaim ID of connection', inject(function(elementRegistry, moddle, modeling) { + + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_1'); + + // when + modeling.removeElements([ sequenceFlow ]); + + // then + expect(moddle.ids.assigned('SequenceFlow_1')).to.be.false; + })); + + + it('should unclaim ID of children', inject(function(elementRegistry, moddle, modeling) { + + // given + var participant = elementRegistry.get('Participant_1'); + + // when + modeling.removeElements([ participant ]); + + // then + expect(moddle.ids.assigned('StartEvent_1')).to.be.false; + expect(moddle.ids.assigned('SequenceFlow_1')).to.be.false; + expect(moddle.ids.assigned('EndEvent_1')).to.be.false; + })); + + + it('should unclaim ID of root', inject(function(elementRegistry, moddle, modeling) { + + // given + var participant = elementRegistry.get('Participant_1'); + + // when + modeling.removeElements([ participant ]); + + // then + expect(moddle.ids.assigned('Collaboration_1')).to.be.false; + })); + +}); \ No newline at end of file diff --git a/test/spec/features/popup-menu/ReplaceMenuProvider.collapsedSubProcess.bpmn b/test/spec/features/popup-menu/ReplaceMenuProvider.collapsedSubProcess.bpmn index aa2b19e1..21cf22e5 100644 --- a/test/spec/features/popup-menu/ReplaceMenuProvider.collapsedSubProcess.bpmn +++ b/test/spec/features/popup-menu/ReplaceMenuProvider.collapsedSubProcess.bpmn @@ -1,13 +1,95 @@ - + + + SequenceFlow_3 + + SequenceFlow_1 + + + SequenceFlow_1 + SequenceFlow_2 + + + + SequenceFlow_2 + + + + + SequenceFlow_3 + + + + + SequenceFlow_4 + + + SequenceFlow_4 + SequenceFlow_5 + + + SequenceFlow_5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js b/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js index ed90416a..285d71a9 100644 --- a/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js +++ b/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js @@ -1,3 +1,5 @@ +/* global sinon */ + import { bootstrapModeler, getBpmnJS, @@ -8,10 +10,11 @@ import { createEvent as globalEvent } from '../../../util/MockEvents'; +import autoResizeModule from 'lib/features/auto-resize'; import coreModule from 'lib/core'; +import customRulesModule from '../../../util/custom-rules'; import modelingModule from 'lib/features/modeling'; import replaceMenuProviderModule from 'lib/features/popup-menu'; -import customRulesModule from '../../../util/custom-rules'; import { query as domQuery, @@ -23,6 +26,8 @@ import { is } from 'lib/util/ModelUtil'; import { isExpanded } from 'lib/util/DiUtil'; +var spy = sinon.spy; + describe('features/popup-menu - replace menu provider', function() { @@ -1778,6 +1783,100 @@ describe('features/popup-menu - replace menu provider', function() { }); + + describe('adhoc sub process', function() { + + var diagramXML = require('./ReplaceMenuProvider.collapsedSubProcess.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { + modules: testModules.concat(autoResizeModule) + })); + + + describe('sub process -> adhoc', function() { + + it('should not resize', inject(function(elementRegistry, modeling, popupMenu) { + + // given + var subProcess = elementRegistry.get('SubProcess_1'); + + var resizeShapeSpy = spy(modeling, 'resizeShape'); + + // when + openPopup(subProcess); + + var adHocEntry = queryEntry('toggle-adhoc'); + + popupMenu.trigger(globalEvent(adHocEntry, { x: 0, y: 0 })); + + // then + expect(resizeShapeSpy).not.to.have.been.called; + })); + + + it('should not lay out connection', inject(function(elementRegistry, modeling, popupMenu) { + + // given + var subProcess = elementRegistry.get('SubProcess_1'); + + var layoutConnectionSpy = spy(modeling, 'layoutConnection'); + + // when + openPopup(subProcess); + + var adHocEntry = queryEntry('toggle-adhoc'); + + popupMenu.trigger(globalEvent(adHocEntry, { x: 0, y: 0 })); + + // then + expect(layoutConnectionSpy).not.to.have.been.called; + })); + + }); + + describe('adhoc -> sub process', function() { + + it('should not resize', inject(function(elementRegistry, modeling, popupMenu) { + + // given + var adhocSubProcess = elementRegistry.get('AdhocSubProcess_1'); + + var resizeShapeSpy = spy(modeling, 'resizeShape'); + + // when + openPopup(adhocSubProcess); + + var adHocEntry = queryEntry('toggle-adhoc'); + + popupMenu.trigger(globalEvent(adHocEntry, { x: 0, y: 0 })); + + // then + expect(resizeShapeSpy).not.to.have.been.called; + })); + + + it('should not lay out connection', inject(function(elementRegistry, modeling, popupMenu) { + + // given + var adhocSubProcess = elementRegistry.get('AdhocSubProcess_1'); + + var layoutConnectionSpy = spy(modeling, 'layoutConnection'); + + // when + openPopup(adhocSubProcess); + + var adHocEntry = queryEntry('toggle-adhoc'); + + popupMenu.trigger(globalEvent(adHocEntry, { x: 0, y: 0 })); + + // then + expect(layoutConnectionSpy).not.to.have.been.called; + })); + + }); + + }); + });