From d568f13ffb6208fd8c818096a9c5c00a18bb42dd Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Thu, 5 Mar 2020 21:34:06 +0000 Subject: [PATCH 01/11] Add getInspectorDataForViewAtPoint --- .../react-native-renderer/src/ReactFabric.js | 5 +- .../src/ReactNativeFiberHostComponent.js | 8 +- .../src/ReactNativeFiberInspector.js | 106 +++++++++++++++++- .../src/ReactNativeHostConfig.js | 6 +- .../src/ReactNativeRenderer.js | 3 +- 5 files changed, 122 insertions(+), 6 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index 54da153f84024..88057a63950ba 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -34,7 +34,7 @@ import ReactVersion from 'shared/ReactVersion'; import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import {getClosestInstanceFromNode} from './ReactFabricComponentTree'; -import {getInspectorDataForViewTag} from './ReactNativeFiberInspector'; +import {getInspectorDataForViewAtPoint, getInspectorDataForViewTag} from './ReactNativeFiberInspector'; import {LegacyRoot} from 'shared/ReactRootTags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; @@ -233,7 +233,8 @@ export { injectIntoDevTools({ findFiberByHostInstance: getClosestInstanceFromNode, getInspectorDataForViewTag: getInspectorDataForViewTag, - bundleType: __DEV__ ? 1 : 0, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind(null, findNodeHandle), + bundleType: __DEV__ ? 1 : 0, version: ReactVersion, rendererPackageName: 'react-native-renderer', }); diff --git a/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js b/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js index f695971f4db49..1bc9aabc16658 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js +++ b/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js @@ -34,11 +34,17 @@ class ReactNativeFiberHostComponent { _children: Array; _nativeTag: number; viewConfig: ReactNativeBaseComponentViewConfig<>; + _internalFiberInstanceHandle: Object; - constructor(tag: number, viewConfig: ReactNativeBaseComponentViewConfig<>) { + constructor( + tag: number, + viewConfig: ReactNativeBaseComponentViewConfig<>, + internalInstanceHandle: Object, + ) { this._nativeTag = tag; this._children = []; this.viewConfig = viewConfig; + this._internalFiberInstanceHandle = internalInstanceHandle; } blur() { diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index 5693a8edd892d..20c97d3aa1069 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -8,6 +8,7 @@ */ import type {Fiber} from 'react-reconciler/src/ReactFiber'; +import type {ReactFabricType, HostComponent as ReactNativeHostComponent} from './ReactNativeTypes'; import { findCurrentHostFiber, @@ -27,6 +28,7 @@ if (__DEV__) { } let getInspectorDataForViewTag; +let getInspectorDataForViewAtPoint; if (__DEV__) { const traverseOwnerTreeUp = function(hierarchy, instance: any) { @@ -89,6 +91,34 @@ if (__DEV__) { })); }; + const getInspectorDataForInstance = function(closestInstance, frame): Object { + // Handle case where user clicks outside of ReactNative + if (!closestInstance) { + return { + hierarchy: [], + props: emptyObject, + selection: null, + source: null, + }; + } + + const fiber = findCurrentFiberUsingSlowPath(closestInstance); + const fiberHierarchy = getOwnerHierarchy(fiber); + const instance = lastNonHostInstance(fiberHierarchy); + const hierarchy = createHierarchy(fiberHierarchy); + const props = getHostProps(instance); + const source = instance._debugSource; + const selection = fiberHierarchy.indexOf(instance); + + return { + hierarchy, + frame, + props, + selection, + source, + }; + } + getInspectorDataForViewTag = function(viewTag: number): Object { const closestInstance = getClosestInstanceFromNode(viewTag); @@ -117,6 +147,73 @@ if (__DEV__) { source, }; }; + + getInspectorDataForViewAtPoint = function( + findNodeHandle, + inspectedView: ?React.ElementRef>, + x: number, + y: number, + callback: (obj: Object) => mixed, + ): void { + let closestInstance = null; + let frame = { + left: 0, + top: 0, + width: 0, + height: 0, + } + + if (inspectedView._internalInstanceHandle != null) { + // fabric + nativeFabricUIManager.findNodeAtPoint( + inspectedView._internalInstanceHandle.stateNode.node, + x, + y, + shadowNode => { + if (shadowNode == null) { + callback(getInspectorDataForInstance(closestInstance, frame)); + } + + closestInstance = shadowNode.stateNode.canonical._internalInstanceHandle; + nativeFabricUIManager.measure( + shadowNode.stateNode.node, + (x, y, width, height, pageX, pageY) => { + frame = { + left: pageX, + top: pageY, + width, + height, + } + + callback(getInspectorDataForInstance(closestInstance, frame)); + }, + ); + }, + ); + } else if (inspectedView._internalFiberInstanceHandle != null) { + UIManager.findSubviewIn( + findNodeHandle(inspectedView), + [x, y], + (nativeViewTag, left, top, width, height) => { + frame = { + left, + top, + width, + height, + }; + var closestInstance = getClosestInstanceFromNode(nativeViewTag); // Handle case where user clicks outside of ReactNative + const inspectorData = getInspectorDataForInstance(closestInstance, frame); + callback({...inspectorData, nativeViewTag}); + }, + ); + } else if (__DEV__) { + console.error( + 'getInspectorDataForViewAtPoint expects to receieve a host component', + ); + + return; + } + }; } else { getInspectorDataForViewTag = () => { invariant( @@ -124,6 +221,13 @@ if (__DEV__) { 'getInspectorDataForViewTag() is not available in production', ); }; + + getInspectorDataForViewAtPoint = () => { + invariant( + false, + 'getInspectorDataForViewAtPoint() is not available in production', + ); + }; } -export {getInspectorDataForViewTag}; +export {getInspectorDataForViewAtPoint, getInspectorDataForViewTag}; diff --git a/packages/react-native-renderer/src/ReactNativeHostConfig.js b/packages/react-native-renderer/src/ReactNativeHostConfig.js index 0349591a99350..d50d0035cf903 100644 --- a/packages/react-native-renderer/src/ReactNativeHostConfig.js +++ b/packages/react-native-renderer/src/ReactNativeHostConfig.js @@ -108,7 +108,11 @@ export function createInstance( updatePayload, // props ); - const component = new ReactNativeFiberHostComponent(tag, viewConfig); + const component = new ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandle, + ); precacheFiberNode(internalInstanceHandle, tag); updateFiberProps(tag, props); diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index 9d156026eb28c..aa954ed570113 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -36,7 +36,7 @@ import ReactVersion from 'shared/ReactVersion'; import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import {getClosestInstanceFromNode} from './ReactNativeComponentTree'; -import {getInspectorDataForViewTag} from './ReactNativeFiberInspector'; +import {getInspectorDataForViewTag, getInspectorDataForViewAtPoint} from './ReactNativeFiberInspector'; import {LegacyRoot} from 'shared/ReactRootTags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; @@ -247,6 +247,7 @@ export { injectIntoDevTools({ findFiberByHostInstance: getClosestInstanceFromNode, getInspectorDataForViewTag: getInspectorDataForViewTag, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind(null, findNodeHandle), bundleType: __DEV__ ? 1 : 0, version: ReactVersion, rendererPackageName: 'react-native-renderer', From 1d7db7a10bc13013ece57525483e2648c1e44d4c Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Thu, 5 Mar 2020 22:06:18 +0000 Subject: [PATCH 02/11] Lint and add comments --- .../react-native-renderer/src/ReactFabric.js | 12 +++++-- .../src/ReactNativeFiberInspector.js | 33 +++++++++++-------- .../src/ReactNativeRenderer.js | 10 ++++-- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index 88057a63950ba..80475703e9e2d 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -34,7 +34,10 @@ import ReactVersion from 'shared/ReactVersion'; import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import {getClosestInstanceFromNode} from './ReactFabricComponentTree'; -import {getInspectorDataForViewAtPoint, getInspectorDataForViewTag} from './ReactNativeFiberInspector'; +import { + getInspectorDataForViewAtPoint, + getInspectorDataForViewTag, +} from './ReactNativeFiberInspector'; import {LegacyRoot} from 'shared/ReactRootTags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; @@ -233,8 +236,11 @@ export { injectIntoDevTools({ findFiberByHostInstance: getClosestInstanceFromNode, getInspectorDataForViewTag: getInspectorDataForViewTag, - getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind(null, findNodeHandle), - bundleType: __DEV__ ? 1 : 0, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( + null, + findNodeHandle, + ), + bundleType: __DEV__ ? 1 : 0, version: ReactVersion, rendererPackageName: 'react-native-renderer', }); diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index 20c97d3aa1069..f83dfc5bff23f 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -8,7 +8,10 @@ */ import type {Fiber} from 'react-reconciler/src/ReactFiber'; -import type {ReactFabricType, HostComponent as ReactNativeHostComponent} from './ReactNativeTypes'; +import type { + ReactFabricType, + HostComponent as ReactNativeHostComponent, +} from './ReactNativeTypes'; import { findCurrentHostFiber, @@ -117,7 +120,7 @@ if (__DEV__) { selection, source, }; - } + }; getInspectorDataForViewTag = function(viewTag: number): Object { const closestInstance = getClosestInstanceFromNode(viewTag); @@ -161,10 +164,10 @@ if (__DEV__) { top: 0, width: 0, height: 0, - } + }; if (inspectedView._internalInstanceHandle != null) { - // fabric + // For Fabric we can look up the instance handle directly and measure it. nativeFabricUIManager.findNodeAtPoint( inspectedView._internalInstanceHandle.stateNode.node, x, @@ -174,7 +177,8 @@ if (__DEV__) { callback(getInspectorDataForInstance(closestInstance, frame)); } - closestInstance = shadowNode.stateNode.canonical._internalInstanceHandle; + closestInstance = + shadowNode.stateNode.canonical._internalInstanceHandle; nativeFabricUIManager.measure( shadowNode.stateNode.node, (x, y, width, height, pageX, pageY) => { @@ -183,7 +187,7 @@ if (__DEV__) { top: pageY, width, height, - } + }; callback(getInspectorDataForInstance(closestInstance, frame)); }, @@ -191,18 +195,21 @@ if (__DEV__) { }, ); } else if (inspectedView._internalFiberInstanceHandle != null) { + // For Paper we fall back to the old strategy using the React tag. UIManager.findSubviewIn( findNodeHandle(inspectedView), [x, y], (nativeViewTag, left, top, width, height) => { frame = { - left, - top, - width, - height, - }; - var closestInstance = getClosestInstanceFromNode(nativeViewTag); // Handle case where user clicks outside of ReactNative - const inspectorData = getInspectorDataForInstance(closestInstance, frame); + left, + top, + width, + height, + }; + const inspectorData = getInspectorDataForInstance( + getClosestInstanceFromNode(nativeViewTag), + frame, + ); callback({...inspectorData, nativeViewTag}); }, ); diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index aa954ed570113..4fd4f4b611a9c 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -36,7 +36,10 @@ import ReactVersion from 'shared/ReactVersion'; import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import {getClosestInstanceFromNode} from './ReactNativeComponentTree'; -import {getInspectorDataForViewTag, getInspectorDataForViewAtPoint} from './ReactNativeFiberInspector'; +import { + getInspectorDataForViewTag, + getInspectorDataForViewAtPoint, +} from './ReactNativeFiberInspector'; import {LegacyRoot} from 'shared/ReactRootTags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; @@ -247,7 +250,10 @@ export { injectIntoDevTools({ findFiberByHostInstance: getClosestInstanceFromNode, getInspectorDataForViewTag: getInspectorDataForViewTag, - getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind(null, findNodeHandle), + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( + null, + findNodeHandle, + ), bundleType: __DEV__ ? 1 : 0, version: ReactVersion, rendererPackageName: 'react-native-renderer', From 2a0a0b33421654262f1b8e7e27eef4ed6875e98e Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Sat, 7 Mar 2020 21:45:18 +0000 Subject: [PATCH 03/11] Feedback updates --- .../src/ReactNativeFiberInspector.js | 57 +++++++++---------- .../src/ReactNativeTypes.js | 18 ++++++ scripts/error-codes/codes.json | 3 +- scripts/flow/react-native-host-hooks.js | 18 ++++++ 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index f83dfc5bff23f..6ced608ae0eed 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -8,10 +8,7 @@ */ import type {Fiber} from 'react-reconciler/src/ReactFiber'; -import type { - ReactFabricType, - HostComponent as ReactNativeHostComponent, -} from './ReactNativeTypes'; +import type {TouchedViewDataAtPoint} from './ReactNativeTypes'; import { findCurrentHostFiber, @@ -152,11 +149,11 @@ if (__DEV__) { }; getInspectorDataForViewAtPoint = function( - findNodeHandle, - inspectedView: ?React.ElementRef>, - x: number, - y: number, - callback: (obj: Object) => mixed, + findNodeHandle: (componentOrHandle: any) => ?number, + inspectedView: Object, + locationX: number, + locationY: number, + callback: (viewData: TouchedViewDataAtPoint) => mixed, ): void { let closestInstance = null; let frame = { @@ -170,8 +167,8 @@ if (__DEV__) { // For Fabric we can look up the instance handle directly and measure it. nativeFabricUIManager.findNodeAtPoint( inspectedView._internalInstanceHandle.stateNode.node, - x, - y, + locationX, + locationY, shadowNode => { if (shadowNode == null) { callback(getInspectorDataForInstance(closestInstance, frame)); @@ -182,14 +179,13 @@ if (__DEV__) { nativeFabricUIManager.measure( shadowNode.stateNode.node, (x, y, width, height, pageX, pageY) => { - frame = { - left: pageX, - top: pageY, - width, - height, - }; - - callback(getInspectorDataForInstance(closestInstance, frame)); + const inspectorData = getInspectorDataForInstance( + closestInstance, + ); + callback({ + ...inspectorData, + frame: {left: pageX, top: pageY, width, height}, + }); }, ); }, @@ -198,19 +194,16 @@ if (__DEV__) { // For Paper we fall back to the old strategy using the React tag. UIManager.findSubviewIn( findNodeHandle(inspectedView), - [x, y], + [locationX, locationY], (nativeViewTag, left, top, width, height) => { - frame = { - left, - top, - width, - height, - }; const inspectorData = getInspectorDataForInstance( getClosestInstanceFromNode(nativeViewTag), - frame, ); - callback({...inspectorData, nativeViewTag}); + callback({ + ...inspectorData, + frame: {left, top, width, height}, + touchedViewTag: nativeViewTag + }); }, ); } else if (__DEV__) { @@ -229,7 +222,13 @@ if (__DEV__) { ); }; - getInspectorDataForViewAtPoint = () => { + getInspectorDataForViewAtPoint = ( + findNodeHandle: (componentOrHandle: any) => ?number, + inspectedView: Object, + locationX: number, + locationY: number, + callback: (viewData: TouchedViewDataAtPoint) => mixed, + ): void => { invariant( false, 'getInspectorDataForViewAtPoint() is not available in production', diff --git a/packages/react-native-renderer/src/ReactNativeTypes.js b/packages/react-native-renderer/src/ReactNativeTypes.js index 4c2df9a44fe06..d5bfd05f18b9d 100644 --- a/packages/react-native-renderer/src/ReactNativeTypes.js +++ b/packages/react-native-renderer/src/ReactNativeTypes.js @@ -100,6 +100,24 @@ type SecretInternalsType = { ... }; +export type TouchedViewDataAtPoint = $ReadOnly<{ + hierarchy?: ?Array<{|name: string|}>, + pointerY: number, + touchedViewTag?: ?number, + props: $ReadOnly<{[propName: string]: string, ...}>, + selection: number, + source: $ReadOnly<{| + fileName?: string, + lineNumber?: number, + |}>, + frame?: ?$ReadOnly<{| + top?: ?number, + left?: ?number, + width?: ?number, + height: ?number, + |}>, +}>; + /** * Flat ReactNative renderer bundles are too big for Flow to parse efficiently. * Provide minimal Flow typing for the high-level RN API and call it a day. diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index 9e85caa7c7475..96540887dd81f 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -346,5 +346,6 @@ "345": "Root did not complete. This is a bug in React.", "346": "An event responder context was used outside of an event cycle.", "347": "Maps are not valid as a React child (found: %s). Consider converting children to an array of keyed ReactElements instead.", - "348": "ensureListeningTo(): received a container that was not an element node. This is likely a bug in React." + "348": "ensureListeningTo(): received a container that was not an element node. This is likely a bug in React.", + "349": "getInspectorDataForViewAtPoint() is not available in production" } diff --git a/scripts/flow/react-native-host-hooks.js b/scripts/flow/react-native-host-hooks.js index 85ea68f160ce2..151e36e4c47fd 100644 --- a/scripts/flow/react-native-host-hooks.js +++ b/scripts/flow/react-native-host-hooks.js @@ -18,6 +18,7 @@ import type { } from 'react-native-renderer/src/ReactNativeTypes'; import type {RNTopLevelEventType} from 'legacy-events/TopLevelEventTypes'; import type {CapturedError} from 'react-reconciler/src/ReactCapturedValue'; +import type {Fiber} from 'react-reconciler/src/ReactFiber'; type DeepDifferOptions = {|+unsafelyIgnoreFunctions?: boolean|}; @@ -96,6 +97,17 @@ declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface' ) => Promise, setJSResponder: (reactTag: number, blockNativeResponder: boolean) => void, clearJSResponder: () => void, + findSubviewIn: ( + reactTag: ?number, + point: Array, + callback: ( + nativeViewTag: number, + left: number, + top: number, + width: number, + height: number, + ) => void, + ) => void, ... }; declare export var BatchedBridge: { @@ -156,6 +168,12 @@ declare var nativeFabricUIManager: { onFail: () => void, onSuccess: MeasureLayoutOnSuccessCallback, ) => void, + findNodeAtPoint: ( + node: Node, + locationX: number, + locationY: number, + callback: (Fiber) => void, + ) => void, ... }; From f2a947b6dbb46bf89e1e31776ac1577bfb5fc303 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Sat, 7 Mar 2020 21:46:34 +0000 Subject: [PATCH 04/11] Fix reference error from dropped change --- packages/react-native-renderer/src/ReactNativeFiberInspector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index 6ced608ae0eed..4585f2efaf1e2 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -202,7 +202,7 @@ if (__DEV__) { callback({ ...inspectorData, frame: {left, top, width, height}, - touchedViewTag: nativeViewTag + touchedViewTag: nativeViewTag, }); }, ); From 9c54afdbdc8210ddde776c1214b71b5218e47778 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Sun, 8 Mar 2020 00:02:52 +0000 Subject: [PATCH 05/11] Update flow types --- packages/react-reconciler/src/ReactFiberReconciler.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index 816a3946562e1..c64852a4703a8 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -10,6 +10,7 @@ import type {Fiber} from './ReactFiber'; import type {FiberRoot} from './ReactFiberRoot'; import type {RootTag} from 'shared/ReactRootTags'; +import type {TouchedViewDataAtPoint} from 'react-native-renderer/src/ReactNativeTypes'; import type { Instance, TextInstance, @@ -109,6 +110,12 @@ type DevToolsConfig = {| // This API is unfortunately RN-specific. // TODO: Change it to accept Fiber instead and type it properly. getInspectorDataForViewTag?: (tag: number) => Object, + // Used by RN in-app inspector. + getInspectorDataForViewAtPoint?: ( + inspectedView: Object, + locationX: number, + locationY: number, + callback: (viewData: TouchedViewDataAtPoint) => mixed) => void, |}; let didWarnAboutNestedUpdates; From 5b3e8a1d0689287d71ac01bea2a32de335701abf Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Sun, 8 Mar 2020 00:07:18 +0000 Subject: [PATCH 06/11] Prettier --- packages/react-reconciler/src/ReactFiberReconciler.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index c64852a4703a8..62173998d4ff5 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -115,7 +115,8 @@ type DevToolsConfig = {| inspectedView: Object, locationX: number, locationY: number, - callback: (viewData: TouchedViewDataAtPoint) => mixed) => void, + callback: (viewData: TouchedViewDataAtPoint) => mixed, + ) => void, |}; let didWarnAboutNestedUpdates; From 96b3319ee93c693798fe819ba5329c449bff8f46 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Tue, 10 Mar 2020 16:53:20 +0000 Subject: [PATCH 07/11] Update flow types --- .../src/ReactNativeFiberInspector.js | 24 +++++------- .../src/ReactNativeTypes.js | 38 +++++++++++++++---- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index 4585f2efaf1e2..d09358dd1fc7b 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -8,7 +8,7 @@ */ import type {Fiber} from 'react-reconciler/src/ReactFiber'; -import type {TouchedViewDataAtPoint} from './ReactNativeTypes'; +import type {TouchedViewDataAtPoint, InspectorData} from './ReactNativeTypes'; import { findCurrentHostFiber, @@ -91,7 +91,7 @@ if (__DEV__) { })); }; - const getInspectorDataForInstance = function(closestInstance, frame): Object { + const getInspectorDataForInstance = function(closestInstance): InspectorData { // Handle case where user clicks outside of ReactNative if (!closestInstance) { return { @@ -112,7 +112,6 @@ if (__DEV__) { return { hierarchy, - frame, props, selection, source, @@ -156,12 +155,6 @@ if (__DEV__) { callback: (viewData: TouchedViewDataAtPoint) => mixed, ): void { let closestInstance = null; - let frame = { - left: 0, - top: 0, - width: 0, - height: 0, - }; if (inspectedView._internalInstanceHandle != null) { // For Fabric we can look up the instance handle directly and measure it. @@ -171,7 +164,11 @@ if (__DEV__) { locationY, shadowNode => { if (shadowNode == null) { - callback(getInspectorDataForInstance(closestInstance, frame)); + callback({ + pointerY: locationY, + frame: {left: 0, top: 0, width: 0, height: 0}, + ...getInspectorDataForInstance(closestInstance), + }); } closestInstance = @@ -179,12 +176,10 @@ if (__DEV__) { nativeFabricUIManager.measure( shadowNode.stateNode.node, (x, y, width, height, pageX, pageY) => { - const inspectorData = getInspectorDataForInstance( - closestInstance, - ); callback({ - ...inspectorData, + pointerY: locationY, frame: {left: pageX, top: pageY, width, height}, + ...getInspectorDataForInstance(closestInstance), }); }, ); @@ -201,6 +196,7 @@ if (__DEV__) { ); callback({ ...inspectorData, + pointerY: locationY, frame: {left, top, width, height}, touchedViewTag: nativeViewTag, }); diff --git a/packages/react-native-renderer/src/ReactNativeTypes.js b/packages/react-native-renderer/src/ReactNativeTypes.js index d5bfd05f18b9d..98d19de2d478d 100644 --- a/packages/react-native-renderer/src/ReactNativeTypes.js +++ b/packages/react-native-renderer/src/ReactNativeTypes.js @@ -100,22 +100,44 @@ type SecretInternalsType = { ... }; +type InspectorDataProps = $ReadOnly<{ + [propName: string]: string, + ..., +}>; + +type InspectorDataSource = $ReadOnly<{| + fileName?: string, + lineNumber?: number, +|}>; + +type InspectorDataGetter = ( + (componentOrHandle: any) => ?number, +) => $ReadOnly<{| + measure: Function, + props: InspectorDataProps, + source: ?InspectorDataSource, +|}>; + +export type InspectorData = $ReadOnly<{ + hierarchy?: ?Array<{| + name: ?string, + getInspectorData: InspectorDataGetter, + |}>, + selection: ?number, + props: InspectorDataProps, + source: ?InspectorDataSource, +}>; + export type TouchedViewDataAtPoint = $ReadOnly<{ - hierarchy?: ?Array<{|name: string|}>, - pointerY: number, + pointerY: ?number, touchedViewTag?: ?number, - props: $ReadOnly<{[propName: string]: string, ...}>, - selection: number, - source: $ReadOnly<{| - fileName?: string, - lineNumber?: number, - |}>, frame?: ?$ReadOnly<{| top?: ?number, left?: ?number, width?: ?number, height: ?number, |}>, + ...InspectorData, }>; /** From a3b89212ee0aa99725cb5b940080b0452242e377 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Tue, 10 Mar 2020 23:21:19 +0000 Subject: [PATCH 08/11] Update getInspectorData for Fabric --- .../src/ReactNativeFiberInspector.js | 38 ++++++++++++++++--- .../src/ReactNativeTypes.js | 18 ++++----- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index d09358dd1fc7b..ce2d0c4646b03 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -82,12 +82,38 @@ if (__DEV__) { const createHierarchy = function(fiberHierarchy) { return fiberHierarchy.map(fiber => ({ name: getComponentName(fiber.type), - getInspectorData: findNodeHandle => ({ - measure: callback => - UIManager.measure(getHostNode(fiber, findNodeHandle), callback), - props: getHostProps(fiber), - source: fiber._debugSource, - }), + getInspectorData: findNodeHandle => { + return { + props: getHostProps(fiber), + source: fiber._debugSource, + measure: callback => { + // If this is Fabric, we'll find a ShadowNode and use that to measure. + const hostFiber = findCurrentHostFiber(fiber); + const shadowNode = + hostFiber != null && + hostFiber.stateNode !== null && + hostFiber.stateNode.node; + + if (shadowNode) { + nativeFabricUIManager.measure(shadowNode, function( + x, + y, + width, + height, + pageX, + pageY, + ) { + callback(x, y, width, height, pageX, pageY); + }); + } else { + return UIManager.measure( + getHostNode(fiber, findNodeHandle), + callback, + ); + } + }, + }; + }, })); }; diff --git a/packages/react-native-renderer/src/ReactNativeTypes.js b/packages/react-native-renderer/src/ReactNativeTypes.js index 98d19de2d478d..e63bd4b7ce0c1 100644 --- a/packages/react-native-renderer/src/ReactNativeTypes.js +++ b/packages/react-native-renderer/src/ReactNativeTypes.js @@ -115,11 +115,11 @@ type InspectorDataGetter = ( ) => $ReadOnly<{| measure: Function, props: InspectorDataProps, - source: ?InspectorDataSource, + source: InspectorDataSource, |}>; export type InspectorData = $ReadOnly<{ - hierarchy?: ?Array<{| + hierarchy: Array<{| name: ?string, getInspectorData: InspectorDataGetter, |}>, @@ -129,13 +129,13 @@ export type InspectorData = $ReadOnly<{ }>; export type TouchedViewDataAtPoint = $ReadOnly<{ - pointerY: ?number, - touchedViewTag?: ?number, - frame?: ?$ReadOnly<{| - top?: ?number, - left?: ?number, - width?: ?number, - height: ?number, + pointerY: number, + touchedViewTag?: number, + frame: $ReadOnly<{| + top: number, + left: number, + width: number, + height: number, |}>, ...InspectorData, }>; From cf2aa24f0ee6858507576392addb49cfee8b4172 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Wed, 11 Mar 2020 00:47:25 +0000 Subject: [PATCH 09/11] Minor naming and grammar updates --- .../src/ReactNativeFiberInspector.js | 8 ++++---- scripts/error-codes/codes.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index ce2d0c4646b03..c6d55f96f6a74 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -188,8 +188,8 @@ if (__DEV__) { inspectedView._internalInstanceHandle.stateNode.node, locationX, locationY, - shadowNode => { - if (shadowNode == null) { + internalInstanceHandle => { + if (internalInstanceHandle == null) { callback({ pointerY: locationY, frame: {left: 0, top: 0, width: 0, height: 0}, @@ -198,9 +198,9 @@ if (__DEV__) { } closestInstance = - shadowNode.stateNode.canonical._internalInstanceHandle; + internalInstanceHandle.stateNode.canonical._internalInstanceHandle; nativeFabricUIManager.measure( - shadowNode.stateNode.node, + internalInstanceHandle.stateNode.node, (x, y, width, height, pageX, pageY) => { callback({ pointerY: locationY, diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index 96540887dd81f..4383e3af74a2b 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -347,5 +347,5 @@ "346": "An event responder context was used outside of an event cycle.", "347": "Maps are not valid as a React child (found: %s). Consider converting children to an array of keyed ReactElements instead.", "348": "ensureListeningTo(): received a container that was not an element node. This is likely a bug in React.", - "349": "getInspectorDataForViewAtPoint() is not available in production" + "349": "getInspectorDataForViewAtPoint() is not available in production." } From b572c1dd24dcaafb89e05cb4b553b51c888bada3 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Wed, 11 Mar 2020 01:08:16 +0000 Subject: [PATCH 10/11] Make types exact --- packages/react-native-renderer/src/ReactNativeTypes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-native-renderer/src/ReactNativeTypes.js b/packages/react-native-renderer/src/ReactNativeTypes.js index e63bd4b7ce0c1..d36378f4d1eb8 100644 --- a/packages/react-native-renderer/src/ReactNativeTypes.js +++ b/packages/react-native-renderer/src/ReactNativeTypes.js @@ -118,7 +118,7 @@ type InspectorDataGetter = ( source: InspectorDataSource, |}>; -export type InspectorData = $ReadOnly<{ +export type InspectorData = $ReadOnly<{| hierarchy: Array<{| name: ?string, getInspectorData: InspectorDataGetter, @@ -126,9 +126,9 @@ export type InspectorData = $ReadOnly<{ selection: ?number, props: InspectorDataProps, source: ?InspectorDataSource, -}>; +|}>; -export type TouchedViewDataAtPoint = $ReadOnly<{ +export type TouchedViewDataAtPoint = $ReadOnly<{| pointerY: number, touchedViewTag?: number, frame: $ReadOnly<{| @@ -138,7 +138,7 @@ export type TouchedViewDataAtPoint = $ReadOnly<{ height: number, |}>, ...InspectorData, -}>; +|}>; /** * Flat ReactNative renderer bundles are too big for Flow to parse efficiently. From aa3719acd23e36924f8d9dfac40c8bd555751ee0 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Wed, 11 Mar 2020 14:56:25 +0000 Subject: [PATCH 11/11] Fix lint --- packages/react-native-renderer/src/ReactNativeFiberInspector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index c6d55f96f6a74..9a25195fc478e 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -253,7 +253,7 @@ if (__DEV__) { ): void => { invariant( false, - 'getInspectorDataForViewAtPoint() is not available in production', + 'getInspectorDataForViewAtPoint() is not available in production.', ); }; }