mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
[DevTools] Allow inspection before streaming has finished in Chrome (#34360)
This commit is contained in:
parent
ba6590dd7c
commit
5a31758ed6
|
|
@ -577,6 +577,7 @@ module.exports = {
|
||||||
$AsyncIterator: 'readonly',
|
$AsyncIterator: 'readonly',
|
||||||
Iterator: 'readonly',
|
Iterator: 'readonly',
|
||||||
AsyncIterator: 'readonly',
|
AsyncIterator: 'readonly',
|
||||||
|
IntervalID: 'readonly',
|
||||||
IteratorResult: 'readonly',
|
IteratorResult: 'readonly',
|
||||||
JSONValue: 'readonly',
|
JSONValue: 'readonly',
|
||||||
JSResourceReference: 'readonly',
|
JSResourceReference: 'readonly',
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const contentScriptsToInject = [
|
||||||
js: ['build/proxy.js'],
|
js: ['build/proxy.js'],
|
||||||
matches: ['<all_urls>'],
|
matches: ['<all_urls>'],
|
||||||
persistAcrossSessions: true,
|
persistAcrossSessions: true,
|
||||||
runAt: 'document_end',
|
runAt: 'document_start',
|
||||||
world: chrome.scripting.ExecutionWorld.ISOLATED,
|
world: chrome.scripting.ExecutionWorld.ISOLATED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,20 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
/* global chrome */
|
/* global chrome */
|
||||||
|
|
||||||
export function executeScriptInIsolatedWorld({target, files}) {
|
export function executeScriptInIsolatedWorld({
|
||||||
|
target,
|
||||||
|
files,
|
||||||
|
}: {
|
||||||
|
files: any,
|
||||||
|
target: any,
|
||||||
|
}): Promise<void> {
|
||||||
return chrome.scripting.executeScript({
|
return chrome.scripting.executeScript({
|
||||||
target,
|
target,
|
||||||
files,
|
files,
|
||||||
|
|
@ -8,10 +22,20 @@ export function executeScriptInIsolatedWorld({target, files}) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function executeScriptInMainWorld({target, files}) {
|
export function executeScriptInMainWorld({
|
||||||
|
target,
|
||||||
|
files,
|
||||||
|
injectImmediately,
|
||||||
|
}: {
|
||||||
|
files: any,
|
||||||
|
target: any,
|
||||||
|
// It's nice to have this required to make active choices.
|
||||||
|
injectImmediately: boolean,
|
||||||
|
}): Promise<void> {
|
||||||
return chrome.scripting.executeScript({
|
return chrome.scripting.executeScript({
|
||||||
target,
|
target,
|
||||||
files,
|
files,
|
||||||
|
injectImmediately,
|
||||||
world: chrome.scripting.ExecutionWorld.MAIN,
|
world: chrome.scripting.ExecutionWorld.MAIN,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/* global chrome */
|
/* global chrome */
|
||||||
|
|
||||||
|
import {__DEBUG__} from 'react-devtools-shared/src/constants';
|
||||||
import setExtensionIconAndPopup from './setExtensionIconAndPopup';
|
import setExtensionIconAndPopup from './setExtensionIconAndPopup';
|
||||||
import {executeScriptInMainWorld} from './executeScript';
|
import {executeScriptInMainWorld} from './executeScript';
|
||||||
|
|
||||||
|
|
@ -25,6 +26,7 @@ export function handleBackendManagerMessage(message, sender) {
|
||||||
payload.versions.forEach(version => {
|
payload.versions.forEach(version => {
|
||||||
if (EXTENSION_CONTAINED_VERSIONS.includes(version)) {
|
if (EXTENSION_CONTAINED_VERSIONS.includes(version)) {
|
||||||
executeScriptInMainWorld({
|
executeScriptInMainWorld({
|
||||||
|
injectImmediately: true,
|
||||||
target: {tabId: sender.tab.id},
|
target: {tabId: sender.tab.id},
|
||||||
files: [`/build/react_devtools_backend_${version}.js`],
|
files: [`/build/react_devtools_backend_${version}.js`],
|
||||||
});
|
});
|
||||||
|
|
@ -79,9 +81,19 @@ export function handleDevToolsPageMessage(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
executeScriptInMainWorld({
|
executeScriptInMainWorld({
|
||||||
|
injectImmediately: true,
|
||||||
target: {tabId},
|
target: {tabId},
|
||||||
files: ['/build/backendManager.js'],
|
files: ['/build/backendManager.js'],
|
||||||
});
|
}).then(
|
||||||
|
() => {
|
||||||
|
if (__DEBUG__) {
|
||||||
|
console.log('Successfully injected backend manager');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reason => {
|
||||||
|
console.error('Failed to inject backend manager:', reason);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,16 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
/* global chrome */
|
/* global chrome */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
window.addEventListener('pageshow', function ({target}) {
|
function injectProxy({target}: {target: any}) {
|
||||||
// Firefox's behaviour for injecting this content script can be unpredictable
|
// Firefox's behaviour for injecting this content script can be unpredictable
|
||||||
// While navigating the history, some content scripts might not be re-injected and still be alive
|
// While navigating the history, some content scripts might not be re-injected and still be alive
|
||||||
if (!window.__REACT_DEVTOOLS_PROXY_INJECTED__) {
|
if (!window.__REACT_DEVTOOLS_PROXY_INJECTED__) {
|
||||||
|
|
@ -14,7 +22,7 @@ window.addEventListener('pageshow', function ({target}) {
|
||||||
// The backend waits to install the global hook until notified by the content script.
|
// The backend waits to install the global hook until notified by the content script.
|
||||||
// In the event of a page reload, the content script might be loaded before the backend manager is injected.
|
// In the event of a page reload, the content script might be loaded before the backend manager is injected.
|
||||||
// Because of this we need to poll the backend manager until it has been initialized.
|
// Because of this we need to poll the backend manager until it has been initialized.
|
||||||
const intervalID = setInterval(() => {
|
const intervalID: IntervalID = setInterval(() => {
|
||||||
if (backendInitialized) {
|
if (backendInitialized) {
|
||||||
clearInterval(intervalID);
|
clearInterval(intervalID);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -22,7 +30,11 @@ window.addEventListener('pageshow', function ({target}) {
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
window.addEventListener('pagereveal', injectProxy);
|
||||||
|
// For backwards compat with browsers not implementing `pagereveal` which is a fairly new event.
|
||||||
|
window.addEventListener('pageshow', injectProxy);
|
||||||
|
|
||||||
window.addEventListener('pagehide', function ({target}) {
|
window.addEventListener('pagehide', function ({target}) {
|
||||||
if (target !== window.document) {
|
if (target !== window.document) {
|
||||||
|
|
@ -45,7 +57,7 @@ function sayHelloToBackendManager() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMessageFromDevtools(message) {
|
function handleMessageFromDevtools(message: any) {
|
||||||
window.postMessage(
|
window.postMessage(
|
||||||
{
|
{
|
||||||
source: 'react-devtools-content-script',
|
source: 'react-devtools-content-script',
|
||||||
|
|
@ -55,7 +67,7 @@ function handleMessageFromDevtools(message) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMessageFromPage(event) {
|
function handleMessageFromPage(event: any) {
|
||||||
if (event.source !== window || !event.data) {
|
if (event.source !== window || !event.data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -65,6 +77,7 @@ function handleMessageFromPage(event) {
|
||||||
case 'react-devtools-bridge': {
|
case 'react-devtools-bridge': {
|
||||||
backendInitialized = true;
|
backendInitialized = true;
|
||||||
|
|
||||||
|
// $FlowFixMe[incompatible-use]
|
||||||
port.postMessage(event.data.payload);
|
port.postMessage(event.data.payload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +112,8 @@ function connectPort() {
|
||||||
|
|
||||||
window.addEventListener('message', handleMessageFromPage);
|
window.addEventListener('message', handleMessageFromPage);
|
||||||
|
|
||||||
|
// $FlowFixMe[incompatible-use]
|
||||||
port.onMessage.addListener(handleMessageFromDevtools);
|
port.onMessage.addListener(handleMessageFromDevtools);
|
||||||
|
// $FlowFixMe[incompatible-use]
|
||||||
port.onDisconnect.addListener(handleDisconnect);
|
port.onDisconnect.addListener(handleDisconnect);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user