From 1f1dba92a85c71c8a418d7220f26217e953ce369 Mon Sep 17 00:00:00 2001 From: Jim Date: Thu, 7 Apr 2016 14:11:12 -0700 Subject: [PATCH] Merge pull request #6364 from p-jackson/issue-5700 Don't wrap drag events in IE/Edge in dev builds (cherry picked from commit 2e8f28c29fd366d83cdbfc00e2b2dcb526e25202) --- 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;