mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
feat[DebuggingOverlayRegistry]: basic implementation (#41743)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/41743 Changelog: [Internal] There will be a single DebuggingRegistry instance per runtime, which will be responsible for finding lowest AppContainer ancestor for highlighted component. It will receive refs to root views (ancestors, AppContainers) as subscriptions and later will call all necessary methods. In the next series of diffs, subscriber will also provide reference to the DebuggingOverlay, on which DebuggingRegistry can call all necessary methods to highlight elements. Reviewed By: rshest Differential Revision: D51536787 fbshipit-source-id: e89f9d466a7e7833733981ff0d3ce2dbe349aaaa
This commit is contained in:
committed by
Facebook GitHub Bot
parent
c989f63fdb
commit
f8a181883f
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
import type {AppContainerRootViewRef} from '../ReactNative/AppContainer-dev';
|
||||
|
||||
export type DebuggingOverlayRegistrySubscriberProtocol = {
|
||||
rootViewRef: AppContainerRootViewRef,
|
||||
};
|
||||
|
||||
class DebuggingOverlayRegistry {
|
||||
#registry: Set<DebuggingOverlayRegistrySubscriberProtocol> = new Set();
|
||||
|
||||
subscribe(subscriber: DebuggingOverlayRegistrySubscriberProtocol) {
|
||||
this.#registry.add(subscriber);
|
||||
}
|
||||
|
||||
unsubscribe(subscriber: DebuggingOverlayRegistrySubscriberProtocol) {
|
||||
const wasPresent = this.#registry.delete(subscriber);
|
||||
if (!wasPresent) {
|
||||
console.error(
|
||||
'[DebuggingOverlayRegistry] Unexpected argument for unsubscription, which was not previously subscribed:',
|
||||
subscriber,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const debuggingOverlayRegistryInstance: DebuggingOverlayRegistry =
|
||||
new DebuggingOverlayRegistry();
|
||||
export default debuggingOverlayRegistryInstance;
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
import type {AppContainerRootViewRef} from '../ReactNative/AppContainer-dev';
|
||||
|
||||
import DebuggingOverlayRegistry from './DebuggingOverlayRegistry';
|
||||
import {useEffect} from 'react';
|
||||
|
||||
const useSubscribeToDebuggingOverlayRegistry = (
|
||||
rootViewRef: AppContainerRootViewRef,
|
||||
) => {
|
||||
useEffect(() => {
|
||||
const subscriber = {rootViewRef};
|
||||
|
||||
DebuggingOverlayRegistry.subscribe(subscriber);
|
||||
return () => DebuggingOverlayRegistry.unsubscribe(subscriber);
|
||||
}, [rootViewRef]);
|
||||
};
|
||||
|
||||
export default useSubscribeToDebuggingOverlayRegistry;
|
||||
+2
-1
@@ -10,6 +10,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {InspectedViewRef} from '../ReactNative/AppContainer-dev';
|
||||
import type {
|
||||
InspectorData,
|
||||
TouchedViewDataAtPoint,
|
||||
@@ -46,7 +47,7 @@ export type InspectedElement = $ReadOnly<{
|
||||
export type ElementsHierarchy = InspectorData['hierarchy'];
|
||||
|
||||
type Props = {
|
||||
inspectedViewRef: React.RefObject<React.ElementRef<typeof View> | null>,
|
||||
inspectedViewRef: InspectedViewRef,
|
||||
onRequestRerenderApp: () => void,
|
||||
reactDevToolsAgent?: ReactDevToolsAgent,
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {InspectedViewRef} from '../ReactNative/AppContainer-dev';
|
||||
import type {PointerEvent} from '../Types/CoreEventTypes';
|
||||
import type {PressEvent} from '../Types/CoreEventTypes';
|
||||
import type {
|
||||
@@ -29,7 +30,7 @@ const getInspectorDataForViewAtPoint = require('./getInspectorDataForViewAtPoint
|
||||
const {useEffect, useState, useCallback} = React;
|
||||
|
||||
type Props = {
|
||||
inspectedViewRef: React.RefObject<React.ElementRef<typeof View> | null>,
|
||||
inspectedViewRef: InspectedViewRef,
|
||||
reactDevToolsAgent: ReactDevToolsAgent,
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import type {Props} from './AppContainer';
|
||||
import TraceUpdateOverlay from '../Components/TraceUpdateOverlay/TraceUpdateOverlay';
|
||||
import ReactNativeStyleAttributes from '../Components/View/ReactNativeStyleAttributes';
|
||||
import View from '../Components/View/View';
|
||||
import useSubscribeToDebuggingOverlayRegistry from '../Debugging/useSubscribeToDebuggingOverlayRegistry';
|
||||
import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter';
|
||||
import ReactDevToolsOverlay from '../Inspector/ReactDevToolsOverlay';
|
||||
import LogBoxNotificationContainer from '../LogBox/LogBoxNotificationContainer';
|
||||
@@ -40,7 +41,7 @@ if (reactDevToolsHook) {
|
||||
}
|
||||
|
||||
type InspectorDeferredProps = {
|
||||
inspectedViewRef: React.RefObject<React.ElementRef<typeof View> | null>,
|
||||
inspectedViewRef: InspectedViewRef,
|
||||
onInspectedViewRerenderRequest: () => void,
|
||||
reactDevToolsAgent?: ReactDevToolsAgent,
|
||||
};
|
||||
@@ -73,7 +74,9 @@ const AppContainer = ({
|
||||
showArchitectureIndicator,
|
||||
WrapperComponent,
|
||||
}: Props): React.Node => {
|
||||
const innerViewRef = React.useRef<React.ElementRef<typeof View> | null>(null);
|
||||
const appContainerRootViewRef: AppContainerRootViewRef = React.useRef(null);
|
||||
const innerViewRef: InspectedViewRef = React.useRef(null);
|
||||
useSubscribeToDebuggingOverlayRegistry(appContainerRootViewRef);
|
||||
|
||||
const [key, setKey] = useState(0);
|
||||
const [shouldRenderInspector, setShouldRenderInspector] = useState(false);
|
||||
@@ -138,7 +141,10 @@ const AppContainer = ({
|
||||
|
||||
return (
|
||||
<RootTagContext.Provider value={createRootTag(rootTag)}>
|
||||
<View style={styles.container} pointerEvents="box-none">
|
||||
<View
|
||||
ref={appContainerRootViewRef}
|
||||
style={styles.container}
|
||||
pointerEvents="box-none">
|
||||
{innerView}
|
||||
|
||||
{reactDevToolsAgent != null && (
|
||||
@@ -169,4 +175,10 @@ const styles = StyleSheet.create({
|
||||
container: {flex: 1},
|
||||
});
|
||||
|
||||
export type AppContainerRootViewRef = React.RefObject<React.ElementRef<
|
||||
typeof View,
|
||||
> | null>;
|
||||
export type InspectedViewRef = React.RefObject<React.ElementRef<
|
||||
typeof View,
|
||||
> | null>;
|
||||
export default AppContainer;
|
||||
|
||||
@@ -4777,6 +4777,27 @@ declare export default HostComponent<NativeProps>;
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Debugging/DebuggingOverlayRegistry.js 1`] = `
|
||||
"export type DebuggingOverlayRegistrySubscriberProtocol = {
|
||||
rootViewRef: AppContainerRootViewRef,
|
||||
};
|
||||
declare class DebuggingOverlayRegistry {
|
||||
subscribe(subscriber: DebuggingOverlayRegistrySubscriberProtocol): void;
|
||||
unsubscribe(subscriber: DebuggingOverlayRegistrySubscriberProtocol): void;
|
||||
}
|
||||
declare const debuggingOverlayRegistryInstance: DebuggingOverlayRegistry;
|
||||
declare export default typeof debuggingOverlayRegistryInstance;
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Debugging/useSubscribeToDebuggingOverlayRegistry.js 1`] = `
|
||||
"declare const useSubscribeToDebuggingOverlayRegistry: (
|
||||
rootViewRef: AppContainerRootViewRef
|
||||
) => void;
|
||||
declare export default typeof useSubscribeToDebuggingOverlayRegistry;
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/DevToolsSettings/DevToolsSettingsManager.android.js 1`] = `
|
||||
"declare module.exports: {
|
||||
setConsolePatchSettings(newSettings: string): void,
|
||||
@@ -5406,8 +5427,7 @@ declare module.exports: resolveAssetSource;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Inspector/Inspector.js 1`] = `
|
||||
"declare const View: $FlowFixMe;
|
||||
declare const React: $FlowFixMe;
|
||||
"declare const React: $FlowFixMe;
|
||||
export type InspectedElementFrame = TouchedViewDataAtPoint[\\"frame\\"];
|
||||
export type InspectedElementSource = InspectorData[\\"source\\"];
|
||||
export type InspectedElement = $ReadOnly<{
|
||||
@@ -5417,7 +5437,7 @@ export type InspectedElement = $ReadOnly<{
|
||||
}>;
|
||||
export type ElementsHierarchy = InspectorData[\\"hierarchy\\"];
|
||||
type Props = {
|
||||
inspectedViewRef: React.RefObject<React.ElementRef<typeof View> | null>,
|
||||
inspectedViewRef: InspectedViewRef,
|
||||
onRequestRerenderApp: () => void,
|
||||
reactDevToolsAgent?: ReactDevToolsAgent,
|
||||
};
|
||||
@@ -5439,7 +5459,7 @@ declare module.exports: InspectorOverlay;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Inspector/ReactDevToolsOverlay.js 1`] = `
|
||||
"type Props = {
|
||||
inspectedViewRef: React.RefObject<React.ElementRef<typeof View> | null>,
|
||||
inspectedViewRef: InspectedViewRef,
|
||||
reactDevToolsAgent: ReactDevToolsAgent,
|
||||
};
|
||||
declare export default function ReactDevToolsOverlay(Props): React.Node;
|
||||
@@ -7520,6 +7540,12 @@ declare module.exports: AppContainer;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/ReactNative/AppContainer-dev.js 1`] = `
|
||||
"declare const AppContainer: (Props) => React.Node;
|
||||
export type AppContainerRootViewRef = React.RefObject<React.ElementRef<
|
||||
typeof View,
|
||||
> | null>;
|
||||
export type InspectedViewRef = React.RefObject<React.ElementRef<
|
||||
typeof View,
|
||||
> | null>;
|
||||
declare export default typeof AppContainer;
|
||||
"
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user