From 051a17969ef06a22edf75a973ab49878907fdfa8 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Thu, 2 Jun 2022 17:08:33 -0400 Subject: [PATCH 1/9] [DevTools] find best renderer when inspecting --- .../src/backend/agent.js | 21 +++++++++---------- .../src/backend/legacy/renderer.js | 6 ++++++ .../src/backend/renderer.js | 5 +++++ .../src/backend/types.js | 1 + .../src/backend/utils.js | 21 +++++++++++++++++++ .../src/backend/views/Highlighter/Overlay.js | 9 +++++--- 6 files changed, 49 insertions(+), 14 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/agent.js b/packages/react-devtools-shared/src/backend/agent.js index 0f0ddbc332c19..811ad2aaf6660 100644 --- a/packages/react-devtools-shared/src/backend/agent.js +++ b/packages/react-devtools-shared/src/backend/agent.js @@ -39,7 +39,10 @@ import type { RendererInterface, } from './types'; import type {ComponentFilter} from '../types'; -import {isSynchronousXHRSupported} from './utils'; +import { + isSynchronousXHRSupported, + getBestMatchingRendererInterface, +} from './utils'; import type {BrowserTheme} from 'react-devtools-shared/src/devtools/views/DevTools'; const debug = (methodName, ...args) => { @@ -310,20 +313,16 @@ export default class Agent extends EventEmitter<{| } getIDForNode(node: Object): number | null { + const renderers = []; for (const rendererID in this._rendererInterfaces) { const renderer = ((this._rendererInterfaces[ (rendererID: any) ]: any): RendererInterface); - - try { - const id = renderer.getFiberIDForNative(node, true); - if (id !== null) { - return id; - } - } catch (error) { - // Some old React versions might throw if they can't find a match. - // If so we should ignore it... - } + renderers.push(renderer); + } + const rendererInterface = getBestMatchingRendererInterface(renderers, node); + if (rendererInterface != null) { + return rendererInterface.getFiberIDForNative(node, true); } return null; } diff --git a/packages/react-devtools-shared/src/backend/legacy/renderer.js b/packages/react-devtools-shared/src/backend/legacy/renderer.js index f24b5bac85bb6..07dd7b02a9332 100644 --- a/packages/react-devtools-shared/src/backend/legacy/renderer.js +++ b/packages/react-devtools-shared/src/backend/legacy/renderer.js @@ -1084,6 +1084,11 @@ export function attach( function unpatchConsoleForStrictMode() {} + function getFiberForNative() { + // Not implemented + return null; + } + return { clearErrorsAndWarnings, clearErrorsForFiberID, @@ -1094,6 +1099,7 @@ export function attach( flushInitialOperations, getBestMatchForTrackedPath, getDisplayNameForFiberID, + getFiberForNative, getFiberIDForNative: getInternalIDForNative, getInstanceAndStyle, findNativeNodesForFiberID: (id: number) => { diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index 055b57ee4b52e..5f9033af9903c 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -2818,6 +2818,10 @@ export function attach( return fiber != null ? getDisplayNameForFiber(((fiber: any): Fiber)) : null; } + function getFiberForNative(hostInstance) { + return renderer.findFiberByHostInstance(hostInstance); + } + function getFiberIDForNative( hostInstance, findNearestUnfilteredAncestor = false, @@ -4490,6 +4494,7 @@ export function attach( flushInitialOperations, getBestMatchForTrackedPath, getDisplayNameForFiberID, + getFiberForNative, getFiberIDForNative, getInstanceAndStyle, getOwnersList, diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js index 92ad42c3010cf..e670b3da688bc 100644 --- a/packages/react-devtools-shared/src/backend/types.js +++ b/packages/react-devtools-shared/src/backend/types.js @@ -350,6 +350,7 @@ export type RendererInterface = { findNativeNodesForFiberID: FindNativeNodesForFiberID, flushInitialOperations: () => void, getBestMatchForTrackedPath: () => PathMatch | null, + getFiberForNative: (hostInstance: NativeType) => ?Fiber, getFiberIDForNative: GetFiberIDForNative, getDisplayNameForFiberID: GetDisplayNameForFiberID, getInstanceAndStyle(id: number): InstanceAndStyle, diff --git a/packages/react-devtools-shared/src/backend/utils.js b/packages/react-devtools-shared/src/backend/utils.js index 5c4b1289855b2..078ab00d6f15f 100644 --- a/packages/react-devtools-shared/src/backend/utils.js +++ b/packages/react-devtools-shared/src/backend/utils.js @@ -11,6 +11,7 @@ import {copy} from 'clipboard-js'; import {dehydrate} from '../hydration'; import isArray from 'shared/isArray'; +import type {RendererInterface} from './types'; import type {DehydratedData} from 'react-devtools-shared/src/devtools/views/Components/types'; @@ -273,3 +274,23 @@ export function isSynchronousXHRSupported(): boolean { window.document.featurePolicy.allowsFeature('sync-xhr') ); } + +export function getBestMatchingRendererInterface( + rendererInterfaces: Iterable, + node: Object, +): RendererInterface | null { + let bestMatch = null; + for (const renderer of rendererInterfaces) { + const fiber = renderer.getFiberForNative(node); + if (fiber != null) { + // check if fiber.stateNode is matching the original hostInstance + if (fiber.stateNode === node) { + return renderer; + } else { + bestMatch = renderer; + } + } + } + // if an exact match is not found, return the best match as fallback + return bestMatch; +} diff --git a/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js b/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js index ba763562a1629..e00b9ecf3c4ee 100644 --- a/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js +++ b/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js @@ -8,6 +8,7 @@ */ import {getElementDimensions, getNestedBoundingClientRect} from '../utils'; +import {getBestMatchingRendererInterface} from '../../utils'; const assign = Object.assign; @@ -233,13 +234,15 @@ export default class Overlay { const hook: DevToolsHook = node.ownerDocument.defaultView.__REACT_DEVTOOLS_GLOBAL_HOOK__; if (hook != null && hook.rendererInterfaces != null) { + const rendererInterface = getBestMatchingRendererInterface( + hook.rendererInterfaces.values(), + node, + ); let ownerName = null; - // eslint-disable-next-line no-for-of-loops/no-for-of-loops - for (const rendererInterface of hook.rendererInterfaces.values()) { + if (rendererInterface !== null) { const id = rendererInterface.getFiberIDForNative(node, true); if (id !== null) { ownerName = rendererInterface.getDisplayNameForFiberID(id, true); - break; } } From 29841c913e7ed81bfd45bb7acfd7142449760025 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Thu, 2 Jun 2022 18:46:53 -0400 Subject: [PATCH 2/9] fix lint --- packages/react-devtools-shared/src/backend/utils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-devtools-shared/src/backend/utils.js b/packages/react-devtools-shared/src/backend/utils.js index 078ab00d6f15f..c3392ea09b854 100644 --- a/packages/react-devtools-shared/src/backend/utils.js +++ b/packages/react-devtools-shared/src/backend/utils.js @@ -280,6 +280,7 @@ export function getBestMatchingRendererInterface( node: Object, ): RendererInterface | null { let bestMatch = null; + // eslint-disable-next-line no-for-of-loops/no-for-of-loops for (const renderer of rendererInterfaces) { const fiber = renderer.getFiberForNative(node); if (fiber != null) { From 276fc88c7941251352caa4f53f4e9f5f560b501b Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Mon, 6 Jun 2022 17:02:47 -0400 Subject: [PATCH 3/9] fix test --- .../src/backend/legacy/renderer.js | 15 ++++++++++----- .../react-devtools-shared/src/backend/types.js | 7 +++++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/legacy/renderer.js b/packages/react-devtools-shared/src/backend/legacy/renderer.js index 07dd7b02a9332..70d700fb7c598 100644 --- a/packages/react-devtools-shared/src/backend/legacy/renderer.js +++ b/packages/react-devtools-shared/src/backend/legacy/renderer.js @@ -40,6 +40,7 @@ import {decorateMany, forceUpdate, restoreMany} from './utils'; import type { DevToolsHook, GetFiberIDForNative, + GetFiberForNative, InspectedElementPayload, InstanceAndStyle, NativeType, @@ -148,6 +149,10 @@ export function attach( let getInternalIDForNative: GetFiberIDForNative = ((null: any): GetFiberIDForNative); let findNativeNodeForInternalID: (id: number) => ?NativeType; + let getFiberForNative: GetFiberForNative = (node) => { + // Not implemented. + return null; + }; if (renderer.ComponentTree) { getInternalIDForNative = (node, findNearestUnfilteredAncestor) => { @@ -160,6 +165,11 @@ export function attach( const internalInstance = idToInternalInstanceMap.get(id); return renderer.ComponentTree.getNodeFromInstance(internalInstance); }; + getFiberForNative = (node) => { + return renderer.ComponentTree.getClosestInstanceFromNode( + node, + ); + }; } else if (renderer.Mount.getID && renderer.Mount.getNode) { getInternalIDForNative = (node, findNearestUnfilteredAncestor) => { // Not implemented. @@ -1084,11 +1094,6 @@ export function attach( function unpatchConsoleForStrictMode() {} - function getFiberForNative() { - // Not implemented - return null; - } - return { clearErrorsAndWarnings, clearErrorsForFiberID, diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js index e670b3da688bc..c7aa43f302108 100644 --- a/packages/react-devtools-shared/src/backend/types.js +++ b/packages/react-devtools-shared/src/backend/types.js @@ -81,6 +81,9 @@ export type GetFiberIDForNative = ( component: NativeType, findNearestUnfilteredAncestor?: boolean, ) => number | null; +export type GetFiberForNative = ( + component: NativeType, +) => Fiber | null; export type FindNativeNodesForFiberID = (id: number) => ?Array; export type ReactProviderType = { @@ -93,7 +96,7 @@ export type Lane = number; export type Lanes = number; export type ReactRenderer = { - findFiberByHostInstance: (hostInstance: NativeType) => ?Fiber, + findFiberByHostInstance: (hostInstance: NativeType) => Fiber | null, version: string, rendererPackageName: string, bundleType: BundleType, @@ -350,7 +353,7 @@ export type RendererInterface = { findNativeNodesForFiberID: FindNativeNodesForFiberID, flushInitialOperations: () => void, getBestMatchForTrackedPath: () => PathMatch | null, - getFiberForNative: (hostInstance: NativeType) => ?Fiber, + getFiberForNative: GetFiberForNative, getFiberIDForNative: GetFiberIDForNative, getDisplayNameForFiberID: GetDisplayNameForFiberID, getInstanceAndStyle(id: number): InstanceAndStyle, From b7d225aec60725c9fff6561a7442f689ebbc816b Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Mon, 6 Jun 2022 17:19:34 -0400 Subject: [PATCH 4/9] fix lint --- .../react-devtools-shared/src/backend/legacy/renderer.js | 8 +++----- packages/react-devtools-shared/src/backend/types.js | 4 +--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/legacy/renderer.js b/packages/react-devtools-shared/src/backend/legacy/renderer.js index 70d700fb7c598..602e53c66e5a1 100644 --- a/packages/react-devtools-shared/src/backend/legacy/renderer.js +++ b/packages/react-devtools-shared/src/backend/legacy/renderer.js @@ -149,7 +149,7 @@ export function attach( let getInternalIDForNative: GetFiberIDForNative = ((null: any): GetFiberIDForNative); let findNativeNodeForInternalID: (id: number) => ?NativeType; - let getFiberForNative: GetFiberForNative = (node) => { + let getFiberForNative: GetFiberForNative = node => { // Not implemented. return null; }; @@ -165,10 +165,8 @@ export function attach( const internalInstance = idToInternalInstanceMap.get(id); return renderer.ComponentTree.getNodeFromInstance(internalInstance); }; - getFiberForNative = (node) => { - return renderer.ComponentTree.getClosestInstanceFromNode( - node, - ); + getFiberForNative = node => { + return renderer.ComponentTree.getClosestInstanceFromNode(node); }; } else if (renderer.Mount.getID && renderer.Mount.getNode) { getInternalIDForNative = (node, findNearestUnfilteredAncestor) => { diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js index c7aa43f302108..05abff2ed5a47 100644 --- a/packages/react-devtools-shared/src/backend/types.js +++ b/packages/react-devtools-shared/src/backend/types.js @@ -81,9 +81,7 @@ export type GetFiberIDForNative = ( component: NativeType, findNearestUnfilteredAncestor?: boolean, ) => number | null; -export type GetFiberForNative = ( - component: NativeType, -) => Fiber | null; +export type GetFiberForNative = (component: NativeType) => Fiber | null; export type FindNativeNodesForFiberID = (id: number) => ?Array; export type ReactProviderType = { From 7a6b59fe1c439f30881a8e12752840e87aed0466 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Mon, 6 Jun 2022 22:56:42 -0400 Subject: [PATCH 5/9] move logic to agent --- .../src/backend/agent.js | 34 ++++++++++++++----- .../src/backend/utils.js | 21 ------------ .../backend/views/Highlighter/Highlighter.js | 5 ++- .../src/backend/views/Highlighter/Overlay.js | 34 ++++++------------- .../src/backend/views/Highlighter/index.js | 4 +-- 5 files changed, 43 insertions(+), 55 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/agent.js b/packages/react-devtools-shared/src/backend/agent.js index 811ad2aaf6660..9baca3cd104fa 100644 --- a/packages/react-devtools-shared/src/backend/agent.js +++ b/packages/react-devtools-shared/src/backend/agent.js @@ -39,10 +39,7 @@ import type { RendererInterface, } from './types'; import type {ComponentFilter} from '../types'; -import { - isSynchronousXHRSupported, - getBestMatchingRendererInterface, -} from './utils'; +import {isSynchronousXHRSupported} from './utils'; import type {BrowserTheme} from 'react-devtools-shared/src/devtools/views/DevTools'; const debug = (methodName, ...args) => { @@ -312,21 +309,42 @@ export default class Agent extends EventEmitter<{| return renderer.getInstanceAndStyle(id); } - getIDForNode(node: Object): number | null { - const renderers = []; + getBestMatchingRendererInterface(node: Object): RendererInterface | null { + let bestMatch = null; for (const rendererID in this._rendererInterfaces) { const renderer = ((this._rendererInterfaces[ (rendererID: any) ]: any): RendererInterface); - renderers.push(renderer); + const fiber = renderer.getFiberForNative(node); + if (fiber != null) { + // check if fiber.stateNode is matching the original hostInstance + if (fiber.stateNode === node) { + return renderer; + } else { + bestMatch = renderer; + } + } } - const rendererInterface = getBestMatchingRendererInterface(renderers, node); + // if an exact match is not found, return the best match as fallback + return bestMatch; + } + + getIDForNode(node: Object): number | null { + const rendererInterface = this.getBestMatchingRendererInterface(node); if (rendererInterface != null) { return rendererInterface.getFiberIDForNative(node, true); } return null; } + getDisplayNameForNode(node: Object): string | null { + const rendererInterface = this.getBestMatchingRendererInterface(node); + if (rendererInterface != null) { + return rendererInterface.getDisplayNameForFiberID(node, true); + } + return null; + } + getBackendVersion = () => { const version = process.env.DEVTOOLS_VERSION; if (version) { diff --git a/packages/react-devtools-shared/src/backend/utils.js b/packages/react-devtools-shared/src/backend/utils.js index c3392ea09b854..5071f362495e9 100644 --- a/packages/react-devtools-shared/src/backend/utils.js +++ b/packages/react-devtools-shared/src/backend/utils.js @@ -274,24 +274,3 @@ export function isSynchronousXHRSupported(): boolean { window.document.featurePolicy.allowsFeature('sync-xhr') ); } - -export function getBestMatchingRendererInterface( - rendererInterfaces: Iterable, - node: Object, -): RendererInterface | null { - let bestMatch = null; - // eslint-disable-next-line no-for-of-loops/no-for-of-loops - for (const renderer of rendererInterfaces) { - const fiber = renderer.getFiberForNative(node); - if (fiber != null) { - // check if fiber.stateNode is matching the original hostInstance - if (fiber.stateNode === node) { - return renderer; - } else { - bestMatch = renderer; - } - } - } - // if an exact match is not found, return the best match as fallback - return bestMatch; -} diff --git a/packages/react-devtools-shared/src/backend/views/Highlighter/Highlighter.js b/packages/react-devtools-shared/src/backend/views/Highlighter/Highlighter.js index b547913cda46d..3a5228658e212 100644 --- a/packages/react-devtools-shared/src/backend/views/Highlighter/Highlighter.js +++ b/packages/react-devtools-shared/src/backend/views/Highlighter/Highlighter.js @@ -7,6 +7,8 @@ * @flow */ +import type Agent from 'react-devtools-shared/src/backend/agent'; + import Overlay from './Overlay'; const SHOW_DURATION = 2000; @@ -26,6 +28,7 @@ export function hideOverlay() { export function showOverlay( elements: Array | null, componentName: string | null, + agent: Agent, hideAfterTimeout: boolean, ) { // TODO (npm-packages) Detect RN and support it somehow @@ -42,7 +45,7 @@ export function showOverlay( } if (overlay === null) { - overlay = new Overlay(); + overlay = new Overlay(agent); } overlay.inspect(elements, componentName); diff --git a/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js b/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js index e00b9ecf3c4ee..e1709951f4b47 100644 --- a/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js +++ b/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js @@ -8,15 +8,14 @@ */ import {getElementDimensions, getNestedBoundingClientRect} from '../utils'; -import {getBestMatchingRendererInterface} from '../../utils'; -const assign = Object.assign; - -import type {DevToolsHook} from 'react-devtools-shared/src/backend/types'; import type {Rect} from '../utils'; +import type Agent from 'react-devtools-shared/src/backend/agent'; type Box = {|top: number, left: number, width: number, height: number|}; +const assign = Object.assign; + // Note that the Overlay components are not affected by the active Theme, // because they highlight elements in the main Chrome window (outside of devtools). // The colors below were chosen to roughly match those used by Chrome devtools. @@ -154,8 +153,9 @@ export default class Overlay { container: HTMLElement; tip: OverlayTip; rects: Array; + agent: Agent; - constructor() { + constructor(agent: Agent) { // Find the root window, because overlays are positioned relative to it. const currentWindow = window.__REACT_DEVTOOLS_TARGET_WINDOW__ || window; this.window = currentWindow; @@ -171,6 +171,8 @@ export default class Overlay { this.tip = new OverlayTip(doc, this.container); this.rects = []; + this.agent = agent; + doc.body.appendChild(this.container); } @@ -231,24 +233,10 @@ export default class Overlay { name = elements[0].nodeName.toLowerCase(); const node = elements[0]; - const hook: DevToolsHook = - node.ownerDocument.defaultView.__REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook != null && hook.rendererInterfaces != null) { - const rendererInterface = getBestMatchingRendererInterface( - hook.rendererInterfaces.values(), - node, - ); - let ownerName = null; - if (rendererInterface !== null) { - const id = rendererInterface.getFiberIDForNative(node, true); - if (id !== null) { - ownerName = rendererInterface.getDisplayNameForFiberID(id, true); - } - } - - if (ownerName) { - name += ' (in ' + ownerName + ')'; - } + const ownerName = this.agent.getDisplayNameForNode(node); + + if (ownerName) { + name += ' (in ' + ownerName + ')'; } } diff --git a/packages/react-devtools-shared/src/backend/views/Highlighter/index.js b/packages/react-devtools-shared/src/backend/views/Highlighter/index.js index 1f3b8974b6578..683c37fd8d02d 100644 --- a/packages/react-devtools-shared/src/backend/views/Highlighter/index.js +++ b/packages/react-devtools-shared/src/backend/views/Highlighter/index.js @@ -118,7 +118,7 @@ export default function setupHighlighter( node.scrollIntoView({block: 'nearest', inline: 'nearest'}); } - showOverlay(nodes, displayName, hideAfterTimeout); + showOverlay(nodes, displayName, agent, hideAfterTimeout); if (openNativeElementsPanel) { window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 = node; @@ -171,7 +171,7 @@ export default function setupHighlighter( // Don't pass the name explicitly. // It will be inferred from DOM tag and Fiber owner. - showOverlay([target], null, false); + showOverlay([target], null, agent, false); selectFiberForNode(target); } From 975601beb5f19c82b21c176655843702680ac8c2 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Mon, 6 Jun 2022 23:01:46 -0400 Subject: [PATCH 6/9] fix lint --- packages/react-devtools-shared/src/backend/utils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-devtools-shared/src/backend/utils.js b/packages/react-devtools-shared/src/backend/utils.js index 5071f362495e9..5c4b1289855b2 100644 --- a/packages/react-devtools-shared/src/backend/utils.js +++ b/packages/react-devtools-shared/src/backend/utils.js @@ -11,7 +11,6 @@ import {copy} from 'clipboard-js'; import {dehydrate} from '../hydration'; import isArray from 'shared/isArray'; -import type {RendererInterface} from './types'; import type {DehydratedData} from 'react-devtools-shared/src/devtools/views/Components/types'; From 48bba785f548d4505ad0c218cec2b84569a24088 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Tue, 7 Jun 2022 17:43:25 -0400 Subject: [PATCH 7/9] style improvements per review comments --- .../react-devtools-shared/src/backend/agent.js | 14 +++----------- .../react-devtools-shared/src/backend/types.js | 3 +-- .../src/backend/views/Highlighter/Overlay.js | 13 +++++++++---- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/agent.js b/packages/react-devtools-shared/src/backend/agent.js index 9baca3cd104fa..1741984c96183 100644 --- a/packages/react-devtools-shared/src/backend/agent.js +++ b/packages/react-devtools-shared/src/backend/agent.js @@ -316,16 +316,16 @@ export default class Agent extends EventEmitter<{| (rendererID: any) ]: any): RendererInterface); const fiber = renderer.getFiberForNative(node); - if (fiber != null) { + if (fiber !== null) { // check if fiber.stateNode is matching the original hostInstance if (fiber.stateNode === node) { return renderer; - } else { + } else if (bestMatch === null) { bestMatch = renderer; } } } - // if an exact match is not found, return the best match as fallback + // if an exact match is not found, return the first valid renderer as fallback return bestMatch; } @@ -337,14 +337,6 @@ export default class Agent extends EventEmitter<{| return null; } - getDisplayNameForNode(node: Object): string | null { - const rendererInterface = this.getBestMatchingRendererInterface(node); - if (rendererInterface != null) { - return rendererInterface.getDisplayNameForFiberID(node, true); - } - return null; - } - getBackendVersion = () => { const version = process.env.DEVTOOLS_VERSION; if (version) { diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js index 05abff2ed5a47..81ed15b04ae78 100644 --- a/packages/react-devtools-shared/src/backend/types.js +++ b/packages/react-devtools-shared/src/backend/types.js @@ -81,7 +81,6 @@ export type GetFiberIDForNative = ( component: NativeType, findNearestUnfilteredAncestor?: boolean, ) => number | null; -export type GetFiberForNative = (component: NativeType) => Fiber | null; export type FindNativeNodesForFiberID = (id: number) => ?Array; export type ReactProviderType = { @@ -351,7 +350,7 @@ export type RendererInterface = { findNativeNodesForFiberID: FindNativeNodesForFiberID, flushInitialOperations: () => void, getBestMatchForTrackedPath: () => PathMatch | null, - getFiberForNative: GetFiberForNative, + getFiberForNative: (component: NativeType) => Fiber | null, getFiberIDForNative: GetFiberIDForNative, getDisplayNameForFiberID: GetDisplayNameForFiberID, getInstanceAndStyle(id: number): InstanceAndStyle, diff --git a/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js b/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js index e1709951f4b47..09369dfda4608 100644 --- a/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js +++ b/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js @@ -233,10 +233,15 @@ export default class Overlay { name = elements[0].nodeName.toLowerCase(); const node = elements[0]; - const ownerName = this.agent.getDisplayNameForNode(node); - - if (ownerName) { - name += ' (in ' + ownerName + ')'; + const rendererInterface = this.agent.getBestMatchingRendererInterface(node); + if (rendererInterface) { + const id = rendererInterface.getFiberIDForNative(node, true); + if (id) { + const ownerName = rendererInterface.getDisplayNameForFiberID(id, true); + if (ownerName) { + name += ' (in ' + ownerName + ')'; + } + } } } From 2e8c6c56f92f2d0c2f87a7d9109523b9b53abda7 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Tue, 7 Jun 2022 18:12:50 -0400 Subject: [PATCH 8/9] fix lint & flow --- .../react-devtools-shared/src/backend/legacy/renderer.js | 5 ++--- .../src/backend/views/Highlighter/Overlay.js | 9 +++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/legacy/renderer.js b/packages/react-devtools-shared/src/backend/legacy/renderer.js index 602e53c66e5a1..a3b1a860b8acd 100644 --- a/packages/react-devtools-shared/src/backend/legacy/renderer.js +++ b/packages/react-devtools-shared/src/backend/legacy/renderer.js @@ -40,7 +40,6 @@ import {decorateMany, forceUpdate, restoreMany} from './utils'; import type { DevToolsHook, GetFiberIDForNative, - GetFiberForNative, InspectedElementPayload, InstanceAndStyle, NativeType, @@ -149,7 +148,7 @@ export function attach( let getInternalIDForNative: GetFiberIDForNative = ((null: any): GetFiberIDForNative); let findNativeNodeForInternalID: (id: number) => ?NativeType; - let getFiberForNative: GetFiberForNative = node => { + let getFiberForNative = (node: NativeType) => { // Not implemented. return null; }; @@ -165,7 +164,7 @@ export function attach( const internalInstance = idToInternalInstanceMap.get(id); return renderer.ComponentTree.getNodeFromInstance(internalInstance); }; - getFiberForNative = node => { + getFiberForNative = (node: NativeType) => { return renderer.ComponentTree.getClosestInstanceFromNode(node); }; } else if (renderer.Mount.getID && renderer.Mount.getNode) { diff --git a/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js b/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js index 09369dfda4608..b9bfae87a86d3 100644 --- a/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js +++ b/packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js @@ -233,11 +233,16 @@ export default class Overlay { name = elements[0].nodeName.toLowerCase(); const node = elements[0]; - const rendererInterface = this.agent.getBestMatchingRendererInterface(node); + const rendererInterface = this.agent.getBestMatchingRendererInterface( + node, + ); if (rendererInterface) { const id = rendererInterface.getFiberIDForNative(node, true); if (id) { - const ownerName = rendererInterface.getDisplayNameForFiberID(id, true); + const ownerName = rendererInterface.getDisplayNameForFiberID( + id, + true, + ); if (ownerName) { name += ' (in ' + ownerName + ')'; } From 27b6756bf4dec401e2d435400bf486019b494865 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Wed, 8 Jun 2022 09:31:24 -0400 Subject: [PATCH 9/9] re-add try catch for safety --- packages/react-devtools-shared/src/backend/agent.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react-devtools-shared/src/backend/agent.js b/packages/react-devtools-shared/src/backend/agent.js index 1741984c96183..a5bb7139f6161 100644 --- a/packages/react-devtools-shared/src/backend/agent.js +++ b/packages/react-devtools-shared/src/backend/agent.js @@ -332,7 +332,12 @@ export default class Agent extends EventEmitter<{| getIDForNode(node: Object): number | null { const rendererInterface = this.getBestMatchingRendererInterface(node); if (rendererInterface != null) { - return rendererInterface.getFiberIDForNative(node, true); + try { + return rendererInterface.getFiberIDForNative(node, true); + } catch (error) { + // Some old React versions might throw if they can't find a match. + // If so we should ignore it... + } } return null; }