diff --git a/lib/features/auto-resize/AutoResize.js b/lib/features/auto-resize/AutoResize.js index 28e67ed3..8e6ed928 100644 --- a/lib/features/auto-resize/AutoResize.js +++ b/lib/features/auto-resize/AutoResize.js @@ -9,7 +9,8 @@ var pick = require('lodash/object/pick'), assign = require('lodash/object/assign'), forEach = require('lodash/collection/forEach'), values = require('lodash/object/values'), - flatten = require('lodash/array/flatten'); + flatten = require('lodash/array/flatten'), + groupBy = require('lodash/collection/groupBy'); var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); @@ -20,7 +21,7 @@ var PADDING = { top: 2, bottom: 2, left: 15, right: 15 }; * An auto resize component that takes care of expanding parent participants * and lanes if elements are modeled close to an edge of the parent element. */ -function AutoResize(eventBus, canvas, modeling){ +function AutoResize(eventBus, canvas, modeling, elementRegistry){ CommandInterceptor.call(this, eventBus); @@ -35,27 +36,15 @@ function AutoResize(eventBus, canvas, modeling){ this.postExecuted([ 'elements.move' ], function(event) { var context = event.context, - elements = [], - parent = context.parent || context.newParent, - oldParent = context.hints && context.hints.oldParent, - primaryShape = context.hints && context.hints.primaryShape; + elements = flatten(values(context.closure.topLevel)); - forEach(flatten(values(context.closure.topLevel)), function(element) { - /** - * exclude the element, when: - * - the primary selection does not change parent AND - * - the primary selection parent is the new parent AND - * - its parent is different from the new parent - */ - if (oldParent && oldParent === parent && - primaryShape && primaryShape.parent === parent && - element.parent !== parent) { - return; - } - elements.push(element); + var expandings = groupBy(elements, function(element){ + return element.parent.id; }); - expand(elements, parent); + forEach(expandings, function(elements, parentId) { + expand(elements, parentId); + }); }); /** @@ -76,10 +65,10 @@ function AutoResize(eventBus, canvas, modeling){ */ function isInbounds(bbox, target, padding) { return { - top: bbox.y < target.y + padding.top && bbox.y + bbox.height > target.y, - bottom: bbox.y < target.y + target.height && bbox.y + bbox.height > target.y + target.height - padding.bottom, - left: bbox.x < target.x + padding.left && bbox.x + bbox.width > target.x, - right: bbox.x < target.x + target.width && bbox.x + bbox.width > target.x + target.width - padding.right, + top: bbox.y < target.y + padding.top, + bottom: bbox.y + bbox.height > target.y + target.height - padding.bottom, + left: bbox.x < target.x + padding.left, + right: bbox.x + bbox.width > target.x + target.width - padding.right, }; } @@ -88,11 +77,15 @@ function AutoResize(eventBus, canvas, modeling){ * considering the position of the bounding box in relation to the parent's edge plus padding. * The amount to expand can be defined for each edge in the OFFSET object. * - * @param {Array} [elements] - * @param {Shape} target + * @param {Array} elements + * @param {Shape|String} target|targetId */ function expand(elements, target) { + if (typeof target === 'string') { + target = elementRegistry.get(target); + } + var bbox = getBoundingBox(elements), canExpand = true; @@ -149,7 +142,7 @@ function AutoResize(eventBus, canvas, modeling){ } } -AutoResize.$inject = [ 'eventBus', 'canvas', 'modeling' ]; +AutoResize.$inject = [ 'eventBus', 'canvas', 'modeling', 'elementRegistry' ]; inherits(AutoResize, CommandInterceptor); diff --git a/test/spec/features/auto-resize/AutoResizeSpec.js b/test/spec/features/auto-resize/AutoResizeSpec.js index 982b30b2..818ceea7 100644 --- a/test/spec/features/auto-resize/AutoResizeSpec.js +++ b/test/spec/features/auto-resize/AutoResizeSpec.js @@ -120,17 +120,6 @@ describe('features/auto-resize', function() { })); - it('should not resize the parent if element is placed too far outside', - inject(function(modeling) { - - // when - modeling.moveElements([ task ], { x: 300, y: 0 }, participant); - - // then - expect(participant).to.have.bounds(originalBounds); - })); - - it('should resize the parent if element and parent edge intersect', inject(function(modeling) { @@ -456,6 +445,23 @@ describe('features/auto-resize', function() { })); + it('should expand non-primary parents', + inject(function(modeling) { + + // given + var originalBounds = getBounds(subProcessShape_1); + + // when + modeling.moveElements([ taskShape_1, taskShape_2 ], + { x: 100, y: 0 }, rootShape, { primaryShape: taskShape_2 }); + + // then + var expectedBounds = assign(originalBounds, { width: 525 }); + expect(subProcessShape_1).to.have.bounds(expectedBounds); + + })); + + it('should expand, if elements keep their parents (same original parent)', inject(function(modeling) { // given