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.
Philip Jackson committed
Mar 28, 2016 at 00:29 UTC
4687a03f5498f119430e5e9b5dfe23f409ae004b
1 file changed
+42
src/shared/utils/ReactErrorUtils.js
+42
@@ -11,6 +11,8 @@
11
12
'use strict';
13
14
+var SyntheticDragEvent = require('SyntheticDragEvent');
15
+
16
var caughtError = null;
17
18
/**
@@ -65,6 +67,11 @@ if (__DEV__) {
67
typeof document.createEvent === 'function') {
68
var fakeNode = document.createElement('react');
69
ReactErrorUtils.invokeGuardedCallback = function(name, func, a, b) {
70
+ if (!canWrapEvent(a)) {
71
+ invokeGuardedCallback(name, func, a, b);
72
+ return;
73
+ }
74
+
75
var boundFunc = func.bind(null, a, b);
76
var evtType = `react-${name}`;
77
fakeNode.addEventListener(evtType, boundFunc, false);
@@ -74,6 +81,41 @@ if (__DEV__) {
81
fakeNode.removeEventListener(evtType, boundFunc, false);
82
};
83
}
84
+
85
+ var cacheCanWrapEvent = null;
86
+
87
+ /**
88
+ * IE and Edge don't allow access to the DataTransfer.dropEffect property when
89
+ * it's wrapped in another event. This function detects whether we're in an
90
+ * environment that behaves this way.
91
+ *
92
+ * @param {*} ev Event that is being tested
93
+ */
94
+ function canWrapEvent(ev) {
95
+ if (!(ev instanceof SyntheticDragEvent)) {
96
+ return true;
97
+ } else if (cacheCanWrapEvent !== null) {
98
+ return cacheCanWrapEvent;
99
+ }
100
+
101
+ var canAccessDropEffect = false;
102
+ function handleWrappedEvent() {
103
+ try {
104
+ ev.dataTransfer.dropEffect; // eslint-disable-line no-unused-expressions
105
+ canAccessDropEffect = true;
106
+ } catch (e) {}
107
+ }
108
+
109
+ var wrappedEventName = 'react-wrappeddragevent';
110
+ var wrappedEvent = document.createEvent('Event');
111
+ wrappedEvent.initEvent(wrappedEventName, false, false);
112
+ fakeNode.addEventListener(wrappedEventName, handleWrappedEvent, false);
113
+ fakeNode.dispatchEvent(wrappedEvent);
114
+ fakeNode.removeEventListener(wrappedEventName, handleWrappedEvent, false);
115
+
116
+ cacheCanWrapEvent = canAccessDropEffect;
117
+ return canAccessDropEffect;
118
+ }
119
}
120
121
module.exports = ReactErrorUtils;