From 1a710d343782072fd29069f909044fbd7edf31a9 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Tue, 28 Nov 2017 14:16:01 -0800 Subject: [PATCH] Ability to access window.event in development (#11687) Before this change in development window.event was overridden in invokeGuardedCallback. After this change window.event is preserved in the browsers that support it. --- .../fixtures/error-handling/index.js | 53 +++++++++++++++++++ packages/shared/invokeGuardedCallback.js | 17 ++++++ 2 files changed, 70 insertions(+) diff --git a/fixtures/dom/src/components/fixtures/error-handling/index.js b/fixtures/dom/src/components/fixtures/error-handling/index.js index 8dcb8e1dc5e0a..7fb9941a73f0f 100644 --- a/fixtures/dom/src/components/fixtures/error-handling/index.js +++ b/fixtures/dom/src/components/fixtures/error-handling/index.js @@ -152,6 +152,44 @@ class SilenceErrors extends React.Component { ); } } +class GetEventTypeDuringUpdate extends React.Component { + state = {}; + + onClick = () => { + this.expectUpdate = true; + this.forceUpdate(); + }; + + componentDidUpdate() { + if (this.expectUpdate) { + this.expectUpdate = false; + this.setState({eventType: window.event.type}); + setTimeout(() => { + this.setState({cleared: !window.event}); + }); + } + } + + render() { + return ( +
+ + {this.state.eventType ? ( +

+ Got {this.state.eventType} event. +

+ ) : ( +

Got no event

+ )} + {this.state.cleared ? ( +

Event cleared correctly.

+ ) : ( +

Event failed to clear.

+ )} +
+ ); + } +} class SilenceRecoverableError extends React.Component { render() { @@ -318,6 +356,21 @@ export default class ErrorHandlingTestCases extends React.Component { + + {window.hasOwnProperty('event') ? ( + + +
  • Click the "Trigger callback in event" button
  • +
    + + You should see "Got click event" and "Event cleared + successfully" below. + + +
    + ) : null} ); } diff --git a/packages/shared/invokeGuardedCallback.js b/packages/shared/invokeGuardedCallback.js index c0cce27cc4f1d..647516ee86bc6 100644 --- a/packages/shared/invokeGuardedCallback.js +++ b/packages/shared/invokeGuardedCallback.js @@ -96,6 +96,11 @@ if (__DEV__) { // the error event at all. let didError = true; + // Keeps track of the value of window.event so that we can reset it + // during the callback to let user code access window.event in the + // browsers that support it. + let windowEvent = window.event; + // Create an event handler for our fake event. We will synchronously // dispatch our fake event using `dispatchEvent`. Inside the handler, we // call the user-provided callback. @@ -106,6 +111,18 @@ if (__DEV__) { // nested call would trigger the fake event handlers of any call higher // in the stack. fakeNode.removeEventListener(evtType, callCallback, false); + + // We check for window.hasOwnProperty('event') to prevent the + // window.event assignment in both IE <= 10 as they throw an error + // "Member not found" in strict mode, and in Firefox which does not + // support window.event. + if ( + typeof window.event !== 'undefined' && + window.hasOwnProperty('event') + ) { + window.event = windowEvent; + } + func.apply(context, funcArgs); didError = false; }