mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Show warning in UI when duplicate installations of DevTools extension are detected (#22563)
This commit is contained in:
+12
-4
@@ -1,12 +1,19 @@
|
||||
/* global chrome */
|
||||
// @flow strict-local
|
||||
|
||||
'use strict';
|
||||
|
||||
const ports = {};
|
||||
declare var chrome: any;
|
||||
|
||||
const ports: {
|
||||
[tab: string]: {|devtools: any, 'content-script': any|},
|
||||
} = {};
|
||||
|
||||
const IS_FIREFOX = navigator.userAgent.indexOf('Firefox') >= 0;
|
||||
|
||||
import {EXTENSION_INSTALL_CHECK_MESSAGE} from './constants';
|
||||
import {
|
||||
EXTENSION_INSTALL_CHECK,
|
||||
SHOW_DUPLICATE_EXTENSION_WARNING,
|
||||
} from './constants';
|
||||
|
||||
chrome.runtime.onConnect.addListener(function(port) {
|
||||
let tab = null;
|
||||
@@ -120,8 +127,9 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||
|
||||
chrome.runtime.onMessageExternal.addListener(
|
||||
(request, sender, sendResponse) => {
|
||||
if (request === EXTENSION_INSTALL_CHECK_MESSAGE) {
|
||||
if (request === EXTENSION_INSTALL_CHECK) {
|
||||
sendResponse(true);
|
||||
chrome.runtime.sendMessage(SHOW_DUPLICATE_EXTENSION_WARNING);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -11,13 +11,13 @@ declare var chrome: any;
|
||||
|
||||
import {__DEBUG__} from 'react-devtools-shared/src/constants';
|
||||
import {
|
||||
EXTENSION_INSTALL_CHECK_MESSAGE,
|
||||
EXTENSION_INSTALL_CHECK,
|
||||
EXTENSION_INSTALLATION_TYPE,
|
||||
INTERNAL_EXTENSION_ID,
|
||||
LOCAL_EXTENSION_ID,
|
||||
} from './constants';
|
||||
|
||||
const UNRECOGNIZED_EXTENSION_WARNING =
|
||||
const UNRECOGNIZED_EXTENSION_ERROR =
|
||||
'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. ' +
|
||||
'Please make sure you only have a single version of the extension installed or enabled. ' +
|
||||
'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) {
|
||||
// detect if there are other installations of DevTools present.
|
||||
// In this case, assume there are no duplicate exensions and show a warning about
|
||||
// potential conflicts.
|
||||
console.error(UNRECOGNIZED_EXTENSION_WARNING);
|
||||
console.error(UNRECOGNIZED_EXTENSION_ERROR);
|
||||
chrome.devtools.inspectedWindow.eval(
|
||||
`console.error("${UNRECOGNIZED_EXTENSION_WARNING}")`,
|
||||
`console.error("${UNRECOGNIZED_EXTENSION_ERROR}")`,
|
||||
);
|
||||
callback(false);
|
||||
break;
|
||||
@@ -80,9 +80,9 @@ export function checkForDuplicateInstallations(callback: boolean => void) {
|
||||
// are other installations of DevTools present.
|
||||
// In this case, assume there are no duplicate exensions and show a warning about
|
||||
// potential conflicts.
|
||||
console.error(UNRECOGNIZED_EXTENSION_WARNING);
|
||||
console.error(UNRECOGNIZED_EXTENSION_ERROR);
|
||||
chrome.devtools.inspectedWindow.eval(
|
||||
`console.error("${UNRECOGNIZED_EXTENSION_WARNING}")`,
|
||||
`console.error("${UNRECOGNIZED_EXTENSION_ERROR}")`,
|
||||
);
|
||||
callback(false);
|
||||
break;
|
||||
@@ -105,7 +105,7 @@ function checkForInstalledExtension(extensionId: string): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
chrome.runtime.sendMessage(
|
||||
extensionId,
|
||||
EXTENSION_INSTALL_CHECK_MESSAGE,
|
||||
EXTENSION_INSTALL_CHECK,
|
||||
response => {
|
||||
if (__DEBUG__) {
|
||||
console.log(
|
||||
|
||||
+3
-1
@@ -11,7 +11,9 @@ declare var chrome: any;
|
||||
|
||||
export const CURRENT_EXTENSION_ID = chrome.runtime.id;
|
||||
|
||||
export const EXTENSION_INSTALL_CHECK_MESSAGE = 'extension-install-check';
|
||||
export const EXTENSION_INSTALL_CHECK = 'extension-install-check';
|
||||
export const SHOW_DUPLICATE_EXTENSION_WARNING =
|
||||
'show-duplicate-extension-warning';
|
||||
|
||||
export const CHROME_WEBSTORE_EXTENSION_ID = 'fmkadmapgofadopljbjfkapdkoienihi';
|
||||
export const INTERNAL_EXTENSION_ID = 'dnjnjgbfilfphmojnmhliehogmojhclc';
|
||||
|
||||
+34
-1
@@ -22,7 +22,11 @@ import {
|
||||
import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
|
||||
import {__DEBUG__} from 'react-devtools-shared/src/constants';
|
||||
import {logEvent} from 'react-devtools-shared/src/Logger';
|
||||
import {CURRENT_EXTENSION_ID, EXTENSION_INSTALLATION_TYPE} from './constants';
|
||||
import {
|
||||
CURRENT_EXTENSION_ID,
|
||||
EXTENSION_INSTALLATION_TYPE,
|
||||
SHOW_DUPLICATE_EXTENSION_WARNING,
|
||||
} from './constants';
|
||||
import {checkForDuplicateInstallations} from './checkForDuplicateInstallations';
|
||||
|
||||
const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY =
|
||||
@@ -108,11 +112,39 @@ function createPanelIfReactLoaded() {
|
||||
let mostRecentOverrideTab = null;
|
||||
let render = null;
|
||||
let root = null;
|
||||
let warnIfDuplicateInstallation = false;
|
||||
|
||||
const tabId = chrome.devtools.inspectedWindow.tabId;
|
||||
|
||||
registerDevToolsEventLogger('extension');
|
||||
|
||||
function onDuplicateExtensionMessage(message) {
|
||||
if (message === SHOW_DUPLICATE_EXTENSION_WARNING) {
|
||||
chrome.runtime.onMessage.removeListener(
|
||||
onDuplicateExtensionMessage,
|
||||
);
|
||||
|
||||
if (warnIfDuplicateInstallation === true) {
|
||||
return;
|
||||
}
|
||||
warnIfDuplicateInstallation = true;
|
||||
const errorMessage =
|
||||
'React Developer Tools: We detected that there are multiple versions of React Developer Tools ' +
|
||||
'installed and enabled in your browser at the same time, which will cause ' +
|
||||
'issues while using the extension. ' +
|
||||
'Please ensure that you have installed and enabled only a single ' +
|
||||
'version of React Developer Tools before proceeding.';
|
||||
console.error(errorMessage);
|
||||
chrome.devtools.inspectedWindow.eval(
|
||||
`console.error("${errorMessage}")`,
|
||||
);
|
||||
if (render != null) {
|
||||
render();
|
||||
}
|
||||
}
|
||||
}
|
||||
chrome.runtime.onMessage.addListener(onDuplicateExtensionMessage);
|
||||
|
||||
function initBridgeAndStore() {
|
||||
const port = chrome.runtime.connect({
|
||||
name: String(tabId),
|
||||
@@ -374,6 +406,7 @@ function createPanelIfReactLoaded() {
|
||||
hookNamesModuleLoaderFunction,
|
||||
overrideTab,
|
||||
profilerPortalContainer,
|
||||
warnIfDuplicateInstallation,
|
||||
showTabBar: false,
|
||||
store,
|
||||
warnIfUnsupportedVersionDetected: true,
|
||||
|
||||
@@ -34,6 +34,7 @@ import {SchedulingProfilerContextController} from 'react-devtools-scheduling-pro
|
||||
import {ModalDialogContextController} from './ModalDialog';
|
||||
import ReactLogo from './ReactLogo';
|
||||
import UnsupportedBridgeProtocolDialog from './UnsupportedBridgeProtocolDialog';
|
||||
import DuplicateInstallationDialog from './DuplicateInstallationDialog';
|
||||
import UnsupportedVersionDialog from './UnsupportedVersionDialog';
|
||||
import WarnIfLegacyBackendDetected from './WarnIfLegacyBackendDetected';
|
||||
import {useLocalStorage} from './hooks';
|
||||
@@ -73,6 +74,7 @@ export type Props = {|
|
||||
enabledInspectedElementContextMenu?: boolean,
|
||||
showTabBar?: boolean,
|
||||
store: Store,
|
||||
warnIfDuplicateInstallation?: boolean,
|
||||
warnIfLegacyBackendDetected?: boolean,
|
||||
warnIfUnsupportedVersionDetected?: boolean,
|
||||
viewAttributeSourceFunction?: ?ViewAttributeSource,
|
||||
@@ -132,6 +134,7 @@ export default function DevTools({
|
||||
profilerPortalContainer,
|
||||
showTabBar = false,
|
||||
store,
|
||||
warnIfDuplicateInstallation = false,
|
||||
warnIfLegacyBackendDetected = false,
|
||||
warnIfUnsupportedVersionDetected = false,
|
||||
viewAttributeSourceFunction,
|
||||
@@ -319,6 +322,7 @@ export default function DevTools({
|
||||
</ViewElementSourceContext.Provider>
|
||||
</SettingsContextController>
|
||||
<UnsupportedBridgeProtocolDialog />
|
||||
{warnIfDuplicateInstallation && <DuplicateInstallationDialog />}
|
||||
{warnIfLegacyBackendDetected && <WarnIfLegacyBackendDetected />}
|
||||
{warnIfUnsupportedVersionDetected && <UnsupportedVersionDialog />}
|
||||
</ModalDialogContextController>
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import {Fragment, useContext, useEffect} from 'react';
|
||||
import {isInternalFacebookBuild} from 'react-devtools-feature-flags';
|
||||
import {ModalDialogContext} from './ModalDialog';
|
||||
|
||||
export default function DuplicateInstallationDialog(_: {||}) {
|
||||
const {dispatch} = useContext(ModalDialogContext);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch({
|
||||
canBeDismissed: false,
|
||||
id: 'DuplicateInstallationDialog',
|
||||
type: 'SHOW',
|
||||
title: 'Duplicate Installations of DevTools Detected',
|
||||
content: <DialogContent />,
|
||||
});
|
||||
}, []);
|
||||
return null;
|
||||
}
|
||||
|
||||
function DialogContent(_: {||}) {
|
||||
return (
|
||||
<Fragment>
|
||||
<p>
|
||||
We detected that there are multiple versions of React Developer Tools
|
||||
installed and enabled in your browser at the same time, which will cause
|
||||
issues while using the extension.
|
||||
</p>
|
||||
{isInternalFacebookBuild ? (
|
||||
<p>
|
||||
Before proceeding, please ensure that the only enabled version of
|
||||
React Developer Tools is the internal (Chef-installed) version. To
|
||||
manage your extensions, visit the <code>about://extensions</code> page
|
||||
in your browser.
|
||||
</p>
|
||||
) : (
|
||||
<p>
|
||||
Please ensure that you have installed and enabled only a single
|
||||
version of React Developer Tools before proceeding. To manage your
|
||||
extensions, visit the <code>about://extensions</code> page in your
|
||||
browser.
|
||||
</p>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user