5
import {createRoot} from 'react-dom/client';
6
import Bridge from 'react-devtools-shared/src/bridge';
7
import Store from 'react-devtools-shared/src/devtools/store';
8
-import {getBrowserName, getBrowserTheme} from './utils';
8
+import {IS_CHROME, IS_EDGE, getBrowserTheme} from './utils';
9
import {LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY} from 'react-devtools-shared/src/constants';
10
import {registerDevToolsEventLogger} from 'react-devtools-shared/src/registerDevToolsEventLogger';
11
import {
27
const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY =
28
'React::DevTools::supportsProfiling';
29
30
-const isChrome = getBrowserName() === 'Chrome';
31
-const isEdge = getBrowserName() === 'Edge';
32
-
30
// rAF never fires on devtools_page (because it's in the background)
31
// https://bugs.chromium.org/p/chromium/issues/detail?id=1241986#c31
32
// Since we render React elements here, we need to polyfill it with setTimeout
173
174
store = new Store(bridge, {
175
isProfiling,
179
- supportsReloadAndProfile: isChrome || isEdge,
176
+ supportsReloadAndProfile: IS_CHROME || IS_EDGE,
177
supportsProfiling,
178
// At this time, the timeline can only parse Chrome performance profiles.
182
- supportsTimeline: isChrome,
179
+ supportsTimeline: IS_CHROME,
180
supportsTraceUpdates: true,
181
});
182
if (!isProfiling) {
185
186
// Initialize the backend only once the Store has been initialized.
187
// Otherwise the Store may miss important initial tree op codes.
191
- chrome.devtools.inspectedWindow.eval(
192
- `window.postMessage({ source: 'react-devtools-inject-backend' }, '*');`,
193
- function (response, evalError) {
194
- if (evalError) {
195
- console.error(evalError);
196
- }
197
- },
198
- );
188
+ if (IS_CHROME || IS_EDGE) {
189
+ chrome.runtime.sendMessage({
190
+ source: 'react-devtools-main',
191
+ payload: {
192
+ type: 'react-devtools-inject-backend',
193
+ tabId,
194
+ },
195
+ });
196
+ } else {
197
+ // Firefox does not support executing script in ExecutionWorld.MAIN from content script.
198
+ // see prepareInjection.js
199
+ chrome.devtools.inspectedWindow.eval(
200
+ `window.postMessage({ source: 'react-devtools-inject-backend' }, '*');`,
201
+ function (response, evalError) {
202
+ if (evalError) {
203
+ console.error(evalError);
204
+ }
205
+ },
206
+ );
207
+ }
208
209
const viewAttributeSourceFunction = (id, path) => {
210
const rendererID = store.getRendererIDForElement(id);
264
// For some reason in Firefox, chrome.runtime.sendMessage() from a content script
265
// never reaches the chrome.runtime.onMessage event listener.
266
let fetchFileWithCaching = null;
258
- if (isChrome) {
267
+ if (IS_CHROME) {
268
const fetchFromNetworkCache = (url, resolve, reject) => {
269
// Debug ID allows us to avoid re-logging (potentially long) URL strings below,
270
// while also still associating (potentially) interleaved logs with the original request.
472
let needsToSyncElementSelection = false;
473
474
chrome.devtools.panels.create(
466
- isChrome || isEdge ? '⚛️ Components' : 'Components',
475
+ IS_CHROME || IS_EDGE ? '⚛️ Components' : 'Components',
476
'',
477
'panel.html',
478
extensionPanel => {
503
);
504
505
chrome.devtools.panels.create(
497
- isChrome || isEdge ? '⚛️ Profiler' : 'Profiler',
506
+ IS_CHROME || IS_EDGE ? '⚛️ Profiler' : 'Profiler',
507
'',
508
'panel.html',
509
extensionPanel => {