@@ -5,8 +5,9 @@ import {createRoot} from 'react-dom/client';
55import {
66 activate as activateBackend ,
77 initialize as initializeBackend ,
8+ attach ,
89} from 'react-devtools-inline/backend' ;
9- import { initialize as initializeFrontend } from 'react-devtools-inline/frontend' ;
10+ import { initialize as initializeFrontend , createBridge , createStore } from 'react-devtools-inline/frontend' ;
1011import { initDevTools } from 'react-devtools-shared/src/devtools' ;
1112
1213// This is a pretty gross hack to make the runtime loaded named-hooks-code work.
@@ -16,20 +17,7 @@ __webpack_public_path__ = '/dist/'; // eslint-disable-line no-undef
1617
1718const iframe = ( ( document . getElementById ( 'target' ) : any ) : HTMLIFrameElement ) ;
1819
19- const { contentDocument, contentWindow} = iframe ;
20-
21- // Helps with positioning Overlay UI.
22- contentWindow . __REACT_DEVTOOLS_TARGET_WINDOW__ = window ;
23-
24- initializeBackend ( contentWindow ) ;
25-
26- // Initialize the front end and activate the backend early so that we are able
27- // to pass console settings in local storage to the backend before initial render
28- const DevTools = initializeFrontend ( contentWindow ) ;
29-
30- // Activate the backend only once the DevTools frontend Store has been initialized.
31- // Otherwise the Store may miss important initial tree op codes.
32- activateBackend ( contentWindow ) ;
20+ let { contentDocument, contentWindow} = iframe ;
3321
3422const container = ( ( document . getElementById ( 'devtools' ) : any ) : HTMLElement ) ;
3523
@@ -59,27 +47,83 @@ function hookNamesModuleLoaderFunction() {
5947 return import ( 'react-devtools-inline/hookNames' ) ;
6048}
6149
62- inject ( 'dist/app-index.js' , ( ) => {
63- initDevTools ( {
64- connect ( cb ) {
65- const root = createRoot ( container ) ;
66- root . render (
67- createElement ( DevTools , {
68- browserTheme : 'light' ,
69- enabledInspectedElementContextMenu : true ,
70- hookNamesModuleLoaderFunction,
71- showTabBar : true ,
72- warnIfLegacyBackendDetected : true ,
73- warnIfUnsupportedVersionDetected : true ,
74- } ) ,
75- ) ;
76- } ,
77-
78- onReload ( reloadFn ) {
79- iframe . onload = reloadFn ;
80- } ,
50+ let store
51+ let profilingData
52+ let controller = new AbortController ( ) ;
53+ const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY = 'React::DevTools::supportsProfiling'
54+ function render ( signal : AbortSignal ) {
55+ ( { contentDocument, contentWindow} = iframe ) ;
56+
57+ const bridge = createBridge ( contentWindow )
58+ bridge . addListener ( 'reloadAppForProfiling' , ( ) => {
59+ localStorage . setItem ( LOCAL_STORAGE_SUPPORTS_PROFILING_KEY , 'true' )
60+ contentWindow . sessionStorage . setItem ( 'React::DevTools::reloadAndProfile' , 'true' )
61+ contentWindow . sessionStorage . setItem ( 'React::DevTools::recordChangeDescriptions' , 'true' )
62+ contentWindow . location . reload ( ) ;
63+ iframe . addEventListener ( 'load' , ( ) => {
64+ contentWindow . __REACT_DEVTOOLS_ATTACH__ = attach ;
65+ controller . abort ( ) ;
66+ controller = new AbortController ( ) ;
67+ render ( controller . signal ) ;
68+ } , { once : true } ) ;
69+ } )
70+ let isProfiling = false
71+ // reload and profile
72+ {
73+ if ( localStorage . getItem ( LOCAL_STORAGE_SUPPORTS_PROFILING_KEY ) === "true" ) {
74+ isProfiling = true
75+ if ( store ) profilingData = store . profilerStore . profilingData
76+ localStorage . removeItem ( LOCAL_STORAGE_SUPPORTS_PROFILING_KEY )
77+ }
78+ }
79+ store = createStore ( bridge , {
80+ isProfiling,
81+ supportsReloadAndProfile : true ,
82+ supportsProfiling : true ,
83+ supportsTimeline : true ,
84+ supportsTraceUpdates : true ,
85+ supportsNativeInspection : true ,
86+ } )
87+ if ( ! isProfiling && profilingData ) store . profilerStore . profilingData = profilingData
88+
89+ // Helps with positioning Overlay UI.
90+ contentWindow . __REACT_DEVTOOLS_TARGET_WINDOW__ = window ;
91+
92+ initializeBackend ( contentWindow ) ;
93+
94+ // Initialize the front end and activate the backend early so that we are able
95+ // to pass console settings in local storage to the backend before initial render
96+ const DevTools = initializeFrontend ( contentWindow , { bridge, store} ) ;
97+
98+ // Activate the backend only once the DevTools frontend Store has been initialized.
99+ // Otherwise the Store may miss important initial tree op codes.
100+ activateBackend ( contentWindow ) ;
101+
102+ inject ( 'dist/app-index.js' , ( ) => {
103+ initDevTools ( {
104+ connect ( cb ) {
105+ const root = createRoot ( container ) ;
106+ root . render (
107+ createElement ( DevTools , {
108+ browserTheme : 'light' ,
109+ enabledInspectedElementContextMenu : true ,
110+ hookNamesModuleLoaderFunction,
111+ showTabBar : true ,
112+ warnIfLegacyBackendDetected : true ,
113+ warnIfUnsupportedVersionDetected : true ,
114+ } ) ,
115+ ) ;
116+ signal . addEventListener ( 'abort' , ( ) => root . unmount ( ) , { once : true } )
117+ } ,
118+
119+ onReload ( reloadFn ) {
120+ iframe . onload = reloadFn ;
121+ } ,
122+ } ) ;
81123 } ) ;
82- } ) ;
124+
125+ }
126+ render ( controller . signal ) ;
83127
84128function inject ( sourcePath : string , callback : ( ) = > void ) {
85129 const script = contentDocument . createElement ( 'script' ) ;
0 commit comments