mirror of
https://github.com/facebook/react.git
synced 2026-02-26 07:55:55 +00:00
Inject early on when reloading-and-profiling
This commit is contained in:
@@ -2,13 +2,24 @@
|
||||
|
||||
import nullthrows from 'nullthrows';
|
||||
import { installHook } from 'src/hook';
|
||||
import { RELOAD_AND_PROFILE_KEY } from 'src/constants';
|
||||
|
||||
function injectCode(code) {
|
||||
const script = document.createElement('script');
|
||||
script.textContent = code;
|
||||
|
||||
// This script runs before the <head> element is created,
|
||||
// so we add the script to <html> instead.
|
||||
nullthrows(document.documentElement).appendChild(script);
|
||||
nullthrows(script.parentNode).removeChild(script);
|
||||
}
|
||||
|
||||
let lastDetectionResult;
|
||||
|
||||
// We want to detect when a renderer attaches, and notify the "background
|
||||
// page" (which is shared between tabs and can highlight the React icon).
|
||||
// Currently we are in "content script" context, so we can't listen
|
||||
// to the hook directly (it will be injected directly into the page).
|
||||
// We want to detect when a renderer attaches, and notify the "background page"
|
||||
// (which is shared between tabs and can highlight the React icon).
|
||||
// Currently we are in "content script" context, so we can't listen to the hook directly
|
||||
// (it will be injected directly into the page).
|
||||
// So instead, the hook will use postMessage() to pass message to us here.
|
||||
// And when this happens, we'll send a message to the "background page".
|
||||
window.addEventListener('message', function(evt) {
|
||||
@@ -51,14 +62,27 @@ window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeWeakMap = WeakMap;
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeSet = Set;
|
||||
`;
|
||||
|
||||
// If we have just reloaded to profile, we need to inject the renderer interface before the app loads.
|
||||
if (localStorage.getItem(RELOAD_AND_PROFILE_KEY) === 'true') {
|
||||
const rendererURL = chrome.runtime.getURL('build/renderer.js');
|
||||
let rendererCode;
|
||||
|
||||
// We need to inject in time to catch the initial mount.
|
||||
// This means we need to synchronously read the renderer code itself,
|
||||
// and synchronously inject it into the page.
|
||||
// There are very few ways to actually do this.
|
||||
// This seems to be the best approach.
|
||||
const request = new XMLHttpRequest();
|
||||
request.addEventListener('load', function() {
|
||||
rendererCode = this.responseText;
|
||||
});
|
||||
request.open('GET', rendererURL, false);
|
||||
request.send();
|
||||
injectCode(rendererCode);
|
||||
}
|
||||
|
||||
// Inject a `__REACT_DEVTOOLS_GLOBAL_HOOK__` global so that React can detect that the
|
||||
// devtools are installed (and skip its suggestion to install the devtools).
|
||||
const js =
|
||||
';(' + installHook.toString() + '(window))' + saveNativeValues + detectReact;
|
||||
|
||||
// This script runs before the <head> element is created, so we add the script
|
||||
// to <html> instead.
|
||||
const script = document.createElement('script');
|
||||
script.textContent = js;
|
||||
nullthrows(document.documentElement).appendChild(script);
|
||||
nullthrows(script.parentNode).removeChild(script);
|
||||
injectCode(
|
||||
';(' + installHook.toString() + '(window))' + saveNativeValues + detectReact
|
||||
);
|
||||
|
||||
21
shells/browser/shared/src/renderer.js
Normal file
21
shells/browser/shared/src/renderer.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Install the hook on window, which is an event emitter.
|
||||
* Note because Chrome content scripts cannot directly modify the window object,
|
||||
* we are evaling this function by inserting a script tag.
|
||||
* That's why we have to inline the whole event emitter implementation here.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import { attach } from 'src/backend/renderer';
|
||||
|
||||
Object.defineProperty(
|
||||
window,
|
||||
'__REACT_DEVTOOLS_ATTACH__',
|
||||
({
|
||||
enumerable: false,
|
||||
get() {
|
||||
return attach;
|
||||
},
|
||||
}: Object)
|
||||
);
|
||||
@@ -18,6 +18,7 @@ module.exports = {
|
||||
inject: './src/GlobalHook.js',
|
||||
main: './src/main.js',
|
||||
panel: './src/panel.js',
|
||||
renderer: './src/renderer.js',
|
||||
},
|
||||
output: {
|
||||
path: __dirname + '/build',
|
||||
|
||||
Reference in New Issue
Block a user