From 7ad9c7106e03ae12faf8990ca382a059ae5a0479 Mon Sep 17 00:00:00 2001 From: Nico Rehwaldt Date: Tue, 8 Mar 2016 14:41:32 +0100 Subject: [PATCH] fix(label-editing): complete editing operation on drag init Make sure the direct editing results are applied (not discarded) when the user starts a drag operation with direct editing active. Closes #490 --- .../label-editing/LabelEditingProvider.js | 2 +- .../label-editing/LabelEditingProviderSpec.js | 343 ++++++++++-------- 2 files changed, 186 insertions(+), 159 deletions(-) diff --git a/lib/features/label-editing/LabelEditingProvider.js b/lib/features/label-editing/LabelEditingProvider.js index 71ffd370..5879f37a 100644 --- a/lib/features/label-editing/LabelEditingProvider.js +++ b/lib/features/label-editing/LabelEditingProvider.js @@ -25,7 +25,7 @@ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) { }); // complete on followup canvas operation - eventBus.on([ 'element.mousedown', 'drag.activate', 'canvas.viewbox.changed' ], function(event) { + eventBus.on([ 'element.mousedown', 'drag.init', 'canvas.viewbox.changed' ], function(event) { directEditing.complete(); }); diff --git a/test/spec/features/label-editing/LabelEditingProviderSpec.js b/test/spec/features/label-editing/LabelEditingProviderSpec.js index 3c47d4e4..ec72d101 100644 --- a/test/spec/features/label-editing/LabelEditingProviderSpec.js +++ b/test/spec/features/label-editing/LabelEditingProviderSpec.js @@ -6,7 +6,8 @@ require('../../../TestHelper'); var labelEditingModule = require('../../../../lib/features/label-editing'), - coreModule = require('../../../../lib/core'); + coreModule = require('../../../../lib/core'), + draggingModule = require('diagram-js/lib/features/dragging'); var LabelUtil = require('../../../../lib/features/label-editing/LabelUtil'); @@ -29,13 +30,14 @@ describe('features - label-editing', function() { var diagramXML = require('../../../fixtures/bpmn/features/label-editing/labels.bpmn'); - var testModules = [ labelEditingModule, coreModule ]; - - beforeEach(bootstrapViewer(diagramXML, { modules: testModules })); - describe('basics', function() { + var testModules = [ labelEditingModule, coreModule, draggingModule ]; + + beforeEach(bootstrapViewer(diagramXML, { modules: testModules })); + + it('should register on dblclick', inject(function(elementRegistry, directEditing, eventBus) { // given @@ -74,6 +76,24 @@ describe('features - label-editing', function() { })); + it('should complete on drag start', inject(function(elementRegistry, directEditing, dragging) { + + // given + var shape = elementRegistry.get('task-nested-embedded'), + task = shape.businessObject; + + directEditing.activate(shape); + + directEditing._textbox.textarea.value = 'FOO BAR'; + + // when + dragging.init(null, { x: 0, y: 0 }, 'foo'); + + // then + expect(task.name).to.equal('FOO BAR'); + })); + + it('should submit on root element click', inject(function(elementRegistry, directEditing, canvas, eventBus) { // given @@ -102,213 +122,220 @@ describe('features - label-editing', function() { }); - var elementRegistry, - eventBus, - directEditing; + describe('details', function() { + + var testModules = [ labelEditingModule, coreModule ]; + + beforeEach(bootstrapViewer(diagramXML, { modules: testModules })); + + var elementRegistry, + eventBus, + directEditing; - beforeEach(inject([ 'elementRegistry', 'eventBus', 'directEditing', function(_elementRegistry, _eventBus, _directEditing) { - elementRegistry = _elementRegistry; - eventBus = _eventBus; - directEditing = _directEditing; - }])); + beforeEach(inject([ 'elementRegistry', 'eventBus', 'directEditing', function(_elementRegistry, _eventBus, _directEditing) { + elementRegistry = _elementRegistry; + eventBus = _eventBus; + directEditing = _directEditing; + }])); - function directEditActivate(element) { - if (element.waypoints) { - eventBus.fire('element.dblclick', { element: element }); - } else { - eventBus.fire('element.dblclick', { element: element }); + function directEditActivate(element) { + if (element.waypoints) { + eventBus.fire('element.dblclick', { element: element }); + } else { + eventBus.fire('element.dblclick', { element: element }); + } } - } - function directEditUpdate(value) { - directEditing._textbox.textarea.value = value; - } + function directEditUpdate(value) { + directEditing._textbox.textarea.value = value; + } - function directEditComplete(value) { - directEditUpdate(value); - directEditing.complete(); - } + function directEditComplete(value) { + directEditUpdate(value); + directEditing.complete(); + } - function directEditCancel(value) { - directEditUpdate(value); - directEditing.cancel(); - } + function directEditCancel(value) { + directEditUpdate(value); + directEditing.cancel(); + } - describe('command support', function() { + describe('command support', function() { - it('should update via command stack', function() { + it('should update via command stack', function() { - // given - var diagramElement = elementRegistry.get('user-task'); + // given + var diagramElement = elementRegistry.get('user-task'); - var listenerCalled; + var listenerCalled; - eventBus.on('commandStack.changed', function(e) { - listenerCalled = true; - }); - - // when - directEditActivate(diagramElement); - directEditComplete('BAR'); - - // then - expect(listenerCalled).to.be.true; - }); - - - it('should undo via command stack', inject(function(commandStack) { - - // given - var diagramElement = elementRegistry.get('user-task'); - - var oldLabel = LabelUtil.getLabel(diagramElement); - - // when - directEditActivate(diagramElement); - directEditComplete('BAR'); - - commandStack.undo(); - - // then - var label = LabelUtil.getLabel(diagramElement); - expect(label).to.eql(oldLabel); - })); - - }); - - - describe('should trigger redraw', function() { - - it('on shape change', function() { - - // given - var diagramElement = elementRegistry.get('user-task'); - - var listenerCalled; - - eventBus.on('element.changed', function(e) { - if (e.element === diagramElement) { + eventBus.on('commandStack.changed', function(e) { listenerCalled = true; - } + }); + + // when + directEditActivate(diagramElement); + directEditComplete('BAR'); + + // then + expect(listenerCalled).to.be.true; }); - // when - directEditActivate(diagramElement); - directEditComplete('BAR'); - // then - expect(listenerCalled).to.be.true; - }); + it('should undo via command stack', inject(function(commandStack) { + // given + var diagramElement = elementRegistry.get('user-task'); - it('on connection on change', function() { + var oldLabel = LabelUtil.getLabel(diagramElement); - // given - var diagramElement = elementRegistry.get('sequence-flow-no'); + // when + directEditActivate(diagramElement); + directEditComplete('BAR'); - var listenerCalled; - - eventBus.on('element.changed', function(e) { - if (e.element === diagramElement.label) { - listenerCalled = true; - } - }); - - // when - directEditActivate(diagramElement); - directEditComplete('BAR'); - - // then - expect(listenerCalled).to.be.true; - }); - - }); - - - describe('element support, should edit', function() { - - function directEdit(elementId) { - - return inject(function(elementRegistry, eventBus, directEditing) { - - var diagramElement = elementRegistry.get(elementId); + commandStack.undo(); + // then var label = LabelUtil.getLabel(diagramElement); + expect(label).to.eql(oldLabel); + })); + }); + + + describe('should trigger redraw', function() { + + it('on shape change', function() { + + // given + var diagramElement = elementRegistry.get('user-task'); + + var listenerCalled; + + eventBus.on('element.changed', function(e) { + if (e.element === diagramElement) { + listenerCalled = true; + } + }); // when directEditActivate(diagramElement); + directEditComplete('BAR'); // then - // expect editing to be active - expect(directEditing.getValue()).to.eql(label); - expect(directEditing.isActive()).to.be.true; - - - // when - directEditComplete('B'); - - // then - // expect update to have happened - label = LabelUtil.getLabel(diagramElement); - expect(label).to.equal('B'); - - - // when - directEditActivate(diagramElement); - directEditCancel('C'); - - // expect no label update to have happened - label = LabelUtil.getLabel(diagramElement); - expect(label).to.equal('B'); + expect(listenerCalled).to.be.true; }); - } - it('task', directEdit('user-task')); + it('on connection on change', function() { + + // given + var diagramElement = elementRegistry.get('sequence-flow-no'); + + var listenerCalled; + + eventBus.on('element.changed', function(e) { + if (e.element === diagramElement.label) { + listenerCalled = true; + } + }); + + // when + directEditActivate(diagramElement); + directEditComplete('BAR'); + + // then + expect(listenerCalled).to.be.true; + }); + + }); - it('gateway', directEdit('exclusive-gateway')); + describe('element support, should edit', function() { - it('gateway via label', directEdit('exclusive-gateway_label')); + function directEdit(elementId) { + + return inject(function(elementRegistry, eventBus, directEditing) { + + var diagramElement = elementRegistry.get(elementId); + + var label = LabelUtil.getLabel(diagramElement); - it('event', directEdit('intermediate-throw-event')); + // when + directEditActivate(diagramElement); - it('event via label', directEdit('intermediate-throw-event_label')); - - it('event without label', directEdit('start-event')); + // then + // expect editing to be active + expect(directEditing.getValue()).to.eql(label); + expect(directEditing.isActive()).to.be.true; - it('data store reference', directEdit('data-store-reference')); + // when + directEditComplete('B'); - it('data object reference', directEdit('data-object-reference')); + // then + // expect update to have happened + label = LabelUtil.getLabel(diagramElement); + expect(label).to.equal('B'); - it('sequenceflow', directEdit('sequence-flow-yes')); + // when + directEditActivate(diagramElement); + directEditCancel('C'); - it('sequenceflow without label', directEdit('sequenceflow-unlabeled')); - - it('sequenceflow via label', directEdit('sequence-flow-yes_label')); + // expect no label update to have happened + label = LabelUtil.getLabel(diagramElement); + expect(label).to.equal('B'); + }); + } - it('message flow', directEdit('message-flow')); - - it('message flow via label', directEdit('message-flow_label')); + it('task', directEdit('user-task')); - it('pool', directEdit('expanded-pool')); + it('gateway', directEdit('exclusive-gateway')); - it('pool, collapsed', directEdit('collapsed-pool')); + it('gateway via label', directEdit('exclusive-gateway_label')); - it('lane with label', directEdit('nested-lane-1-2')); + it('event', directEdit('intermediate-throw-event')); - it('lane without label', directEdit('nested-lane-no-label')); + it('event via label', directEdit('intermediate-throw-event_label')); + it('event without label', directEdit('start-event')); + + + it('data store reference', directEdit('data-store-reference')); + + it('data object reference', directEdit('data-object-reference')); + + + it('sequenceflow', directEdit('sequence-flow-yes')); + + it('sequenceflow without label', directEdit('sequenceflow-unlabeled')); + + it('sequenceflow via label', directEdit('sequence-flow-yes_label')); + + + it('message flow', directEdit('message-flow')); + + it('message flow via label', directEdit('message-flow_label')); + + + it('pool', directEdit('expanded-pool')); + + it('pool, collapsed', directEdit('collapsed-pool')); + + + it('lane with label', directEdit('nested-lane-1-2')); + + it('lane without label', directEdit('nested-lane-no-label')); + + }); }); });