all files / lib/features/modeling/cmd/helper/ MoveHelper.js

100% Statements 24/24
100% Branches 21/21
100% Functions 6/6
100% Lines 24/24
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99                                      1118×                             43×   39×                       215×   215× 215× 215× 215× 215×   215× 19×       215×     261×             215×   48× 48×   48× 17×   31×                           215×  
import {
  forEach
} from 'min-dash';
 
import {
  getMovedSourceAnchor,
  getMovedTargetAnchor
} from './AnchorsHelper';
 
import MoveClosure from './MoveClosure';
 
 
/**
 * A helper that is able to carry out serialized move
 * operations on multiple elements.
 *
 * @param {Modeling} modeling
 */
export default function MoveHelper(modeling) {
  this._modeling = modeling;
}
 
/**
 * Move the specified elements and all children by the given delta.
 *
 * This moves all enclosed connections, too and layouts all affected
 * external connections.
 *
 * @param  {Array<djs.model.Base>} elements
 * @param  {Point} delta
 * @param  {djs.model.Base} newParent applied to the first level of shapes
 *
 * @return {Array<djs.model.Base>} list of touched elements
 */
MoveHelper.prototype.moveRecursive = function(elements, delta, newParent) {
  if (!elements) {
    return [];
  } else {
    return this.moveClosure(this.getClosure(elements), delta, newParent);
  }
};
 
/**
 * Move the given closure of elmements.
 *
 * @param {Object} closure
 * @param {Point} delta
 * @param {djs.model.Base} [newParent]
 * @param {djs.model.Base} [newHost]
 */
MoveHelper.prototype.moveClosure = function(closure, delta, newParent, newHost, primaryShape) {
  var modeling = this._modeling;
 
  var allShapes = closure.allShapes,
      allConnections = closure.allConnections,
      enclosedConnections = closure.enclosedConnections,
      topLevel = closure.topLevel,
      keepParent = false;
 
  if (primaryShape && primaryShape.parent === newParent) {
    keepParent = true;
  }
 
  // move all shapes
  forEach(allShapes, function(shape) {
 
    // move the element according to the given delta
    modeling.moveShape(shape, delta, topLevel[shape.id] && !keepParent && newParent, {
      recurse: false,
      layout: false
    });
  });
 
  // move all child connections / layout external connections
  forEach(allConnections, function(c) {
 
    var sourceMoved = !!allShapes[c.source.id],
        targetMoved = !!allShapes[c.target.id];
 
    if (enclosedConnections[c.id] && sourceMoved && targetMoved) {
      modeling.moveConnection(c, delta, topLevel[c.id] && !keepParent && newParent);
    } else {
      modeling.layoutConnection(c, {
        connectionStart: sourceMoved && getMovedSourceAnchor(c, c.source, delta),
        connectionEnd: targetMoved && getMovedTargetAnchor(c, c.target, delta)
      });
    }
  });
};
 
/**
 * Returns the closure for the selected elements
 *
 * @param  {Array<djs.model.Base>} elements
 * @return {MoveClosure} closure
 */
MoveHelper.prototype.getClosure = function(elements) {
  return new MoveClosure().addAll(elements, true);
};