| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { |
| value: true |
| }); |
| exports.canDragX = canDragX; |
| exports.canDragY = canDragY; |
| exports.createCoreData = createCoreData; |
| exports.createDraggableData = createDraggableData; |
| exports.getBoundPosition = getBoundPosition; |
| exports.getControlPosition = getControlPosition; |
| exports.snapToGrid = snapToGrid; |
| |
| var _shims = require("./shims"); |
| |
| var _domFns = require("./domFns"); |
| |
| function getBoundPosition(draggable |
| /*: Draggable*/ |
| , x |
| /*: number*/ |
| , y |
| /*: number*/ |
| ) |
| /*: [number, number]*/ |
| { |
| // If no bounds, short-circuit and move on |
| if (!draggable.props.bounds) return [x, y]; // Clone new bounds |
| |
| var bounds = draggable.props.bounds; |
| bounds = typeof bounds === 'string' ? bounds : cloneBounds(bounds); |
| var node = findDOMNode(draggable); |
| |
| if (typeof bounds === 'string') { |
| var ownerDocument = node.ownerDocument; |
| var ownerWindow = ownerDocument.defaultView; |
| var boundNode; |
| |
| if (bounds === 'parent') { |
| boundNode = node.parentNode; |
| } else { |
| boundNode = ownerDocument.querySelector(bounds); |
| } |
| |
| if (!(boundNode instanceof ownerWindow.HTMLElement)) { |
| throw new Error('Bounds selector "' + bounds + '" could not find an element.'); |
| } |
| |
| var boundNodeEl |
| /*: HTMLElement*/ |
| = boundNode; // for Flow, can't seem to refine correctly |
| |
| var nodeStyle = ownerWindow.getComputedStyle(node); |
| var boundNodeStyle = ownerWindow.getComputedStyle(boundNodeEl); // Compute bounds. This is a pain with padding and offsets but this gets it exactly right. |
| |
| bounds = { |
| left: -node.offsetLeft + (0, _shims.int)(boundNodeStyle.paddingLeft) + (0, _shims.int)(nodeStyle.marginLeft), |
| top: -node.offsetTop + (0, _shims.int)(boundNodeStyle.paddingTop) + (0, _shims.int)(nodeStyle.marginTop), |
| right: (0, _domFns.innerWidth)(boundNodeEl) - (0, _domFns.outerWidth)(node) - node.offsetLeft + (0, _shims.int)(boundNodeStyle.paddingRight) - (0, _shims.int)(nodeStyle.marginRight), |
| bottom: (0, _domFns.innerHeight)(boundNodeEl) - (0, _domFns.outerHeight)(node) - node.offsetTop + (0, _shims.int)(boundNodeStyle.paddingBottom) - (0, _shims.int)(nodeStyle.marginBottom) |
| }; |
| } // Keep x and y below right and bottom limits... |
| |
| |
| if ((0, _shims.isNum)(bounds.right)) x = Math.min(x, bounds.right); |
| if ((0, _shims.isNum)(bounds.bottom)) y = Math.min(y, bounds.bottom); // But above left and top limits. |
| |
| if ((0, _shims.isNum)(bounds.left)) x = Math.max(x, bounds.left); |
| if ((0, _shims.isNum)(bounds.top)) y = Math.max(y, bounds.top); |
| return [x, y]; |
| } |
| |
| function snapToGrid(grid |
| /*: [number, number]*/ |
| , pendingX |
| /*: number*/ |
| , pendingY |
| /*: number*/ |
| ) |
| /*: [number, number]*/ |
| { |
| var x = Math.round(pendingX / grid[0]) * grid[0]; |
| var y = Math.round(pendingY / grid[1]) * grid[1]; |
| return [x, y]; |
| } |
| |
| function canDragX(draggable |
| /*: Draggable*/ |
| ) |
| /*: boolean*/ |
| { |
| return draggable.props.axis === 'both' || draggable.props.axis === 'x'; |
| } |
| |
| function canDragY(draggable |
| /*: Draggable*/ |
| ) |
| /*: boolean*/ |
| { |
| return draggable.props.axis === 'both' || draggable.props.axis === 'y'; |
| } // Get {x, y} positions from event. |
| |
| |
| function getControlPosition(e |
| /*: MouseTouchEvent*/ |
| , touchIdentifier |
| /*: ?number*/ |
| , draggableCore |
| /*: DraggableCore*/ |
| ) |
| /*: ?ControlPosition*/ |
| { |
| var touchObj = typeof touchIdentifier === 'number' ? (0, _domFns.getTouch)(e, touchIdentifier) : null; |
| if (typeof touchIdentifier === 'number' && !touchObj) return null; // not the right touch |
| |
| var node = findDOMNode(draggableCore); // User can provide an offsetParent if desired. |
| |
| var offsetParent = draggableCore.props.offsetParent || node.offsetParent || node.ownerDocument.body; |
| return (0, _domFns.offsetXYFromParent)(touchObj || e, offsetParent, draggableCore.props.scale); |
| } // Create an data object exposed by <DraggableCore>'s events |
| |
| |
| function createCoreData(draggable |
| /*: DraggableCore*/ |
| , x |
| /*: number*/ |
| , y |
| /*: number*/ |
| ) |
| /*: DraggableData*/ |
| { |
| var state = draggable.state; |
| var isStart = !(0, _shims.isNum)(state.lastX); |
| var node = findDOMNode(draggable); |
| |
| if (isStart) { |
| // If this is our first move, use the x and y as last coords. |
| return { |
| node: node, |
| deltaX: 0, |
| deltaY: 0, |
| lastX: x, |
| lastY: y, |
| x: x, |
| y: y |
| }; |
| } else { |
| // Otherwise calculate proper values. |
| return { |
| node: node, |
| deltaX: x - state.lastX, |
| deltaY: y - state.lastY, |
| lastX: state.lastX, |
| lastY: state.lastY, |
| x: x, |
| y: y |
| }; |
| } |
| } // Create an data exposed by <Draggable>'s events |
| |
| |
| function createDraggableData(draggable |
| /*: Draggable*/ |
| , coreData |
| /*: DraggableData*/ |
| ) |
| /*: DraggableData*/ |
| { |
| var scale = draggable.props.scale; |
| return { |
| node: coreData.node, |
| x: draggable.state.x + coreData.deltaX / scale, |
| y: draggable.state.y + coreData.deltaY / scale, |
| deltaX: coreData.deltaX / scale, |
| deltaY: coreData.deltaY / scale, |
| lastX: draggable.state.x, |
| lastY: draggable.state.y |
| }; |
| } // A lot faster than stringify/parse |
| |
| |
| function cloneBounds(bounds |
| /*: Bounds*/ |
| ) |
| /*: Bounds*/ |
| { |
| return { |
| left: bounds.left, |
| top: bounds.top, |
| right: bounds.right, |
| bottom: bounds.bottom |
| }; |
| } |
| |
| function findDOMNode(draggable |
| /*: Draggable | DraggableCore*/ |
| ) |
| /*: HTMLElement*/ |
| { |
| var node = draggable.findDOMNode(); |
| |
| if (!node) { |
| throw new Error('<DraggableCore>: Unmounted during event!'); |
| } // $FlowIgnore we can't assert on HTMLElement due to tests... FIXME |
| |
| |
| return node; |
| } |