diff --git a/lib/utils/domFns.js b/lib/utils/domFns.js index a4c50b90..b44fd3eb 100644 --- a/lib/utils/domFns.js +++ b/lib/utils/domFns.js @@ -65,35 +65,35 @@ export function removeEvent(el: ?Node, event: string, handler: Function, inputOp } } -export function outerHeight(node: HTMLElement): number { +export function outerHeight(node: Element): number { // This is deliberately excluding margin for our calculations, since we are using // offsetTop which is including margin. See getBoundPosition - let height = node.clientHeight; + let height = Math.round(node.getBoundingClientRect().height); const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); height += int(computedStyle.borderTopWidth); height += int(computedStyle.borderBottomWidth); return height; } -export function outerWidth(node: HTMLElement): number { +export function outerWidth(node: Element): number { // This is deliberately excluding margin for our calculations, since we are using // offsetLeft which is including margin. See getBoundPosition - let width = node.clientWidth; + let width = Math.round(node.getBoundingClientRect().width); const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); width += int(computedStyle.borderLeftWidth); width += int(computedStyle.borderRightWidth); return width; } -export function innerHeight(node: HTMLElement): number { - let height = node.clientHeight; +export function innerHeight(node: Element): number { + let height = Math.round(node.getBoundingClientRect().height); const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); height -= int(computedStyle.paddingTop); height -= int(computedStyle.paddingBottom); return height; } -export function innerWidth(node: HTMLElement): number { - let width = node.clientWidth; +export function innerWidth(node: Element): number { + let width = Math.round(node.getBoundingClientRect().width); const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); width -= int(computedStyle.paddingLeft); width -= int(computedStyle.paddingRight); diff --git a/lib/utils/positionFns.js b/lib/utils/positionFns.js index 31346524..318208a3 100644 --- a/lib/utils/positionFns.js +++ b/lib/utils/positionFns.js @@ -13,7 +13,7 @@ export function getBoundPosition(draggable: Draggable, x: number, y: number): [n // Clone new bounds let {bounds} = draggable.props; bounds = typeof bounds === 'string' ? bounds : cloneBounds(bounds); - const node = findDOMNode(draggable); + const node: Element = findDOMNode(draggable); // for Flow, can't seem to work correctly ": Element" if (typeof bounds === 'string') { const {ownerDocument} = node; @@ -24,19 +24,31 @@ export function getBoundPosition(draggable: Draggable, x: number, y: number): [n } else { boundNode = ownerDocument.querySelector(bounds); } - if (!(boundNode instanceof ownerWindow.HTMLElement)) { + if (!(boundNode instanceof ownerWindow.Element)) { throw new Error('Bounds selector "' + bounds + '" could not find an element.'); } - const boundNodeEl: HTMLElement = boundNode; // for Flow, can't seem to refine correctly + const boundNodeEl: Element = boundNode; // for Flow, can't seem to work correctly ": Element" const nodeStyle = ownerWindow.getComputedStyle(node); const boundNodeStyle = ownerWindow.getComputedStyle(boundNodeEl); + + let nodeOffsetLeft: number, nodeOffsetTop: number; + + if (node instanceof HTMLElement) { + nodeOffsetLeft = node.offsetLeft; + nodeOffsetTop = node.offsetTop; + } else { + // if node is not HTMLElement, Compute nodeOffsetLeft, nodeOffsetTop from boundNode + nodeOffsetLeft = int(boundNodeStyle.paddingLeft) + int(nodeStyle.marginLeft); + nodeOffsetTop = int(boundNodeStyle.paddingLeft) + int(nodeStyle.marginLeft); + } + // Compute bounds. This is a pain with padding and offsets but this gets it exactly right. bounds = { - left: -node.offsetLeft + int(boundNodeStyle.paddingLeft) + int(nodeStyle.marginLeft), - top: -node.offsetTop + int(boundNodeStyle.paddingTop) + int(nodeStyle.marginTop), - right: innerWidth(boundNodeEl) - outerWidth(node) - node.offsetLeft + + left: -nodeOffsetLeft + int(boundNodeStyle.paddingLeft) + int(nodeStyle.marginLeft), + top: -nodeOffsetTop + int(boundNodeStyle.paddingTop) + int(nodeStyle.marginTop), + right: innerWidth(boundNodeEl) - outerWidth(node) - nodeOffsetLeft + int(boundNodeStyle.paddingRight) - int(nodeStyle.marginRight), - bottom: innerHeight(boundNodeEl) - outerHeight(node) - node.offsetTop + + bottom: innerHeight(boundNodeEl) - outerHeight(node) - nodeOffsetTop + int(boundNodeStyle.paddingBottom) - int(nodeStyle.marginBottom) }; }