diff --git a/lib/features/modeling/behavior/ResizeBehavior.js b/lib/features/modeling/behavior/ResizeBehavior.js index 935752cf..e63f91ad 100644 --- a/lib/features/modeling/behavior/ResizeBehavior.js +++ b/lib/features/modeling/behavior/ResizeBehavior.js @@ -2,7 +2,14 @@ import { is } from '../../../util/ModelUtil'; import { isExpanded } from '../../../util/DiUtil'; -import { getParticipantResizeConstraints } from './util/ResizeUtil'; +import { + asTRBL +} from 'diagram-js/lib/layout/LayoutUtil'; + +import { + collectLanes, + getLanesRoot +} from '../util/LaneUtil'; var HIGH_PRIORITY = 1500; @@ -14,7 +21,6 @@ export var SUB_PROCESS_MIN_DIMENSIONS = { width: 140, height: 120 }; export var TEXT_ANNOTATION_MIN_DIMENSIONS = { width: 50, height: 30 }; - /** * Set minimum bounds/resize constraints on resize. * @@ -45,4 +51,124 @@ export default function ResizeBehavior(eventBus) { }); } -ResizeBehavior.$inject = [ 'eventBus' ]; \ No newline at end of file +ResizeBehavior.$inject = [ 'eventBus' ]; + + +var abs = Math.abs, + min = Math.min, + max = Math.max; + + +function addToTrbl(trbl, attr, value, choice) { + var current = trbl[attr]; + + // make sure to set the value if it does not exist + // or apply the correct value by comparing against + // choice(value, currentValue) + trbl[attr] = current === undefined ? value : choice(value, current); +} + +function addMin(trbl, attr, value) { + return addToTrbl(trbl, attr, value, min); +} + +function addMax(trbl, attr, value) { + return addToTrbl(trbl, attr, value, max); +} + +var LANE_RIGHT_PADDING = 20, + LANE_LEFT_PADDING = 50, + LANE_TOP_PADDING = 20, + LANE_BOTTOM_PADDING = 20; + +export function getParticipantResizeConstraints(laneShape, resizeDirection, balanced) { + var lanesRoot = getLanesRoot(laneShape); + + var isFirst = true, + isLast = true; + + // max top/bottom size for lanes + var allLanes = collectLanes(lanesRoot, [ lanesRoot ]); + + var laneTrbl = asTRBL(laneShape); + + var maxTrbl = {}, + minTrbl = {}; + + if (/e/.test(resizeDirection)) { + minTrbl.right = laneTrbl.left + LANE_MIN_DIMENSIONS.width; + } else + if (/w/.test(resizeDirection)) { + minTrbl.left = laneTrbl.right - LANE_MIN_DIMENSIONS.width; + } + + allLanes.forEach(function(other) { + + var otherTrbl = asTRBL(other); + + if (/n/.test(resizeDirection)) { + + if (otherTrbl.top < (laneTrbl.top - 10)) { + isFirst = false; + } + + // max top size (based on next element) + if (balanced && abs(laneTrbl.top - otherTrbl.bottom) < 10) { + addMax(maxTrbl, 'top', otherTrbl.top + LANE_MIN_DIMENSIONS.height); + } + + // min top size (based on self or nested element) + if (abs(laneTrbl.top - otherTrbl.top) < 5) { + addMin(minTrbl, 'top', otherTrbl.bottom - LANE_MIN_DIMENSIONS.height); + } + } + + if (/s/.test(resizeDirection)) { + + if (otherTrbl.bottom > (laneTrbl.bottom + 10)) { + isLast = false; + } + + // max bottom size (based on previous element) + if (balanced && abs(laneTrbl.bottom - otherTrbl.top) < 10) { + addMin(maxTrbl, 'bottom', otherTrbl.bottom - LANE_MIN_DIMENSIONS.height); + } + + // min bottom size (based on self or nested element) + if (abs(laneTrbl.bottom - otherTrbl.bottom) < 5) { + addMax(minTrbl, 'bottom', otherTrbl.top + LANE_MIN_DIMENSIONS.height); + } + } + }); + + // max top/bottom/left/right size based on flow nodes + var flowElements = lanesRoot.children.filter(function(s) { + return !s.hidden && !s.waypoints && (is(s, 'bpmn:FlowElement') || is(s, 'bpmn:Artifact')); + }); + + flowElements.forEach(function(flowElement) { + + var flowElementTrbl = asTRBL(flowElement); + + if (isFirst && /n/.test(resizeDirection)) { + addMin(minTrbl, 'top', flowElementTrbl.top - LANE_TOP_PADDING); + } + + if (/e/.test(resizeDirection)) { + addMax(minTrbl, 'right', flowElementTrbl.right + LANE_RIGHT_PADDING); + } + + if (isLast && /s/.test(resizeDirection)) { + addMax(minTrbl, 'bottom', flowElementTrbl.bottom + LANE_BOTTOM_PADDING); + } + + if (/w/.test(resizeDirection)) { + addMin(minTrbl, 'left', flowElementTrbl.left - LANE_LEFT_PADDING); + } + }); + + return { + min: minTrbl, + max: maxTrbl + }; +} \ No newline at end of file diff --git a/lib/features/modeling/behavior/util/ResizeUtil.js b/lib/features/modeling/behavior/util/ResizeUtil.js index f0bfd86e..49b66e6a 100644 --- a/lib/features/modeling/behavior/util/ResizeUtil.js +++ b/lib/features/modeling/behavior/util/ResizeUtil.js @@ -1,132 +1 @@ -import { is } from '../../../../util/ModelUtil'; - -import { - asTRBL -} from 'diagram-js/lib/layout/LayoutUtil'; - -import { - collectLanes, - getLanesRoot -} from '../../../modeling/util/LaneUtil'; - -import { LANE_MIN_DIMENSIONS } from '../ResizeBehavior'; - -var abs = Math.abs, - min = Math.min, - max = Math.max; - - -function addToTrbl(trbl, attr, value, choice) { - var current = trbl[attr]; - - // make sure to set the value if it does not exist - // or apply the correct value by comparing against - // choice(value, currentValue) - trbl[attr] = current === undefined ? value : choice(value, current); -} - -function addMin(trbl, attr, value) { - return addToTrbl(trbl, attr, value, min); -} - -function addMax(trbl, attr, value) { - return addToTrbl(trbl, attr, value, max); -} - -var LANE_RIGHT_PADDING = 20, - LANE_LEFT_PADDING = 50, - LANE_TOP_PADDING = 20, - LANE_BOTTOM_PADDING = 20; - - -export function getParticipantResizeConstraints(laneShape, resizeDirection, balanced) { - var lanesRoot = getLanesRoot(laneShape); - - var isFirst = true, - isLast = true; - - // max top/bottom size for lanes - var allLanes = collectLanes(lanesRoot, [ lanesRoot ]); - - var laneTrbl = asTRBL(laneShape); - - var maxTrbl = {}, - minTrbl = {}; - - if (/e/.test(resizeDirection)) { - minTrbl.right = laneTrbl.left + LANE_MIN_DIMENSIONS.width; - } else - if (/w/.test(resizeDirection)) { - minTrbl.left = laneTrbl.right - LANE_MIN_DIMENSIONS.width; - } - - allLanes.forEach(function(other) { - - var otherTrbl = asTRBL(other); - - if (/n/.test(resizeDirection)) { - - if (otherTrbl.top < (laneTrbl.top - 10)) { - isFirst = false; - } - - // max top size (based on next element) - if (balanced && abs(laneTrbl.top - otherTrbl.bottom) < 10) { - addMax(maxTrbl, 'top', otherTrbl.top + LANE_MIN_DIMENSIONS.height); - } - - // min top size (based on self or nested element) - if (abs(laneTrbl.top - otherTrbl.top) < 5) { - addMin(minTrbl, 'top', otherTrbl.bottom - LANE_MIN_DIMENSIONS.height); - } - } - - if (/s/.test(resizeDirection)) { - - if (otherTrbl.bottom > (laneTrbl.bottom + 10)) { - isLast = false; - } - - // max bottom size (based on previous element) - if (balanced && abs(laneTrbl.bottom - otherTrbl.top) < 10) { - addMin(maxTrbl, 'bottom', otherTrbl.bottom - LANE_MIN_DIMENSIONS.height); - } - - // min bottom size (based on self or nested element) - if (abs(laneTrbl.bottom - otherTrbl.bottom) < 5) { - addMax(minTrbl, 'bottom', otherTrbl.top + LANE_MIN_DIMENSIONS.height); - } - } - }); - - // max top/bottom/left/right size based on flow nodes - var flowElements = lanesRoot.children.filter(function(s) { - return !s.hidden && !s.waypoints && (is(s, 'bpmn:FlowElement') || is(s, 'bpmn:Artifact')); - }); - - flowElements.forEach(function(flowElement) { - - var flowElementTrbl = asTRBL(flowElement); - - if (isFirst && /n/.test(resizeDirection)) { - addMin(minTrbl, 'top', flowElementTrbl.top - LANE_TOP_PADDING); - } - - if (/e/.test(resizeDirection)) { - addMax(minTrbl, 'right', flowElementTrbl.right + LANE_RIGHT_PADDING); - } - - if (isLast && /s/.test(resizeDirection)) { - addMax(minTrbl, 'bottom', flowElementTrbl.bottom + LANE_BOTTOM_PADDING); - } - - if (/w/.test(resizeDirection)) { - addMin(minTrbl, 'left', flowElementTrbl.left - LANE_LEFT_PADDING); - } - }); - - return { - min: minTrbl, - max: maxTrbl - }; -} \ No newline at end of file +export { getParticipantResizeConstraints } from '../ResizeBehavior'; \ No newline at end of file diff --git a/test/spec/features/modeling/behavior/util/ResizeUtil.lanes-flowNodes.bpmn b/test/spec/features/modeling/behavior/ResizeBehavior.utility.lanes-flowNodes.bpmn similarity index 100% rename from test/spec/features/modeling/behavior/util/ResizeUtil.lanes-flowNodes.bpmn rename to test/spec/features/modeling/behavior/ResizeBehavior.utility.lanes-flowNodes.bpmn diff --git a/test/spec/features/modeling/behavior/util/ResizeUtil.lanes.bpmn b/test/spec/features/modeling/behavior/ResizeBehavior.utility.lanes.bpmn similarity index 100% rename from test/spec/features/modeling/behavior/util/ResizeUtil.lanes.bpmn rename to test/spec/features/modeling/behavior/ResizeBehavior.utility.lanes.bpmn diff --git a/test/spec/features/modeling/behavior/ResizeBehaviorSpec.js b/test/spec/features/modeling/behavior/ResizeBehaviorSpec.js index 15139dcd..9020913c 100644 --- a/test/spec/features/modeling/behavior/ResizeBehaviorSpec.js +++ b/test/spec/features/modeling/behavior/ResizeBehaviorSpec.js @@ -13,6 +13,10 @@ import { createCanvasEvent as canvasEvent } from '../../../../util/MockEvents'; +import { + getParticipantResizeConstraints +} from 'lib/features/modeling/behavior/ResizeBehavior'; + var testModules = [ coreModule, modelingModule, @@ -255,4 +259,280 @@ describe('features/modeling - resize behavior', function() { }); +}); + + +var LANE_MIN_HEIGHT = 60, + LANE_RIGHT_PADDING = 20, + LANE_LEFT_PADDING = 50, + LANE_TOP_PADDING = 20, + LANE_BOTTOM_PADDING = 20; + +describe('modeling/behavior - resize behavior - utilities', function() { + + describe('#getParticipantResizeConstraints', function() { + + describe('lanes', function() { + + var diagramXML = require('./ResizeBehavior.utility.lanes.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { modules: [ coreModule ] })); + + + it('resize participant (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Participant_Lane'), + otherLaneShape = elementRegistry.get('Lane_B'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: otherLaneShape.y + LANE_MIN_HEIGHT + }, + max: {} + }); + + })); + + + it('bottom lane (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_B'), + otherLaneShape = elementRegistry.get('Lane_B'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: otherLaneShape.y + LANE_MIN_HEIGHT + }, + max: {} + }); + + })); + + + it('resize participant (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Participant_Lane'), + otherLaneShape = elementRegistry.get('Nested_Lane_A'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT + }, + max: {} + }); + + })); + + + it('resize top lane (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_A'), + otherLaneShape = elementRegistry.get('Nested_Lane_A'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT + }, + max: {} + }); + + })); + + + it('resize middle lane (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Nested_Lane_B'), + aboveLaneShape = elementRegistry.get('Nested_Lane_A'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n', true); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: resizeShape.y + resizeShape.height - LANE_MIN_HEIGHT + }, + max: { + top: aboveLaneShape.y + LANE_MIN_HEIGHT + } + }); + + })); + + + it('resize middle lane (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Nested_Lane_B'), + otherLaneShape = elementRegistry.get('Lane_B'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's', true); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: resizeShape.y + LANE_MIN_HEIGHT + }, + max: { + bottom: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT + } + }); + + })); + + }); + + + describe('flowNodes', function() { + + var diagramXML = require('./ResizeBehavior.utility.lanes-flowNodes.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { modules: [ coreModule ] })); + + + it('resize participant (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Participant_Lane'), + taskShape = elementRegistry.get('Task'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: taskShape.y + taskShape.height + LANE_BOTTOM_PADDING + }, + max: {} + }); + + })); + + + it('bottom lane (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_B'), + taskShape = elementRegistry.get('Task'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: taskShape.y + taskShape.height + LANE_BOTTOM_PADDING + }, + max: {} + }); + + })); + + + it('resize participant (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Participant_Lane'), + taskShape = elementRegistry.get('Task_Boundary'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: taskShape.y - LANE_TOP_PADDING + }, + max: {} + }); + + })); + + + it('resize top lane (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_A'), + taskShape = elementRegistry.get('Task_Boundary'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: taskShape.y - LANE_TOP_PADDING + }, + max: {} + }); + + })); + + + it('resize lane (W)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Nested_Lane_B'), + otherShape = elementRegistry.get('Boundary_label'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'w'); + + // then + expect(sizeConstraints).to.eql({ + min: { + left: otherShape.x - LANE_LEFT_PADDING + }, + max: { } + }); + + })); + + + it('resize lane (E)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_B'), + otherShape = elementRegistry.get('Task'); + + // when + var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'e'); + + // then + expect(sizeConstraints).to.eql({ + min: { + right: otherShape.x + otherShape.width + LANE_RIGHT_PADDING + }, + max: { } + }); + + })); + + }); + + }); + }); \ No newline at end of file diff --git a/test/spec/features/modeling/behavior/util/ResizeUtilSpec.js b/test/spec/features/modeling/behavior/util/ResizeUtilSpec.js index ac726c65..3bca23da 100644 --- a/test/spec/features/modeling/behavior/util/ResizeUtilSpec.js +++ b/test/spec/features/modeling/behavior/util/ResizeUtilSpec.js @@ -1,282 +1,14 @@ import { - bootstrapModeler, - inject -} from 'test/TestHelper'; - -import { getParticipantResizeConstraints } from 'lib/features/modeling/behavior/util/ResizeUtil'; - -import coreModule from 'lib/core'; - -var LANE_MIN_HEIGHT = 60, - LANE_RIGHT_PADDING = 20, - LANE_LEFT_PADDING = 50, - LANE_TOP_PADDING = 20, - LANE_BOTTOM_PADDING = 20; + getParticipantResizeConstraints +} from 'lib/features/modeling/behavior/util/ResizeUtil'; describe('modeling/behavior/util - Resize', function() { describe('#getParticipantResizeConstraints', function() { - describe('lanes', function() { - - var diagramXML = require('./ResizeUtil.lanes.bpmn'); - - beforeEach(bootstrapModeler(diagramXML, { modules: [ coreModule ] })); - - - it('resize participant (S)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Participant_Lane'), - otherLaneShape = elementRegistry.get('Lane_B'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's'); - - // then - expect(sizeConstraints).to.eql({ - min: { - bottom: otherLaneShape.y + LANE_MIN_HEIGHT - }, - max: {} - }); - - })); - - - it('bottom lane (S)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Lane_B'), - otherLaneShape = elementRegistry.get('Lane_B'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's'); - - // then - expect(sizeConstraints).to.eql({ - min: { - bottom: otherLaneShape.y + LANE_MIN_HEIGHT - }, - max: {} - }); - - })); - - - it('resize participant (N)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Participant_Lane'), - otherLaneShape = elementRegistry.get('Nested_Lane_A'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n'); - - // then - expect(sizeConstraints).to.eql({ - min: { - top: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT - }, - max: {} - }); - - })); - - - it('resize top lane (N)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Lane_A'), - otherLaneShape = elementRegistry.get('Nested_Lane_A'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n'); - - // then - expect(sizeConstraints).to.eql({ - min: { - top: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT - }, - max: {} - }); - - })); - - - it('resize middle lane (N)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Nested_Lane_B'), - aboveLaneShape = elementRegistry.get('Nested_Lane_A'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n', true); - - // then - expect(sizeConstraints).to.eql({ - min: { - top: resizeShape.y + resizeShape.height - LANE_MIN_HEIGHT - }, - max: { - top: aboveLaneShape.y + LANE_MIN_HEIGHT - } - }); - - })); - - - it('resize middle lane (S)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Nested_Lane_B'), - otherLaneShape = elementRegistry.get('Lane_B'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's', true); - - // then - expect(sizeConstraints).to.eql({ - min: { - bottom: resizeShape.y + LANE_MIN_HEIGHT - }, - max: { - bottom: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT - } - }); - - })); - - }); - - - describe('flowNodes', function() { - - var diagramXML = require('./ResizeUtil.lanes-flowNodes.bpmn'); - - beforeEach(bootstrapModeler(diagramXML, { modules: [ coreModule ] })); - - - it('resize participant (S)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Participant_Lane'), - taskShape = elementRegistry.get('Task'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's'); - - // then - expect(sizeConstraints).to.eql({ - min: { - bottom: taskShape.y + taskShape.height + LANE_BOTTOM_PADDING - }, - max: {} - }); - - })); - - - it('bottom lane (S)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Lane_B'), - taskShape = elementRegistry.get('Task'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 's'); - - // then - expect(sizeConstraints).to.eql({ - min: { - bottom: taskShape.y + taskShape.height + LANE_BOTTOM_PADDING - }, - max: {} - }); - - })); - - - it('resize participant (N)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Participant_Lane'), - taskShape = elementRegistry.get('Task_Boundary'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n'); - - // then - expect(sizeConstraints).to.eql({ - min: { - top: taskShape.y - LANE_TOP_PADDING - }, - max: {} - }); - - })); - - - it('resize top lane (N)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Lane_A'), - taskShape = elementRegistry.get('Task_Boundary'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'n'); - - // then - expect(sizeConstraints).to.eql({ - min: { - top: taskShape.y - LANE_TOP_PADDING - }, - max: {} - }); - - })); - - - it('resize lane (W)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Nested_Lane_B'), - otherShape = elementRegistry.get('Boundary_label'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'w'); - - // then - expect(sizeConstraints).to.eql({ - min: { - left: otherShape.x - LANE_LEFT_PADDING - }, - max: { } - }); - - })); - - - it('resize lane (E)', inject(function(elementRegistry) { - - // given - var resizeShape = elementRegistry.get('Lane_B'), - otherShape = elementRegistry.get('Task'); - - // when - var sizeConstraints = getParticipantResizeConstraints(resizeShape, 'e'); - - // then - expect(sizeConstraints).to.eql({ - min: { - right: otherShape.x + otherShape.width + LANE_RIGHT_PADDING - }, - max: { } - }); - - })); - + it('should expose', function() { + expect(getParticipantResizeConstraints).to.exist; }); });