From c8897f8382f10ac390f8f7f4f15c8ffaeccb6a8c Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Thu, 23 Mar 2017 08:16:52 -0700 Subject: [PATCH 1/4] Updated ReactNative findNodeHandle() to handle number case (#9238) --- src/renderers/native/ReactNativeFiber.js | 5 ++++- src/renderers/native/ReactNativeStack.js | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/renderers/native/ReactNativeFiber.js b/src/renderers/native/ReactNativeFiber.js index 783ae91397..014b4dfa85 100644 --- a/src/renderers/native/ReactNativeFiber.js +++ b/src/renderers/native/ReactNativeFiber.js @@ -382,7 +382,10 @@ const ReactNative = { // See NativeMethodsMixin#setNativeProps for more info on why this is done. findNodeHandle(componentOrHandle: any): ?number { const instance: any = findNodeHandle(componentOrHandle); - return instance ? instance._nativeTag : null; + if (instance == null || typeof instance === 'number') { + return instance; + } + return instance._nativeTag; }, render(element: Element, containerTag: any, callback: ?Function) { diff --git a/src/renderers/native/ReactNativeStack.js b/src/renderers/native/ReactNativeStack.js index 37d8b89f56..2a5b8f509b 100644 --- a/src/renderers/native/ReactNativeStack.js +++ b/src/renderers/native/ReactNativeStack.js @@ -37,7 +37,11 @@ var ReactNative = { // The injected findNodeHandle() strategy returns the instance wrapper though. // See NativeMethodsMixin#setNativeProps for more info on why this is done. findNodeHandle(componentOrHandle: any): ?number { - return findNodeHandle(componentOrHandle).getHostNode(); + const nodeHandle = findNodeHandle(componentOrHandle); + if (nodeHandle == null || typeof nodeHandle === 'number') { + return nodeHandle; + } + return nodeHandle.getHostNode(); }, render: render, From 1c9dcd53d5a5e194afc0d953a3341ad32fe311dc Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 23 Mar 2017 18:45:38 +0000 Subject: [PATCH 2/4] Add dynamic injection to ReactErrorUtils (#9246) --- src/renderers/shared/utils/ReactErrorUtils.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/renderers/shared/utils/ReactErrorUtils.js b/src/renderers/shared/utils/ReactErrorUtils.js index b3910a0dd8..b57db95527 100644 --- a/src/renderers/shared/utils/ReactErrorUtils.js +++ b/src/renderers/shared/utils/ReactErrorUtils.js @@ -12,6 +12,8 @@ 'use strict'; +const invariant = require('invariant'); + let caughtError = null; /** @@ -24,6 +26,21 @@ let caughtError = null; * @param {...*} args Arguments for function */ const ReactErrorUtils = { + injection: { + injectErrorUtils(injectedErrorUtils: Object) { + invariant( + typeof injectedErrorUtils.invokeGuardedCallback === 'function', + 'Injected invokeGuardedCallback() must be a function.', + ); + invariant( + typeof injectedErrorUtils.rethrowCaughtError === 'function', + 'Injected rethrowCaughtError() must be a function.', + ); + ReactErrorUtils.invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback; + ReactErrorUtils.rethrowCaughtError = injectedErrorUtils.rethrowCaughtError; + }, + }, + invokeGuardedCallback: function( name: string | null, func: (a: A, b: B, c: C, d: D, e: E, f: F) => void, From d6a2c669d22e0bf0bc839493b863673df09c99c9 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 23 Mar 2017 19:13:07 +0000 Subject: [PATCH 3/4] Fix ReactErrorUtils injection (#9247) --- src/renderers/shared/utils/ReactErrorUtils.js | 130 +++++++++--------- 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/src/renderers/shared/utils/ReactErrorUtils.js b/src/renderers/shared/utils/ReactErrorUtils.js index b57db95527..fe3017bbc9 100644 --- a/src/renderers/shared/utils/ReactErrorUtils.js +++ b/src/renderers/shared/utils/ReactErrorUtils.js @@ -16,6 +16,66 @@ const invariant = require('invariant'); let caughtError = null; +let invokeGuardedCallback = function(name, func, context, a, b, c, d, e, f) { + const funcArgs = Array.prototype.slice.call(arguments, 3); + try { + func.apply(context, funcArgs); + } catch (error) { + return error; + } + return null; +}; + +if (__DEV__) { + /** + * To help development we can get better devtools integration by simulating a + * real browser event. + */ + if ( + typeof window !== 'undefined' && + typeof window.dispatchEvent === 'function' && + typeof document !== 'undefined' && + typeof document.createEvent === 'function' + ) { + const fakeNode = document.createElement('react'); + let depth = 0; + + invokeGuardedCallback = function(name, func, context, a, b, c, d, e, f) { + depth++; + const thisDepth = depth; + const funcArgs = Array.prototype.slice.call(arguments, 3); + const boundFunc = function() { + func.apply(context, funcArgs); + }; + let fakeEventError = null; + const onFakeEventError = function(event) { + // Don't capture nested errors + if (depth === thisDepth) { + fakeEventError = event.error; + } + }; + const evtType = `react-${name ? name : 'invokeguardedcallback'}-${depth}`; + window.addEventListener('error', onFakeEventError); + fakeNode.addEventListener(evtType, boundFunc, false); + const evt = document.createEvent('Event'); + evt.initEvent(evtType, false, false); + fakeNode.dispatchEvent(evt); + fakeNode.removeEventListener(evtType, boundFunc, false); + window.removeEventListener('error', onFakeEventError); + depth--; + return fakeEventError; + }; + } +} + +let rethrowCaughtError = function() { + if (caughtError) { + const error = caughtError; + caughtError = null; + throw error; + } +}; + /** * Call a function while guarding against errors that happens within it. * Returns an error if it throws, otherwise null. @@ -36,8 +96,8 @@ const ReactErrorUtils = { typeof injectedErrorUtils.rethrowCaughtError === 'function', 'Injected rethrowCaughtError() must be a function.', ); - ReactErrorUtils.invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback; - ReactErrorUtils.rethrowCaughtError = injectedErrorUtils.rethrowCaughtError; + invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback; + rethrowCaughtError = injectedErrorUtils.rethrowCaughtError; }, }, @@ -52,13 +112,7 @@ const ReactErrorUtils = { e: E, f: F, ): Error | null { - const funcArgs = Array.prototype.slice.call(arguments, 3); - try { - func.apply(context, funcArgs); - } catch (error) { - return error; - } - return null; + return invokeGuardedCallback.apply(this, arguments); }, /** @@ -92,64 +146,8 @@ const ReactErrorUtils = { * we will rethrow to be handled by the top level error handler. */ rethrowCaughtError: function() { - if (caughtError) { - const error = caughtError; - caughtError = null; - throw error; - } + return rethrowCaughtError.apply(this, arguments); }, }; -if (__DEV__) { - /** - * To help development we can get better devtools integration by simulating a - * real browser event. - */ - if ( - typeof window !== 'undefined' && - typeof window.dispatchEvent === 'function' && - typeof document !== 'undefined' && - typeof document.createEvent === 'function' - ) { - const fakeNode = document.createElement('react'); - let depth = 0; - - ReactErrorUtils.invokeGuardedCallback = function( - name, - func, - context, - a, - b, - c, - d, - e, - f, - ) { - depth++; - const thisDepth = depth; - const funcArgs = Array.prototype.slice.call(arguments, 3); - const boundFunc = function() { - func.apply(context, funcArgs); - }; - let fakeEventError = null; - const onFakeEventError = function(event) { - // Don't capture nested errors - if (depth === thisDepth) { - fakeEventError = event.error; - } - }; - const evtType = `react-${name ? name : 'invokeguardedcallback'}-${depth}`; - window.addEventListener('error', onFakeEventError); - fakeNode.addEventListener(evtType, boundFunc, false); - const evt = document.createEvent('Event'); - evt.initEvent(evtType, false, false); - fakeNode.dispatchEvent(evt); - fakeNode.removeEventListener(evtType, boundFunc, false); - window.removeEventListener('error', onFakeEventError); - depth--; - return fakeEventError; - }; - } -} - module.exports = ReactErrorUtils; From f082e35b36ece6bf301051296380aa15897d7431 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 23 Mar 2017 19:45:10 +0000 Subject: [PATCH 4/4] Fix up invariant import to be from fbjs/lib/ --- src/renderers/shared/utils/ReactErrorUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/shared/utils/ReactErrorUtils.js b/src/renderers/shared/utils/ReactErrorUtils.js index fe3017bbc9..71ed3063cd 100644 --- a/src/renderers/shared/utils/ReactErrorUtils.js +++ b/src/renderers/shared/utils/ReactErrorUtils.js @@ -12,7 +12,7 @@ 'use strict'; -const invariant = require('invariant'); +const invariant = require('fbjs/lib/invariant'); let caughtError = null;