From 4687a03f5498f119430e5e9b5dfe23f409ae004b Mon Sep 17 00:00:00 2001 From: Philip Jackson Date: Mon, 28 Mar 2016 00:29:46 +1300 Subject: [PATCH] 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. --- src/shared/utils/ReactErrorUtils.js | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/shared/utils/ReactErrorUtils.js b/src/shared/utils/ReactErrorUtils.js index cff46bc15e..2746220920 100644 --- a/src/shared/utils/ReactErrorUtils.js +++ b/src/shared/utils/ReactErrorUtils.js @@ -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;