Skip to content

Commit 930c9e7

Browse files
author
Juan
authored
Show warning in UI when duplicate installations of DevTools extension are detected (facebook#22563)
1 parent 9d3d030 commit 930c9e7

File tree

6 files changed

+115
-13
lines changed

6 files changed

+115
-13
lines changed

packages/react-devtools-extensions/src/background.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
/* global chrome */
1+
// @flow strict-local
22

33
'use strict';
44

5-
const ports = {};
5+
declare var chrome: any;
6+
7+
const ports: {
8+
[tab: string]: {|devtools: any, 'content-script': any|},
9+
} = {};
610

711
const IS_FIREFOX = navigator.userAgent.indexOf('Firefox') >= 0;
812

9-
import {EXTENSION_INSTALL_CHECK_MESSAGE} from './constants';
13+
import {
14+
EXTENSION_INSTALL_CHECK,
15+
SHOW_DUPLICATE_EXTENSION_WARNING,
16+
} from './constants';
1017

1118
chrome.runtime.onConnect.addListener(function(port) {
1219
let tab = null;
@@ -120,8 +127,9 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
120127

121128
chrome.runtime.onMessageExternal.addListener(
122129
(request, sender, sendResponse) => {
123-
if (request === EXTENSION_INSTALL_CHECK_MESSAGE) {
130+
if (request === EXTENSION_INSTALL_CHECK) {
124131
sendResponse(true);
132+
chrome.runtime.sendMessage(SHOW_DUPLICATE_EXTENSION_WARNING);
125133
}
126134
},
127135
);

packages/react-devtools-extensions/src/checkForDuplicateInstallations.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ declare var chrome: any;
1111

1212
import {__DEBUG__} from 'react-devtools-shared/src/constants';
1313
import {
14-
EXTENSION_INSTALL_CHECK_MESSAGE,
14+
EXTENSION_INSTALL_CHECK,
1515
EXTENSION_INSTALLATION_TYPE,
1616
INTERNAL_EXTENSION_ID,
1717
LOCAL_EXTENSION_ID,
1818
} from './constants';
1919

20-
const UNRECOGNIZED_EXTENSION_WARNING =
20+
const UNRECOGNIZED_EXTENSION_ERROR =
2121
'React Developer Tools: You are running an unrecognized installation of the React Developer Tools extension, which might conflict with other versions of the extension installed in your browser. ' +
2222
'Please make sure you only have a single version of the extension installed or enabled. ' +
2323
'If you are developing this extension locally, make sure to build the extension using the `yarn build:<browser>:local` command.';
@@ -68,9 +68,9 @@ export function checkForDuplicateInstallations(callback: boolean => void) {
6868
// detect if there are other installations of DevTools present.
6969
// In this case, assume there are no duplicate exensions and show a warning about
7070
// potential conflicts.
71-
console.error(UNRECOGNIZED_EXTENSION_WARNING);
71+
console.error(UNRECOGNIZED_EXTENSION_ERROR);
7272
chrome.devtools.inspectedWindow.eval(
73-
`console.error("${UNRECOGNIZED_EXTENSION_WARNING}")`,
73+
`console.error("${UNRECOGNIZED_EXTENSION_ERROR}")`,
7474
);
7575
callback(false);
7676
break;
@@ -80,9 +80,9 @@ export function checkForDuplicateInstallations(callback: boolean => void) {
8080
// are other installations of DevTools present.
8181
// In this case, assume there are no duplicate exensions and show a warning about
8282
// potential conflicts.
83-
console.error(UNRECOGNIZED_EXTENSION_WARNING);
83+
console.error(UNRECOGNIZED_EXTENSION_ERROR);
8484
chrome.devtools.inspectedWindow.eval(
85-
`console.error("${UNRECOGNIZED_EXTENSION_WARNING}")`,
85+
`console.error("${UNRECOGNIZED_EXTENSION_ERROR}")`,
8686
);
8787
callback(false);
8888
break;
@@ -105,7 +105,7 @@ function checkForInstalledExtension(extensionId: string): Promise<boolean> {
105105
return new Promise(resolve => {
106106
chrome.runtime.sendMessage(
107107
extensionId,
108-
EXTENSION_INSTALL_CHECK_MESSAGE,
108+
EXTENSION_INSTALL_CHECK,
109109
response => {
110110
if (__DEBUG__) {
111111
console.log(

packages/react-devtools-extensions/src/constants.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ declare var chrome: any;
1111

1212
export const CURRENT_EXTENSION_ID = chrome.runtime.id;
1313

14-
export const EXTENSION_INSTALL_CHECK_MESSAGE = 'extension-install-check';
14+
export const EXTENSION_INSTALL_CHECK = 'extension-install-check';
15+
export const SHOW_DUPLICATE_EXTENSION_WARNING =
16+
'show-duplicate-extension-warning';
1517

1618
export const CHROME_WEBSTORE_EXTENSION_ID = 'fmkadmapgofadopljbjfkapdkoienihi';
1719
export const INTERNAL_EXTENSION_ID = 'dnjnjgbfilfphmojnmhliehogmojhclc';

packages/react-devtools-extensions/src/main.js

+34-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ import {
2222
import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
2323
import {__DEBUG__} from 'react-devtools-shared/src/constants';
2424
import {logEvent} from 'react-devtools-shared/src/Logger';
25-
import {CURRENT_EXTENSION_ID, EXTENSION_INSTALLATION_TYPE} from './constants';
25+
import {
26+
CURRENT_EXTENSION_ID,
27+
EXTENSION_INSTALLATION_TYPE,
28+
SHOW_DUPLICATE_EXTENSION_WARNING,
29+
} from './constants';
2630
import {checkForDuplicateInstallations} from './checkForDuplicateInstallations';
2731

2832
const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY =
@@ -108,11 +112,39 @@ function createPanelIfReactLoaded() {
108112
let mostRecentOverrideTab = null;
109113
let render = null;
110114
let root = null;
115+
let warnIfDuplicateInstallation = false;
111116

112117
const tabId = chrome.devtools.inspectedWindow.tabId;
113118

114119
registerDevToolsEventLogger('extension');
115120

121+
function onDuplicateExtensionMessage(message) {
122+
if (message === SHOW_DUPLICATE_EXTENSION_WARNING) {
123+
chrome.runtime.onMessage.removeListener(
124+
onDuplicateExtensionMessage,
125+
);
126+
127+
if (warnIfDuplicateInstallation === true) {
128+
return;
129+
}
130+
warnIfDuplicateInstallation = true;
131+
const errorMessage =
132+
'React Developer Tools: We detected that there are multiple versions of React Developer Tools ' +
133+
'installed and enabled in your browser at the same time, which will cause ' +
134+
'issues while using the extension. ' +
135+
'Please ensure that you have installed and enabled only a single ' +
136+
'version of React Developer Tools before proceeding.';
137+
console.error(errorMessage);
138+
chrome.devtools.inspectedWindow.eval(
139+
`console.error("${errorMessage}")`,
140+
);
141+
if (render != null) {
142+
render();
143+
}
144+
}
145+
}
146+
chrome.runtime.onMessage.addListener(onDuplicateExtensionMessage);
147+
116148
function initBridgeAndStore() {
117149
const port = chrome.runtime.connect({
118150
name: String(tabId),
@@ -374,6 +406,7 @@ function createPanelIfReactLoaded() {
374406
hookNamesModuleLoaderFunction,
375407
overrideTab,
376408
profilerPortalContainer,
409+
warnIfDuplicateInstallation,
377410
showTabBar: false,
378411
store,
379412
warnIfUnsupportedVersionDetected: true,

packages/react-devtools-shared/src/devtools/views/DevTools.js

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {SchedulingProfilerContextController} from 'react-devtools-scheduling-pro
3434
import {ModalDialogContextController} from './ModalDialog';
3535
import ReactLogo from './ReactLogo';
3636
import UnsupportedBridgeProtocolDialog from './UnsupportedBridgeProtocolDialog';
37+
import DuplicateInstallationDialog from './DuplicateInstallationDialog';
3738
import UnsupportedVersionDialog from './UnsupportedVersionDialog';
3839
import WarnIfLegacyBackendDetected from './WarnIfLegacyBackendDetected';
3940
import {useLocalStorage} from './hooks';
@@ -73,6 +74,7 @@ export type Props = {|
7374
enabledInspectedElementContextMenu?: boolean,
7475
showTabBar?: boolean,
7576
store: Store,
77+
warnIfDuplicateInstallation?: boolean,
7678
warnIfLegacyBackendDetected?: boolean,
7779
warnIfUnsupportedVersionDetected?: boolean,
7880
viewAttributeSourceFunction?: ?ViewAttributeSource,
@@ -132,6 +134,7 @@ export default function DevTools({
132134
profilerPortalContainer,
133135
showTabBar = false,
134136
store,
137+
warnIfDuplicateInstallation = false,
135138
warnIfLegacyBackendDetected = false,
136139
warnIfUnsupportedVersionDetected = false,
137140
viewAttributeSourceFunction,
@@ -319,6 +322,7 @@ export default function DevTools({
319322
</ViewElementSourceContext.Provider>
320323
</SettingsContextController>
321324
<UnsupportedBridgeProtocolDialog />
325+
{warnIfDuplicateInstallation && <DuplicateInstallationDialog />}
322326
{warnIfLegacyBackendDetected && <WarnIfLegacyBackendDetected />}
323327
{warnIfUnsupportedVersionDetected && <UnsupportedVersionDialog />}
324328
</ModalDialogContextController>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
*/
9+
10+
import * as React from 'react';
11+
import {Fragment, useContext, useEffect} from 'react';
12+
import {isInternalFacebookBuild} from 'react-devtools-feature-flags';
13+
import {ModalDialogContext} from './ModalDialog';
14+
15+
export default function DuplicateInstallationDialog(_: {||}) {
16+
const {dispatch} = useContext(ModalDialogContext);
17+
18+
useEffect(() => {
19+
dispatch({
20+
canBeDismissed: false,
21+
id: 'DuplicateInstallationDialog',
22+
type: 'SHOW',
23+
title: 'Duplicate Installations of DevTools Detected',
24+
content: <DialogContent />,
25+
});
26+
}, []);
27+
return null;
28+
}
29+
30+
function DialogContent(_: {||}) {
31+
return (
32+
<Fragment>
33+
<p>
34+
We detected that there are multiple versions of React Developer Tools
35+
installed and enabled in your browser at the same time, which will cause
36+
issues while using the extension.
37+
</p>
38+
{isInternalFacebookBuild ? (
39+
<p>
40+
Before proceeding, please ensure that the only enabled version of
41+
React Developer Tools is the internal (Chef-installed) version. To
42+
manage your extensions, visit the <code>about://extensions</code> page
43+
in your browser.
44+
</p>
45+
) : (
46+
<p>
47+
Please ensure that you have installed and enabled only a single
48+
version of React Developer Tools before proceeding. To manage your
49+
extensions, visit the <code>about://extensions</code> page in your
50+
browser.
51+
</p>
52+
)}
53+
</Fragment>
54+
);
55+
}

0 commit comments

Comments
 (0)