Skip to content

Commit

Permalink
Drop Zone: Detect node removal when mutations occur
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Dec 7, 2015
1 parent 03f60cd commit 85fff41
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
36 changes: 36 additions & 0 deletions client/components/drop-zone/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,47 @@ module.exports = React.createClass( {
window.addEventListener( 'dragleave', this.toggleDraggingOverDocument );
},

componentDidUpdate: function( prevProps, prevState ) {
if ( prevState.isDraggingOverDocument !== this.state.isDraggingOverDocument ) {
this.toggleMutationObserver();
}
},

componentWillUnmount: function() {
window.removeEventListener( 'dragover', this.preventDefault );
window.removeEventListener( 'drop', this.onDrop );
window.removeEventListener( 'dragenter', this.toggleDraggingOverDocument );
window.removeEventListener( 'dragleave', this.toggleDraggingOverDocument );
this.disconnectMutationObserver();
},

toggleMutationObserver: function() {
this.disconnectMutationObserver();

if ( this.state.isDraggingOverDocument ) {
this.observer = new window.MutationObserver( this.detectNodeRemoval );
this.observer.observe( document.body, {
childList: true,
subtree: true
} );
}
},

disconnectMutationObserver: function() {
if ( ! this.observer ) {
return;
}

this.observer.disconnect();
delete this.observer;
},

detectNodeRemoval: function( record ) {
if ( ! record.removedNodes ) {
return;
}

this.dragEnterNodes = without( this.dragEnterNodes, Array.from( record.removedNodes ) );
},

toggleDraggingOverDocument: function( event ) {
Expand Down
35 changes: 35 additions & 0 deletions client/components/drop-zone/test/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ describe( 'DropZone', function() {
before( function() {
DropZone.type.prototype.__reactAutoBindMap.translate = sinon.stub().returnsArg( 0 );
container = document.getElementById( 'container' );
window.MutationObserver = sinon.stub().returns( {
observe: sinon.stub(),
disconnect: sinon.stub()
} );
} );

after( function() {
delete window.MutationObserver;
delete DropZone.type.prototype.__reactAutoBindMap.translate;
} );

Expand Down Expand Up @@ -87,6 +92,36 @@ describe( 'DropZone', function() {
expect( tree.state.isDraggingOverElement ).to.not.be.ok;
} );

it( 'should start observing the body for mutations when dragging over', function( done ) {
var tree = React.render( React.createElement( DropZone ), container ),
dragEnterEvent = new window.MouseEvent();

dragEnterEvent.initMouseEvent( 'dragenter', true, true );
window.dispatchEvent( dragEnterEvent );

process.nextTick( function() {
expect( tree.observer ).to.be.ok;
done();
} );
} );

it( 'should stop observing the body for mutations upon drag ending', function( done ) {
var tree = React.render( React.createElement( DropZone ), container ),
dragEnterEvent = new window.MouseEvent(),
dragLeaveEvent = new window.MouseEvent();

dragEnterEvent.initMouseEvent( 'dragenter', true, true );
window.dispatchEvent( dragEnterEvent );

dragLeaveEvent.initMouseEvent( 'dragleave', true, true );
window.dispatchEvent( dragLeaveEvent );

process.nextTick( function() {
expect( tree.observer ).to.be.undefined;
done();
} );
} );

it( 'should not highlight if onVerifyValidTransfer returns false', function() {
var dragEnterEvent = new window.MouseEvent(),
tree;
Expand Down

0 comments on commit 85fff41

Please sign in to comment.