@samitouri / QOS-React / commits / 4687a03f54

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;