While the files property is not accessible on event.dataTransfer during drag events event, the items property is. This lets us respond to native drag data much earlier stage.
monkey patch 🙉
import HTML5Backend from 'react-dnd-html5-backend/lib/HTML5Backend';
import {isFirefox} from 'react-dnd-html5-backend/lib/BrowserDetector';
import {createNativeDragSource, matchNativeItemType}
from 'react-dnd-html5-backend/lib/NativeDragSources';
HTML5Backend.prototype.updateCurrentNativeSourceItem = function(dataTransfer) {
const items = Array.prototype.slice.call(dataTransfer.items || []);
this.currentNativeSource.item.items = items;
};
// Wrapped methods:
const {handleTopDrop} = HTML5Backend.prototype;
HTML5Backend.prototype.handleTopDrop = function(e) {
if (this.isDraggingNativeItem()) {
this.updateCurrentNativeSourceItem(e.dataTransfer);
}
return handleTopDrop.call(this, e);
};
const {handleTopDragEnter} = HTML5Backend.prototype;
HTML5Backend.prototype.handleTopDragEnter = function(e) {
if (this.isDraggingNativeItem()) {
this.updateCurrentNativeSourceItem(e.dataTransfer);
}
return handleTopDragEnter.call(this, e);
};
const {handleTopDragOver} = HTML5Backend.prototype;
HTML5Backend.prototype.handleTopDragOver = function(e) {
if (this.isDraggingNativeItem()) {
this.updateCurrentNativeSourceItem(e.dataTransfer);
}
return handleTopDragOver.call(this, e);
};
// Patched methods:
HTML5Backend.prototype.handleTopDragEnterCapture = function(e) {
this.dragEnterTargetIds = [];
const isFirstEnter = this.enterLeaveCounter.enter(e.target);
if (!isFirstEnter || this.monitor.isDragging()) {
return;
}
const {dataTransfer} = e;
const nativeType = matchNativeItemType(dataTransfer);
if (nativeType) {
this.beginDragNativeItem(nativeType/* PATCH */, dataTransfer/* END PATCH */);
}
};
HTML5Backend.prototype.beginDragNativeItem = function(type, dataTransfer) {
this.clearCurrentDragSourceNode();
const SourceType = createNativeDragSource(type);
this.currentNativeSource = new SourceType();
/* PATCH */
this.updateCurrentNativeSourceItem(dataTransfer);
/* END PATCH*/
this.currentNativeHandle = this.registry.addSource(type, this.currentNativeSource);
this.actions.beginDrag([this.currentNativeHandle]);
// On Firefox, if mousemove fires, the drag is over but browser failed to tell us.
// This is not true for other browsers.
if (isFirefox()) {
window.addEventListener('mousemove', this.endDragNativeItem, true);
}
};
The
DataTransferItems
interface is the successor to theFilesList
interface ofDataTransfer
objects. It's only currently supported by Chrome.https://www.w3.org/TR/html51/editing.html#the-datatransfer-interface https://www.w3.org/TR/html51/editing.html#the-datatransferitemlist-interface
While the
files
property is not accessible onevent.dataTransfer
during drag events event, theitems
property is. This lets us respond to native drag data much earlier stage.monkey patch 🙉