Ability to access window.event in development (#11687) (#11696)
Before this change in development window.event was overridden in invokeGuardedCallback. After this change window.event is preserved in the browsers that support it.
Conrad Irwin committed
Aug 14, 2018 at 13:35 UTC
69e2a0d732e1ca74f6dc5df9d0ddd0bf24373965
2 files changed
+70
fixtures/dom/src/components/fixtures/error-handling/index.js
+53
@@ -152,6 +152,44 @@ class SilenceErrors extends React.Component {
152
);
153
}
154
}
155
+class GetEventTypeDuringUpdate extends React.Component {
156
+ state = {};
157
+
158
+ onClick = () => {
159
+ this.expectUpdate = true;
160
+ this.forceUpdate();
161
+ };
162
+
163
+ componentDidUpdate() {
164
+ if (this.expectUpdate) {
165
+ this.expectUpdate = false;
166
+ this.setState({eventType: window.event.type});
167
+ setTimeout(() => {
168
+ this.setState({cleared: !window.event});
169
+ });
170
+ }
171
+ }
172
+
173
+ render() {
174
+ return (
175
+ <div className="test-fixture">
176
+ <button onClick={this.onClick}>Trigger callback in event.</button>
177
+ {this.state.eventType ? (
178
+ <p>
179
+ Got <b>{this.state.eventType}</b> event.
180
+ </p>
181
+ ) : (
182
+ <p>Got no event</p>
183
+ )}
184
+ {this.state.cleared ? (
185
+ <p>Event cleared correctly.</p>
186
+ ) : (
187
+ <p>Event failed to clear.</p>
188
+ )}
189
+ </div>
190
+ );
191
+ }
192
+}
193
194
class SilenceRecoverableError extends React.Component {
195
render() {
@@ -318,6 +356,21 @@ export default class ErrorHandlingTestCases extends React.Component {
356
</TestCase.ExpectedResult>
357
<TrySilenceFatalError />
358
</TestCase>
359
+
360
+ {window.hasOwnProperty('event') ? (
361
+ <TestCase
362
+ title="Error handling does not interfere with window.event"
363
+ description="">
364
+ <TestCase.Steps>
365
+ <li>Click the "Trigger callback in event" button</li>
366
+ </TestCase.Steps>
367
+ <TestCase.ExpectedResult>
368
+ You should see "Got <b>click</b> event" and "Event cleared
369
+ successfully" below.
370
+ </TestCase.ExpectedResult>
371
+ <GetEventTypeDuringUpdate />
372
+ </TestCase>
373
+ ) : null}
374
</FixtureSet>
375
);
376
}
packages/shared/invokeGuardedCallback.js
+17
@@ -96,6 +96,11 @@ if (__DEV__) {
96
// the error event at all.
97
let didError = true;
98
99
+ // Keeps track of the value of window.event so that we can reset it
100
+ // during the callback to let user code access window.event in the
101
+ // browsers that support it.
102
+ let windowEvent = window.event;
103
+
104
// Create an event handler for our fake event. We will synchronously
105
// dispatch our fake event using `dispatchEvent`. Inside the handler, we
106
// call the user-provided callback.
@@ -106,6 +111,18 @@ if (__DEV__) {
111
// nested call would trigger the fake event handlers of any call higher
112
// in the stack.
113
fakeNode.removeEventListener(evtType, callCallback, false);
114
+
115
+ // We check for window.hasOwnProperty('event') to prevent the
116
+ // window.event assignment in both IE <= 10 as they throw an error
117
+ // "Member not found" in strict mode, and in Firefox which does not
118
+ // support window.event.
119
+ if (
120
+ typeof window.event !== 'undefined' &&
121
+ window.hasOwnProperty('event')
122
+ ) {
123
+ window.event = windowEvent;
124
+ }
125
+
126
func.apply(context, funcArgs);
127
didError = false;
128
}