2015-04-15 07:06:34 +00:00
|
|
|
'use strict';
|
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
var inherits = require('inherits');
|
|
|
|
|
2016-07-13 10:57:18 +00:00
|
|
|
var forEach = require('lodash/collection/forEach'),
|
|
|
|
assign = require('lodash/object/assign');
|
2015-04-27 14:50:09 +00:00
|
|
|
|
2015-04-15 07:06:34 +00:00
|
|
|
var getBoundingBox = require('diagram-js/lib/util/Elements').getBBox;
|
2015-10-09 23:41:32 +00:00
|
|
|
|
|
|
|
var is = require('../../util/ModelUtil').is,
|
|
|
|
isAny = require('../modeling/util/ModelingUtil').isAny,
|
2015-07-03 08:48:32 +00:00
|
|
|
isExpanded = require('../../util/DiUtil').isExpanded;
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
var Snapping = require('diagram-js/lib/features/snapping/Snapping'),
|
|
|
|
SnapUtil = require('diagram-js/lib/features/snapping/SnapUtil');
|
|
|
|
|
2015-10-09 23:41:32 +00:00
|
|
|
var asTRBL = require('diagram-js/lib/layout/LayoutUtil').asTRBL;
|
2015-07-03 08:48:32 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
var round = Math.round;
|
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
var mid = SnapUtil.mid,
|
|
|
|
topLeft = SnapUtil.topLeft,
|
2015-07-13 08:37:43 +00:00
|
|
|
bottomRight = SnapUtil.bottomRight,
|
2015-08-06 07:40:58 +00:00
|
|
|
isSnapped = SnapUtil.isSnapped,
|
2015-10-09 23:41:32 +00:00
|
|
|
setSnapped = SnapUtil.setSnapped;
|
|
|
|
|
|
|
|
var getBoundaryAttachment = require('./BpmnSnappingUtil').getBoundaryAttachment,
|
|
|
|
getParticipantSizeConstraints = require('./BpmnSnappingUtil').getParticipantSizeConstraints,
|
|
|
|
getLanesRoot = require('../modeling/util/LaneUtil').getLanesRoot;
|
|
|
|
|
2016-06-22 16:15:20 +00:00
|
|
|
var HIGH_PRIORITY = 1500;
|
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
|
2015-04-15 07:06:34 +00:00
|
|
|
/**
|
|
|
|
* BPMN specific snapping functionality
|
|
|
|
*
|
|
|
|
* * snap on process elements if a pool is created inside a
|
|
|
|
* process diagram
|
|
|
|
*
|
|
|
|
* @param {EventBus} eventBus
|
|
|
|
* @param {Canvas} canvas
|
|
|
|
*/
|
2015-10-09 23:41:32 +00:00
|
|
|
function BpmnSnapping(eventBus, canvas, bpmnRules, elementRegistry) {
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
// instantiate super
|
|
|
|
Snapping.call(this, eventBus, canvas);
|
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
|
2015-04-15 07:06:34 +00:00
|
|
|
/**
|
2015-04-27 14:50:09 +00:00
|
|
|
* Drop participant on process <> process elements snapping
|
2015-04-15 07:06:34 +00:00
|
|
|
*/
|
2015-08-06 07:40:58 +00:00
|
|
|
eventBus.on('create.start', function(event) {
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
var context = event.context,
|
|
|
|
shape = context.shape,
|
|
|
|
rootElement = canvas.getRootElement();
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
// snap participant around existing elements (if any)
|
|
|
|
if (is(shape, 'bpmn:Participant') && is(rootElement, 'bpmn:Process')) {
|
|
|
|
initParticipantSnapping(context, shape, rootElement.children);
|
2015-04-15 07:06:34 +00:00
|
|
|
}
|
2015-08-06 07:40:58 +00:00
|
|
|
});
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2016-06-22 16:15:20 +00:00
|
|
|
eventBus.on([ 'create.move', 'create.end' ], HIGH_PRIORITY, function(event) {
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
var context = event.context,
|
|
|
|
shape = context.shape,
|
|
|
|
participantSnapBox = context.participantSnapBox;
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
if (!isSnapped(event) && participantSnapBox) {
|
|
|
|
snapParticipant(participantSnapBox, shape, event);
|
2015-04-15 07:06:34 +00:00
|
|
|
}
|
2015-08-06 07:40:58 +00:00
|
|
|
});
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
eventBus.on('shape.move.start', function(event) {
|
2015-04-15 07:06:34 +00:00
|
|
|
|
|
|
|
var context = event.context,
|
|
|
|
shape = context.shape,
|
|
|
|
rootElement = canvas.getRootElement();
|
|
|
|
|
|
|
|
// snap participant around existing elements (if any)
|
2015-04-27 14:50:09 +00:00
|
|
|
if (is(shape, 'bpmn:Participant') && is(rootElement, 'bpmn:Process')) {
|
2015-04-15 07:06:34 +00:00
|
|
|
initParticipantSnapping(context, shape, rootElement.children);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
|
|
|
|
function canAttach(shape, target, position) {
|
|
|
|
return bpmnRules.canAttach([ shape ], target, null, position) === 'attach';
|
|
|
|
}
|
|
|
|
|
2016-07-13 10:57:18 +00:00
|
|
|
function canConnect(source, target) {
|
|
|
|
return bpmnRules.canConnect(source, target);
|
|
|
|
}
|
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
/**
|
|
|
|
* Snap boundary events to elements border
|
|
|
|
*/
|
2015-10-09 23:41:32 +00:00
|
|
|
eventBus.on([
|
|
|
|
'create.move',
|
|
|
|
'create.end',
|
|
|
|
'shape.move.move',
|
|
|
|
'shape.move.end'
|
2016-06-22 16:15:20 +00:00
|
|
|
], HIGH_PRIORITY, function(event) {
|
2015-04-15 07:06:34 +00:00
|
|
|
|
|
|
|
var context = event.context,
|
2015-08-06 07:40:58 +00:00
|
|
|
target = context.target,
|
|
|
|
shape = context.shape;
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
if (target && !isSnapped(event) && canAttach(shape, target, event)) {
|
|
|
|
snapBoundaryEvent(event, shape, target);
|
2015-04-15 07:06:34 +00:00
|
|
|
}
|
|
|
|
});
|
2015-04-28 11:24:55 +00:00
|
|
|
|
2015-10-09 23:41:32 +00:00
|
|
|
/**
|
|
|
|
* Adjust parent for flowElements to the target participant
|
|
|
|
* when droping onto lanes.
|
|
|
|
*/
|
|
|
|
eventBus.on([
|
|
|
|
'shape.move.hover',
|
|
|
|
'shape.move.move',
|
|
|
|
'shape.move.end',
|
|
|
|
'create.hover',
|
|
|
|
'create.move',
|
|
|
|
'create.end'
|
2016-06-22 16:15:20 +00:00
|
|
|
], HIGH_PRIORITY, function(event) {
|
2015-08-06 07:40:58 +00:00
|
|
|
var context = event.context,
|
2015-10-09 23:41:32 +00:00
|
|
|
shape = context.shape,
|
|
|
|
hover = event.hover;
|
2015-07-13 08:37:43 +00:00
|
|
|
|
2015-10-09 23:41:32 +00:00
|
|
|
if (is(hover, 'bpmn:Lane') && !isAny(shape, [ 'bpmn:Lane', 'bpmn:Participant' ])) {
|
|
|
|
event.hover = getLanesRoot(hover);
|
|
|
|
event.hoverGfx = elementRegistry.getGraphics(event.hover);
|
2015-08-06 07:40:58 +00:00
|
|
|
}
|
2015-07-13 08:37:43 +00:00
|
|
|
});
|
|
|
|
|
2016-07-13 10:57:18 +00:00
|
|
|
/**
|
|
|
|
* Snap sequence flows.
|
|
|
|
*/
|
|
|
|
eventBus.on([
|
|
|
|
'connect.move',
|
|
|
|
'connect.hover',
|
|
|
|
'connect.end'
|
|
|
|
], HIGH_PRIORITY, function(event) {
|
|
|
|
var context = event.context,
|
|
|
|
source = context.source,
|
|
|
|
target = context.target;
|
2015-08-06 07:40:58 +00:00
|
|
|
|
2016-07-13 10:57:18 +00:00
|
|
|
var connection = canConnect(source, target) || {};
|
2015-10-09 23:41:32 +00:00
|
|
|
|
2016-07-13 10:57:18 +00:00
|
|
|
if (!context.initialSourcePosition) {
|
|
|
|
context.initialSourcePosition = context.sourcePosition;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (target && connection.type === 'bpmn:SequenceFlow') {
|
|
|
|
|
|
|
|
// snap source
|
|
|
|
context.sourcePosition = mid(source);
|
|
|
|
|
|
|
|
// snap target
|
|
|
|
assign(event, mid(target));
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// otherwise reset source snap
|
|
|
|
context.sourcePosition = context.initialSourcePosition;
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
2015-10-09 23:41:32 +00:00
|
|
|
|
|
|
|
|
2016-06-22 16:15:20 +00:00
|
|
|
eventBus.on('resize.start', HIGH_PRIORITY, function(event) {
|
2015-04-28 11:24:55 +00:00
|
|
|
var context = event.context,
|
|
|
|
shape = context.shape;
|
|
|
|
|
2015-07-03 08:48:32 +00:00
|
|
|
if (is(shape, 'bpmn:SubProcess') && isExpanded(shape)) {
|
2015-10-09 23:41:32 +00:00
|
|
|
context.minDimensions = { width: 140, height: 120 };
|
2015-04-28 11:24:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (is(shape, 'bpmn:Participant')) {
|
2015-08-24 14:59:13 +00:00
|
|
|
context.minDimensions = { width: 300, height: 150 };
|
|
|
|
}
|
|
|
|
|
2015-10-09 23:41:32 +00:00
|
|
|
if (is(shape, 'bpmn:Lane') || is(shape, 'bpmn:Participant')) {
|
2015-10-22 18:35:34 +00:00
|
|
|
context.resizeConstraints = getParticipantSizeConstraints(shape, context.direction, context.balanced);
|
2015-04-28 11:24:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (is(shape, 'bpmn:TextAnnotation')) {
|
2016-03-03 16:51:07 +00:00
|
|
|
context.minDimensions = { width: 50, height: 30 };
|
2015-04-28 11:24:55 +00:00
|
|
|
}
|
|
|
|
});
|
2015-05-21 12:55:10 +00:00
|
|
|
|
2015-04-15 07:06:34 +00:00
|
|
|
}
|
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
inherits(BpmnSnapping, Snapping);
|
|
|
|
|
2015-10-09 23:41:32 +00:00
|
|
|
BpmnSnapping.$inject = [ 'eventBus', 'canvas', 'bpmnRules', 'elementRegistry' ];
|
2015-04-15 07:06:34 +00:00
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
module.exports = BpmnSnapping;
|
|
|
|
|
|
|
|
|
|
|
|
BpmnSnapping.prototype.initSnap = function(event) {
|
|
|
|
|
|
|
|
var context = event.context,
|
2015-07-13 08:37:43 +00:00
|
|
|
shape = event.shape,
|
2015-08-06 07:40:58 +00:00
|
|
|
shapeMid,
|
|
|
|
shapeBounds,
|
|
|
|
shapeTopLeft,
|
|
|
|
shapeBottomRight,
|
|
|
|
snapContext;
|
2015-04-27 14:50:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
snapContext = Snapping.prototype.initSnap.call(this, event);
|
|
|
|
|
|
|
|
if (is(shape, 'bpmn:Participant')) {
|
|
|
|
// assign higher priority for outer snaps on participants
|
|
|
|
snapContext.setSnapLocations([ 'top-left', 'bottom-right', 'mid' ]);
|
|
|
|
}
|
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
if (shape) {
|
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
shapeMid = mid(shape, event);
|
|
|
|
|
|
|
|
shapeBounds = {
|
|
|
|
width: shape.width,
|
|
|
|
height: shape.height,
|
|
|
|
x: isNaN(shape.x) ? round(shapeMid.x - shape.width / 2) : shape.x,
|
2016-06-07 06:46:45 +00:00
|
|
|
y: isNaN(shape.y) ? round(shapeMid.y - shape.height / 2) : shape.y
|
2015-08-06 07:40:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
shapeTopLeft = topLeft(shapeBounds);
|
|
|
|
shapeBottomRight = bottomRight(shapeBounds);
|
|
|
|
|
|
|
|
snapContext.setSnapOrigin('top-left', {
|
|
|
|
x: shapeTopLeft.x - event.x,
|
|
|
|
y: shapeTopLeft.y - event.y
|
|
|
|
});
|
2015-04-27 14:50:09 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
snapContext.setSnapOrigin('bottom-right', {
|
|
|
|
x: shapeBottomRight.x - event.x,
|
|
|
|
y: shapeBottomRight.y - event.y
|
2015-04-27 14:50:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
forEach(shape.outgoing, function(c) {
|
|
|
|
var docking = c.waypoints[0];
|
|
|
|
|
|
|
|
docking = docking.original || docking;
|
|
|
|
|
|
|
|
snapContext.setSnapOrigin(c.id + '-docking', {
|
|
|
|
x: docking.x - event.x,
|
|
|
|
y: docking.y - event.y
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
forEach(shape.incoming, function(c) {
|
|
|
|
var docking = c.waypoints[c.waypoints.length - 1];
|
|
|
|
|
|
|
|
docking = docking.original || docking;
|
|
|
|
|
|
|
|
snapContext.setSnapOrigin(c.id + '-docking', {
|
|
|
|
x: docking.x - event.x,
|
|
|
|
y: docking.y - event.y
|
|
|
|
});
|
|
|
|
});
|
2015-04-28 11:57:47 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var source = context.source;
|
|
|
|
|
|
|
|
if (source) {
|
|
|
|
snapContext.addDefaultSnap('mid', mid(source));
|
2015-04-27 14:50:09 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
BpmnSnapping.prototype.addTargetSnaps = function(snapPoints, shape, target) {
|
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
// use target parent as snap target
|
2015-09-07 13:07:09 +00:00
|
|
|
if (is(shape, 'bpmn:BoundaryEvent') && shape.type !== 'label') {
|
2015-08-06 07:40:58 +00:00
|
|
|
target = target.parent;
|
|
|
|
}
|
2015-04-27 14:50:09 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
// add sequence flow parents as snap targets
|
2015-05-21 12:55:10 +00:00
|
|
|
if (is(target, 'bpmn:SequenceFlow')) {
|
|
|
|
this.addTargetSnaps(snapPoints, shape, target.parent);
|
|
|
|
}
|
2015-04-27 14:50:09 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
var siblings = this.getSiblings(shape, target) || [];
|
|
|
|
|
2017-07-14 09:29:41 +00:00
|
|
|
forEach(siblings, function(sibling) {
|
2015-10-09 23:41:32 +00:00
|
|
|
|
|
|
|
// do not snap to lanes
|
2017-07-14 09:29:41 +00:00
|
|
|
if (is(sibling, 'bpmn:Lane')) {
|
2015-10-09 23:41:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-14 09:29:41 +00:00
|
|
|
if (sibling.waypoints) {
|
2015-04-27 14:50:09 +00:00
|
|
|
|
2017-12-10 12:48:35 +00:00
|
|
|
forEach(sibling.waypoints.slice(1, -1), function(waypoint, i) {
|
|
|
|
var nextWaypoint = sibling.waypoints[i + 2],
|
|
|
|
previousWaypoint = sibling.waypoints[i];
|
|
|
|
|
|
|
|
if (!nextWaypoint || !previousWaypoint) {
|
|
|
|
throw new Error('waypoints must exist');
|
2017-07-14 09:29:41 +00:00
|
|
|
}
|
|
|
|
|
2017-12-10 12:48:35 +00:00
|
|
|
if (nextWaypoint.x === waypoint.x ||
|
|
|
|
nextWaypoint.y === waypoint.y ||
|
|
|
|
previousWaypoint.x === waypoint.x ||
|
|
|
|
previousWaypoint.y === waypoint.y) {
|
2017-07-14 09:29:41 +00:00
|
|
|
snapPoints.add('mid', waypoint);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
snapPoints.add('mid', mid(sibling));
|
|
|
|
|
|
|
|
if (is(sibling, 'bpmn:Participant')) {
|
|
|
|
snapPoints.add('top-left', topLeft(sibling));
|
|
|
|
snapPoints.add('bottom-right', bottomRight(sibling));
|
2015-04-27 14:50:09 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
|
2015-04-27 14:50:09 +00:00
|
|
|
forEach(shape.incoming, function(c) {
|
|
|
|
|
|
|
|
if (siblings.indexOf(c.source) === -1) {
|
|
|
|
snapPoints.add('mid', mid(c.source));
|
|
|
|
}
|
2015-08-06 07:40:58 +00:00
|
|
|
|
|
|
|
var docking = c.waypoints[0];
|
|
|
|
snapPoints.add(c.id + '-docking', docking.original || docking);
|
2015-04-27 14:50:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
forEach(shape.outgoing, function(c) {
|
|
|
|
|
|
|
|
if (siblings.indexOf(c.target) === -1) {
|
|
|
|
snapPoints.add('mid', mid(c.target));
|
|
|
|
}
|
2015-04-28 11:57:47 +00:00
|
|
|
|
2015-08-06 07:40:58 +00:00
|
|
|
var docking = c.waypoints[c.waypoints.length - 1];
|
|
|
|
snapPoints.add(c.id + '-docking', docking.original || docking);
|
|
|
|
});
|
2015-05-28 07:30:50 +00:00
|
|
|
};
|
2015-08-06 07:40:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
/////// participant snapping //////////////////
|
|
|
|
|
|
|
|
function initParticipantSnapping(context, shape, elements) {
|
|
|
|
|
|
|
|
if (!elements.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var snapBox = getBoundingBox(elements.filter(function(e) {
|
|
|
|
return !e.labelTarget && !e.waypoints;
|
|
|
|
}));
|
|
|
|
|
|
|
|
snapBox.x -= 50;
|
|
|
|
snapBox.y -= 20;
|
|
|
|
snapBox.width += 70;
|
|
|
|
snapBox.height += 40;
|
|
|
|
|
|
|
|
// adjust shape height to include bounding box
|
|
|
|
shape.width = Math.max(shape.width, snapBox.width);
|
|
|
|
shape.height = Math.max(shape.height, snapBox.height);
|
|
|
|
|
|
|
|
context.participantSnapBox = snapBox;
|
|
|
|
}
|
|
|
|
|
|
|
|
function snapParticipant(snapBox, shape, event, offset) {
|
|
|
|
offset = offset || 0;
|
|
|
|
|
|
|
|
var shapeHalfWidth = shape.width / 2 - offset,
|
|
|
|
shapeHalfHeight = shape.height / 2;
|
|
|
|
|
|
|
|
var currentTopLeft = {
|
|
|
|
x: event.x - shapeHalfWidth - offset,
|
|
|
|
y: event.y - shapeHalfHeight
|
|
|
|
};
|
|
|
|
|
|
|
|
var currentBottomRight = {
|
|
|
|
x: event.x + shapeHalfWidth + offset,
|
|
|
|
y: event.y + shapeHalfHeight
|
|
|
|
};
|
|
|
|
|
|
|
|
var snapTopLeft = snapBox,
|
|
|
|
snapBottomRight = bottomRight(snapBox);
|
|
|
|
|
|
|
|
if (currentTopLeft.x >= snapTopLeft.x) {
|
|
|
|
setSnapped(event, 'x', snapTopLeft.x + offset + shapeHalfWidth);
|
|
|
|
} else
|
|
|
|
if (currentBottomRight.x <= snapBottomRight.x) {
|
|
|
|
setSnapped(event, 'x', snapBottomRight.x - offset - shapeHalfWidth);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currentTopLeft.y >= snapTopLeft.y) {
|
|
|
|
setSnapped(event, 'y', snapTopLeft.y + shapeHalfHeight);
|
|
|
|
} else
|
|
|
|
if (currentBottomRight.y <= snapBottomRight.y) {
|
|
|
|
setSnapped(event, 'y', snapBottomRight.y - shapeHalfHeight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/////// boundary event snapping /////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
function snapBoundaryEvent(event, shape, target) {
|
2015-10-09 23:41:32 +00:00
|
|
|
var targetTRBL = asTRBL(target);
|
2015-08-06 07:40:58 +00:00
|
|
|
|
|
|
|
var direction = getBoundaryAttachment(event, target);
|
|
|
|
|
|
|
|
if (/top/.test(direction)) {
|
|
|
|
setSnapped(event, 'y', targetTRBL.top);
|
|
|
|
} else
|
|
|
|
if (/bottom/.test(direction)) {
|
|
|
|
setSnapped(event, 'y', targetTRBL.bottom);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (/left/.test(direction)) {
|
|
|
|
setSnapped(event, 'x', targetTRBL.left);
|
|
|
|
} else
|
|
|
|
if (/right/.test(direction)) {
|
|
|
|
setSnapped(event, 'x', targetTRBL.right);
|
|
|
|
}
|
2016-03-03 16:51:07 +00:00
|
|
|
}
|