Skip to content

Commit e8760d1

Browse files
committed
docs: add reload-and-profile to shell
1 parent 57c0a55 commit e8760d1

File tree

1 file changed

+79
-35
lines changed

1 file changed

+79
-35
lines changed

packages/react-devtools-shell/src/app/devtools.js

Lines changed: 79 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import {createRoot} from 'react-dom/client';
55
import {
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';
1011
import {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

1718
const 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

3422
const 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

84128
function inject(sourcePath: string, callback: () => void) {
85129
const script = contentDocument.createElement('script');

0 commit comments

Comments
 (0)