Don't wrap drag events in IE/Edge in dev builds

Dev builds wrap synthetic events inside other events for a better debug
experience. However IE/Edge won't allow access to the
DataTransfer.dropEffect property if it's wrapped in this way.
The first time a drag event is fired, test if we're in an environment
that behaves this way and disable React's improved development
experience if we are.
This commit is contained in:
Philip Jackson 2016-03-28 00:29:46 +13:00
parent a2780212ae
commit 4687a03f54
1 changed files with 42 additions and 0 deletions

View File

@ -11,6 +11,8 @@
'use strict';
var SyntheticDragEvent = require('SyntheticDragEvent');
var caughtError = null;
/**
@ -65,6 +67,11 @@ if (__DEV__) {
typeof document.createEvent === 'function') {
var fakeNode = document.createElement('react');
ReactErrorUtils.invokeGuardedCallback = function(name, func, a, b) {
if (!canWrapEvent(a)) {
invokeGuardedCallback(name, func, a, b);
return;
}
var boundFunc = func.bind(null, a, b);
var evtType = `react-${name}`;
fakeNode.addEventListener(evtType, boundFunc, false);
@ -74,6 +81,41 @@ if (__DEV__) {
fakeNode.removeEventListener(evtType, boundFunc, false);
};
}
var cacheCanWrapEvent = null;
/**
* IE and Edge don't allow access to the DataTransfer.dropEffect property when
* it's wrapped in another event. This function detects whether we're in an
* environment that behaves this way.
*
* @param {*} ev Event that is being tested
*/
function canWrapEvent(ev) {
if (!(ev instanceof SyntheticDragEvent)) {
return true;
} else if (cacheCanWrapEvent !== null) {
return cacheCanWrapEvent;
}
var canAccessDropEffect = false;
function handleWrappedEvent() {
try {
ev.dataTransfer.dropEffect; // eslint-disable-line no-unused-expressions
canAccessDropEffect = true;
} catch (e) {}
}
var wrappedEventName = 'react-wrappeddragevent';
var wrappedEvent = document.createEvent('Event');
wrappedEvent.initEvent(wrappedEventName, false, false);
fakeNode.addEventListener(wrappedEventName, handleWrappedEvent, false);
fakeNode.dispatchEvent(wrappedEvent);
fakeNode.removeEventListener(wrappedEventName, handleWrappedEvent, false);
cacheCanWrapEvent = canAccessDropEffect;
return canAccessDropEffect;
}
}
module.exports = ReactErrorUtils;