From 86eee400ec6a0ef741e4734c15e254f2e2b0ebb3 Mon Sep 17 00:00:00 2001 From: Nik Nyby Date: Thu, 23 Jun 2016 13:21:10 -0400 Subject: [PATCH 1/3] Add missing comma in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40e3a540..5eb7882c 100644 --- a/README.md +++ b/README.md @@ -253,7 +253,7 @@ on itself and thus must have callbacks attached to be useful. handle: string, onStart: DraggableEventHandler, onDrag: DraggableEventHandler, - onStop: DraggableEventHandler + onStop: DraggableEventHandler, onMouseDown: (e: MouseEvent) => void } ``` From 549669e2f0eed35c1ecfff60666c03dce2fd34b4 Mon Sep 17 00:00:00 2001 From: Andrew Patton Date: Mon, 18 Jul 2016 13:26:59 -0700 Subject: [PATCH 2/3] :white_check_mark: Fix propType tests latest React React 15.2.0 changed propType validation warning text: https://github.com/facebook/react/blob/master/CHANGELOG.md#1520-july-1-2 016 --- specs/draggable.spec.jsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/specs/draggable.spec.jsx b/specs/draggable.spec.jsx index 7ef79b8b..a0b68a7b 100644 --- a/specs/draggable.spec.jsx +++ b/specs/draggable.spec.jsx @@ -122,7 +122,11 @@ describe('react-draggable', function () { TestUtils.renderIntoDocument(drag); - expect(console.error).toHaveBeenCalledWith('Warning: Failed propType: Invalid prop className passed to Draggable - do not set this, set it on the child.'); + expect( + console.error.calls.argsFor(0)[0].replace('propType:', 'prop type:').split('\n')[0] + ).toBe( + 'Warning: Failed prop type: Invalid prop className passed to Draggable - do not set this, set it on the child.' + ); }); it('should throw when setting style', function () { @@ -130,7 +134,11 @@ describe('react-draggable', function () { TestUtils.renderIntoDocument(drag); - expect(console.error).toHaveBeenCalledWith('Warning: Failed propType: Invalid prop style passed to Draggable - do not set this, set it on the child.'); + expect( + console.error.calls.argsFor(0)[0].replace('propType:', 'prop type:').split('\n')[0] + ).toBe( + 'Warning: Failed prop type: Invalid prop style passed to Draggable - do not set this, set it on the child.' + ); }); it('should throw when setting transform', function () { @@ -138,7 +146,11 @@ describe('react-draggable', function () { TestUtils.renderIntoDocument(drag); - expect(console.error).toHaveBeenCalledWith('Warning: Failed propType: Invalid prop transform passed to Draggable - do not set this, set it on the child.'); + expect( + console.error.calls.argsFor(0)[0].replace('propType:', 'prop type:').split('\n')[0] + ).toBe( + 'Warning: Failed prop type: Invalid prop transform passed to Draggable - do not set this, set it on the child.' + ); }); it('should call onStart when dragging begins', function () { From 2f1ffdbcde2b7018577313a052d13fe9339bc984 Mon Sep 17 00:00:00 2001 From: Andrew Patton Date: Mon, 18 Jul 2016 13:36:31 -0700 Subject: [PATCH 3/3] Use window/document relative to DOM element Use the ownerDocument and window of the DOM element being manipulated rather than the global window and document objects. This makes react-draggable work with a tool like https://github.com/ryanseddon/react-frame-component --- lib/DraggableCore.es6 | 25 ++++++++++++++----------- lib/utils/domFns.es6 | 12 ++++++------ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/DraggableCore.es6 b/lib/DraggableCore.es6 index 3c4d9b43..b1d6b1e8 100644 --- a/lib/DraggableCore.es6 +++ b/lib/DraggableCore.es6 @@ -171,10 +171,11 @@ export default class DraggableCore extends React.Component { componentWillUnmount() { // Remove any leftover event handlers. Remove both touch and mouse handlers in case // some browser quirk caused a touch event to fire during a mouse move, or vice versa. - removeEvent(document, eventsFor.mouse.move, this.handleDrag); - removeEvent(document, eventsFor.touch.move, this.handleDrag); - removeEvent(document, eventsFor.mouse.stop, this.handleDragStop); - removeEvent(document, eventsFor.touch.stop, this.handleDragStop); + const {ownerDocument} = ReactDOM.findDOMNode(this); + removeEvent(ownerDocument, eventsFor.mouse.move, this.handleDrag); + removeEvent(ownerDocument, eventsFor.touch.move, this.handleDrag); + removeEvent(ownerDocument, eventsFor.mouse.stop, this.handleDragStop); + removeEvent(ownerDocument, eventsFor.touch.stop, this.handleDragStop); if (this.props.enableUserSelectHack) removeUserSelectStyles(); } @@ -185,11 +186,12 @@ export default class DraggableCore extends React.Component { // Only accept left-clicks. if (!this.props.allowAnyClick && typeof e.button === 'number' && e.button !== 0) return false; + const domNode = ReactDOM.findDOMNode(this); // Short circuit if handle or cancel prop was provided and selector doesn't match. if (this.props.disabled || - (!(e.target instanceof Node)) || - (this.props.handle && !matchesSelectorAndParentsTo(e.target, this.props.handle, ReactDOM.findDOMNode(this))) || - (this.props.cancel && matchesSelectorAndParentsTo(e.target, this.props.cancel, ReactDOM.findDOMNode(this)))) { + (!(e.target instanceof domNode.ownerDocument.defaultView.Node)) || + (this.props.handle && !matchesSelectorAndParentsTo(e.target, this.props.handle, domNode)) || + (this.props.cancel && matchesSelectorAndParentsTo(e.target, this.props.cancel, domNode))) { return; } @@ -231,8 +233,8 @@ export default class DraggableCore extends React.Component { // Add events to the document directly so we catch when the user's mouse/touch moves outside of // this element. We use different events depending on whether or not we have detected that this // is a touch-capable device. - addEvent(document, dragEventFor.move, this.handleDrag); - addEvent(document, dragEventFor.stop, this.handleDragStop); + addEvent(domNode.ownerDocument, dragEventFor.move, this.handleDrag); + addEvent(domNode.ownerDocument, dragEventFor.stop, this.handleDragStop); }; handleDrag: EventHandler = (e) => { @@ -302,9 +304,10 @@ export default class DraggableCore extends React.Component { this.props.onStop(e, coreEvent); // Remove event handlers + const {ownerDocument} = ReactDOM.findDOMNode(this); log('DraggableCore: Removing handlers'); - removeEvent(document, dragEventFor.move, this.handleDrag); - removeEvent(document, dragEventFor.stop, this.handleDragStop); + removeEvent(ownerDocument, dragEventFor.move, this.handleDrag); + removeEvent(ownerDocument, dragEventFor.stop, this.handleDragStop); }; onMouseDown: EventHandler = (e) => { diff --git a/lib/utils/domFns.es6 b/lib/utils/domFns.es6 index 9afa67a5..41fc1e6e 100644 --- a/lib/utils/domFns.es6 +++ b/lib/utils/domFns.es6 @@ -63,7 +63,7 @@ export function outerHeight(node: HTMLElement): number { // This is deliberately excluding margin for our calculations, since we are using // offsetTop which is including margin. See getBoundPosition let height = node.clientHeight; - const computedStyle = window.getComputedStyle(node); + const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); height += int(computedStyle.borderTopWidth); height += int(computedStyle.borderBottomWidth); return height; @@ -73,14 +73,14 @@ export function outerWidth(node: HTMLElement): number { // This is deliberately excluding margin for our calculations, since we are using // offsetLeft which is including margin. See getBoundPosition let width = node.clientWidth; - const computedStyle = window.getComputedStyle(node); + 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; - const computedStyle = window.getComputedStyle(node); + const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); height -= int(computedStyle.paddingTop); height -= int(computedStyle.paddingBottom); return height; @@ -88,7 +88,7 @@ export function innerHeight(node: HTMLElement): number { export function innerWidth(node: HTMLElement): number { let width = node.clientWidth; - const computedStyle = window.getComputedStyle(node); + const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); width -= int(computedStyle.paddingLeft); width -= int(computedStyle.paddingRight); return width; @@ -96,8 +96,8 @@ export function innerWidth(node: HTMLElement): number { // Get from offsetParent export function offsetXYFromParentOf(evt: {clientX: number, clientY: number}, node: HTMLElement & {offsetParent: HTMLElement}): ControlPosition { - const offsetParent = node.offsetParent || document.body; - const offsetParentRect = node.offsetParent === document.body ? {left: 0, top: 0} : offsetParent.getBoundingClientRect(); + const offsetParent = node.offsetParent || node.ownerDocument.body; + const offsetParentRect = node.offsetParent === node.ownerDocument.body ? {left: 0, top: 0} : offsetParent.getBoundingClientRect(); const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left; const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;