Repository: facebook/react
Pull request: [DevTools] Expose "view source" options to Fusebox integration

## Summary

Exposes the APIs needed by React Native DevTools (Fusebox) to implement the "view element source" and "view attribute source" features.

## How did you test this change?

1. `yarn build` in `react-devtools-fusebox`
2. Copy artifacts to rn-chrome-devtools-frontend
3. Write some additional glue code to implement `viewElementSourceFunction` in our CDT fork.
4. Test the feature manually.

https://github.com/facebook/react/assets/2246565/12667018-100a-4b3f-957a-06c07f2af41a


Changed files:
filename: packages/react-devtools-fusebox/src/frontend.d.ts
patch: @@ -5,36 +5,49 @@
  * LICENSE file in the root directory of this source tree.
  */
 
-export type MessagePayload =
-  | null
-  | string
-  | number
-  | boolean
-  | {[key: string]: MessagePayload}
-  | MessagePayload[];
-export type Message = {event: string; payload?: MessagePayload};
+export type MessagePayload = null | string | number | boolean | { [key: string]: MessagePayload } | MessagePayload[];
+export type Message = { event: string, payload?: MessagePayload };
 
 export type WallListener = (message: Message) => void;
 export type Wall = {
-  listen: (fn: WallListener) => Function;
-  send: (event: string, payload?: MessagePayload) => void;
+  listen: (fn: WallListener) => Function,
+  send: (event: string, payload?: MessagePayload) => void,
 };
 
 export type Bridge = {
-  shutdown: () => void;
+  shutdown: () => void,
 };
 export type Store = Object;
 export type BrowserTheme = 'dark' | 'light';
 
 export function createBridge(wall: Wall): Bridge;
 export function createStore(bridge: Bridge): Store;
 
+export type Source = {
+  sourceURL: string,
+  line: number,
+  column: number,
+};
+export type ViewElementSource = (
+  source: Source,
+  symbolicatedSource: Source | null,
+) => void;
+export type ViewAttributeSource = (
+  id: number,
+  path: Array<string | number>,
+) => void;
+export type CanViewElementSource = (
+  source: Source,
+  symbolicatedSource: Source | null,
+) => boolean;
+
 export type InitializationOptions = {
-  bridge: Bridge;
-  store: Store;
-  theme?: BrowserTheme;
+  bridge: Bridge,
+  store: Store,
+  theme?: BrowserTheme,
+  viewAttributeSourceFunction?: ViewAttributeSource,
+  viewElementSourceFunction?: ViewElementSource,
+  canViewElementSourceFunction?: CanViewElementSource,
 };
-export function initialize(
-  node: Element | Document,
-  options: InitializationOptions,
-): void;
+
+export function initialize(node: Element | Document, options: InitializationOptions): void;

filename: packages/react-devtools-fusebox/src/frontend.js
patch: @@ -18,6 +18,11 @@ import type {
   Wall,
 } from 'react-devtools-shared/src/frontend/types';
 import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
+import type {
+  ViewAttributeSource,
+  ViewElementSource,
+  CanViewElementSource,
+} from 'react-devtools-shared/src/devtools/views/DevTools';
 
 type Config = {
   checkBridgeProtocolCompatibility?: boolean,
@@ -46,13 +51,23 @@ type InitializationOptions = {
   bridge: FrontendBridge,
   store: Store,
   theme?: BrowserTheme,
+  viewAttributeSourceFunction?: ViewAttributeSource,
+  viewElementSourceFunction?: ViewElementSource,
+  canViewElementSourceFunction?: CanViewElementSource,
 };
 
 export function initialize(
   contentWindow: Element | Document,
   options: InitializationOptions,
 ): void {
-  const {bridge, store, theme = 'light'} = options;
+  const {
+    bridge,
+    store,
+    theme = 'light',
+    viewAttributeSourceFunction,
+    viewElementSourceFunction,
+    canViewElementSourceFunction,
+  } = options;
   const root = createRoot(contentWindow);
 
   root.render(
@@ -63,6 +78,9 @@ export function initialize(
       showTabBar={true}
       warnIfLegacyBackendDetected={true}
       enabledInspectedElementContextMenu={true}
+      viewAttributeSourceFunction={viewAttributeSourceFunction}
+      viewElementSourceFunction={viewElementSourceFunction}
+      canViewElementSourceFunction={canViewElementSourceFunction}
     />,
   );
 }