New NPM package react-devtools-inline (#363)
Brian Vaughn committed
Aug 5, 2019 at 10:09 UTC
dc8580e64df475709fd693f87ef85ae25e5181dd
21 files changed
+440
-116
.eslintignore
+1
@@ -5,6 +5,7 @@ shells/browser/firefox/build
5
shells/browser/shared/build
6
shells/dev/dist
7
packages/react-devtools-core/dist
8
+packages/react-devtools-inline/dist
9
vendor
10
*.js.snap
11
.gitignore
+4
-2
@@ -4,11 +4,13 @@
4
/shells/browser/firefox/*.pem
5
/shells/browser/shared/build
6
/packages/react-devtools-core/dist
7
+/packages/react-devtools-inline/dist
8
/shells/dev/dist
9
build
10
/node_modules
10
-/packages/react-devtools-core/node_modules/
11
-/packages/react-devtools/node_modules/
11
+/packages/react-devtools-core/node_modules
12
+/packages/react-devtools-inline/node_modules
13
+/packages/react-devtools/node_modules
14
npm-debug.log
15
yarn-error.log
16
.DS_Store
package.json
+2
@@ -34,6 +34,8 @@
34
"scripts": {
35
"build:core:backend": "cd ./packages/react-devtools-core && yarn build:backend",
36
"build:core:standalone": "cd ./packages/react-devtools-core && yarn build:standalone",
37
+ "build:core": "cd ./packages/react-devtools-core && yarn build",
38
+ "build:inline": "cd ./packages/react-devtools-inline && yarn build",
39
"build:demo": "cd ./shells/dev && cross-env NODE_ENV=development cross-env TARGET=remote webpack --config webpack.config.js",
40
"build:extension": "cross-env NODE_ENV=production yarn run build:extension:chrome && yarn run build:extension:firefox",
41
"build:extension:dev": "cross-env NODE_ENV=development yarn run build:extension:chrome && yarn run build:extension:firefox",
packages/react-devtools-core/package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "react-devtools-core",
3
- "version": "4.0.0-alpha.6",
3
+ "version": "4.0.0-alpha.7",
4
"description": "Use react-devtools outside of the browser",
5
"license": "MIT",
6
"main": "./dist/backend.js",
packages/react-devtools-inline/README.md
new
+134
@@ -0,0 +1,134 @@
1
+# `react-devtools-inline`
2
+
3
+React DevTools implementation for embedding within a browser-based IDE (e.g. [CodeSandbox](https://codesandbox.io/), [StackBlitz](https://stackblitz.com/)).
4
+
5
+This is a low-level package. If you're looking for the standalone DevTools app, **use the `react-devtools` package instead.**
6
+
7
+## Usage
8
+
9
+This package exports two entry points: a frontend (to be run in the main `window`) and a backend (to be installed and run within an `iframe`<sup>1</sup>).
10
+
11
+The frontend and backend can be initialized in any order, but **the backend must not be activated until after the frontend has been initialized**. Because of this, the simplest sequence is:
12
+
13
+1. Frontend (DevTools interface) initialized in the main `window`.
14
+1. Backend initialized in an `iframe`.
15
+1. Backend activated.
16
+
17
+<sup>1</sup> Sandboxed iframes are supported.
18
+
19
+## API
20
+
21
+### `react-devtools-inline/backend`
22
+
23
+* **`initialize(contentWindow)`** -
24
+Installs the global hook on the window. This hook is how React and DevTools communicate. **This method must be called before React is loaded.** (This means before any `import` or `require` statements!)
25
+* **`activate(contentWindow)`** -
26
+Lets the backend know when the frontend is ready. It should not be called until after the frontend has been initialized, else the frontend might miss important tree-initialization events.
27
+
28
+```js
29
+import { activate, initialize } from 'react-devtools-inline/backend';
30
+
31
+// Call this before importing React (or any other packages that might import React).
32
+initialize();
33
+
34
+// Call this only once the frontend has been initialized.
35
+activate();
36
+```
37
+
38
+### `react-devtools-inline/frontend`
39
+
40
+* **`initialize(contentWindow)`** -
41
+Configures the DevTools interface to listen to the `window` the backend was injected into. This method returns a React component that can be rendered directly.
42
+
43
+```js
44
+import { initialize } from 'react-devtools-inline/frontend';
45
+
46
+// This should be the iframe the backend hook has been installed in.
47
+const iframe = document.getElementById(frameID);
48
+const contentWindow = iframe.contentWindow;
49
+
50
+// This returns a React component that can be rendered into your app.
51
+// <DevTools {...props} />
52
+const DevTools = initialize(contentWindow);
53
+```
54
+
55
+## Examples
56
+
57
+### Configuring a same-origin `iframe`
58
+
59
+The simplest way to use this package is to install the hook from the parent `window`. This is possible if the `iframe` is not sandboxed and there are no cross-origin restrictions.
60
+
61
+```js
62
+import {
63
+ activate as activateBackend,
64
+ initialize as initializeBackend
65
+} from 'react-devtools-inline/backend';
66
+import { initialize as initializeFrontend } from 'react-devtools-inline/frontend';
67
+
68
+// The React app you want to inspect with DevTools is running within this iframe:
69
+const iframe = document.getElementById('target');
70
+const { contentWindow } = iframe;
71
+
72
+// Installs the global hook into the iframe.
73
+// This be called before React is loaded into that frame.
74
+initializeBackend(contentWindow);
75
+
76
+// React application can be injected into <iframe> at any time now...
77
+
78
+// Initialize DevTools UI to listen to the hook we just installed.
79
+// This returns a React component we can render anywhere in the parent window.
80
+const DevTools = initializeFrontend(contentWindow);
81
+
82
+// <DevTools /> interface can be rendered in the parent window at any time now...
83
+
84
+// Let the backend know the frontend is ready and listening.
85
+activateBackend(contentWindow);
86
+```
87
+
88
+### Configuring a sandboxed `iframe`
89
+
90
+Sandboxed `iframe`s are also supported but require more complex initialization.
91
+
92
+**`iframe.html`**
93
+```js
94
+import { activate, initialize } from 'react-devtools-inline/backend';
95
+
96
+// The DevTooks hook needs to be installed before React is even required!
97
+// The safest way to do this is probably to install it in a separate script tag.
98
+initialize(window);
99
+
100
+// Wait for the frontend to let us know that it's ready.
101
+window.addEventListener('message', ({ data }) => {
102
+ switch (data.type) {
103
+ case 'activate':
104
+ activate(window);
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+});
110
+```
111
+
112
+**`main-window.html`**
113
+```js
114
+import { initialize } from 'react-devtools-inline/frontend';
115
+
116
+const iframe = document.getElementById('target');
117
+const { contentWindow } = iframe;
118
+
119
+// Initialize DevTools UI to listen to the iframe.
120
+// This returns a React component we can render anywhere in the main window.
121
+const DevTools = initialize(contentWindow);
122
+
123
+// Let the backend know to initialize itself.
124
+// We can't do this directly because the iframe is sandboxed.
125
+// Only initialize the backend once the DevTools frontend has been initialized.
126
+iframe.onload = () => {
127
+ contentWindow.postMessage(
128
+ {
129
+ type: 'activate',
130
+ },
131
+ '*'
132
+ );
133
+};
134
+```
\ No newline at end of file
packages/react-devtools-inline/backend.js
new
+1
@@ -0,0 +1 @@
1
+module.exports = require('./dist/backend');
packages/react-devtools-inline/frontend.js
new
+1
@@ -0,0 +1 @@
1
+module.exports = require('./dist/frontend');
packages/react-devtools-inline/package.json
new
+25
@@ -0,0 +1,25 @@
1
+{
2
+ "name": "react-devtools-inline",
3
+ "version": "4.0.0-alpha.7",
4
+ "description": "Embed react-devtools within a website",
5
+ "license": "MIT",
6
+ "main": "./dist/backend.js",
7
+ "repository": {
8
+ "url": "https://github.com/bvaughn/react-devtools-experimental.git",
9
+ "type": "git"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "backend.js",
14
+ "frontend.js"
15
+ ],
16
+ "scripts": {
17
+ "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
18
+ "prepublish": "yarn run build",
19
+ "start": "cross-env NODE_ENV=development webpack --config webpack.config.js --watch"
20
+ },
21
+ "dependencies": {},
22
+ "devDependencies": {
23
+ "cross-env": "^3.1.4"
24
+ }
25
+}
packages/react-devtools-inline/src/backend.js
new
+96
@@ -0,0 +1,96 @@
1
+/** @flow */
2
+
3
+import Agent from 'src/backend/agent';
4
+import Bridge from 'src/bridge';
5
+import { initBackend } from 'src/backend';
6
+import { installHook } from 'src/hook';
7
+import setupNativeStyleEditor from 'src/backend/NativeStyleEditor/setupNativeStyleEditor';
8
+import {
9
+ MESSAGE_TYPE_GET_SAVED_PREFERENCES,
10
+ MESSAGE_TYPE_SAVED_PREFERENCES,
11
+} from './constants';
12
+
13
+function startActivation(contentWindow: window) {
14
+ const { parent } = contentWindow;
15
+
16
+ const onMessage = ({ data }) => {
17
+ switch (data.type) {
18
+ case MESSAGE_TYPE_SAVED_PREFERENCES:
19
+ // This is the only message we're listening for,
20
+ // so it's safe to cleanup after we've received it.
21
+ contentWindow.removeEventListener('message', onMessage);
22
+
23
+ const { appendComponentStack, componentFilters } = data;
24
+
25
+ contentWindow.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = appendComponentStack;
26
+ contentWindow.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
27
+
28
+ // TRICKY
29
+ // The backend entry point may be required in the context of an iframe or the parent window.
30
+ // If it's required within the parent window, store the saved values on it as well,
31
+ // since the injected renderer interface will read from window.
32
+ // Technically we don't need to store them on the contentWindow in this case,
33
+ // but it doesn't really hurt anything to store them there too.
34
+ if (contentWindow !== window) {
35
+ window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = appendComponentStack;
36
+ window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
37
+ }
38
+
39
+ finishActivation(contentWindow);
40
+ break;
41
+ default:
42
+ break;
43
+ }
44
+ };
45
+
46
+ contentWindow.addEventListener('message', onMessage);
47
+
48
+ // The backend may be unable to read saved preferences directly,
49
+ // because they are stored in localStorage within the context of the extension (on the frontend).
50
+ // Instead it relies on the extension to pass preferences through.
51
+ // Because we might be in a sandboxed iframe, we have to ask for them by way of postMessage().
52
+ parent.postMessage({ type: MESSAGE_TYPE_GET_SAVED_PREFERENCES }, '*');
53
+}
54
+
55
+function finishActivation(contentWindow: window) {
56
+ const { parent } = contentWindow;
57
+
58
+ const bridge = new Bridge({
59
+ listen(fn) {
60
+ const onMessage = event => {
61
+ fn(event.data);
62
+ };
63
+ contentWindow.addEventListener('message', onMessage);
64
+ return () => {
65
+ contentWindow.removeEventListener('message', onMessage);
66
+ };
67
+ },
68
+ send(event: string, payload: any, transferable?: Array<any>) {
69
+ parent.postMessage({ event, payload }, '*', transferable);
70
+ },
71
+ });
72
+
73
+ const agent = new Agent(bridge);
74
+
75
+ const hook = contentWindow.__REACT_DEVTOOLS_GLOBAL_HOOK__;
76
+
77
+ initBackend(hook, agent, contentWindow);
78
+
79
+ // Setup React Native style editor if a renderer like react-native-web has injected it.
80
+ if (!!hook.resolveRNStyle) {
81
+ setupNativeStyleEditor(
82
+ bridge,
83
+ agent,
84
+ hook.resolveRNStyle,
85
+ hook.nativeStyleEditorValidAttributes
86
+ );
87
+ }
88
+}
89
+
90
+export function activate(contentWindow: window): void {
91
+ startActivation(contentWindow);
92
+}
93
+
94
+export function initialize(contentWindow: window): void {
95
+ installHook(contentWindow);
96
+}
packages/react-devtools-inline/src/constants.js
new
+6
@@ -0,0 +1,6 @@
1
+/** @flow */
2
+
3
+export const MESSAGE_TYPE_GET_SAVED_PREFERENCES =
4
+ 'React::DevTools::getSavedPreferences';
5
+export const MESSAGE_TYPE_SAVED_PREFERENCES =
6
+ 'React::DevTools::savedPreferences';
packages/react-devtools-inline/src/frontend.js
new
+68
@@ -0,0 +1,68 @@
1
+/** @flow */
2
+
3
+import React, { forwardRef } from 'react';
4
+import Bridge from 'src/bridge';
5
+import Store from 'src/devtools/store';
6
+import DevTools from 'src/devtools/views/DevTools';
7
+import { getSavedComponentFilters, getAppendComponentStack } from 'src/utils';
8
+import {
9
+ MESSAGE_TYPE_GET_SAVED_PREFERENCES,
10
+ MESSAGE_TYPE_SAVED_PREFERENCES,
11
+} from './constants';
12
+
13
+import type { FrontendBridge } from 'src/bridge';
14
+import type { Props } from 'src/devtools/views/DevTools';
15
+
16
+export function initialize(
17
+ contentWindow: window
18
+): React$AbstractComponent<Props, mixed> {
19
+ const onMessage = ({ data, origin, source }) => {
20
+ switch (data.type) {
21
+ case MESSAGE_TYPE_GET_SAVED_PREFERENCES:
22
+ // This is the only message we're listening for,
23
+ // so it's safe to cleanup after we've received it.
24
+ window.removeEventListener('message', onMessage);
25
+
26
+ // The renderer interface can't read saved preferences directly,
27
+ // because they are stored in localStorage within the context of the extension.
28
+ // Instead it relies on the extension to pass them through.
29
+ contentWindow.postMessage(
30
+ {
31
+ type: MESSAGE_TYPE_SAVED_PREFERENCES,
32
+ appendComponentStack: getAppendComponentStack(),
33
+ componentFilters: getSavedComponentFilters(),
34
+ },
35
+ '*'
36
+ );
37
+ break;
38
+ default:
39
+ break;
40
+ }
41
+ };
42
+
43
+ window.addEventListener('message', onMessage);
44
+
45
+ const bridge: FrontendBridge = new Bridge({
46
+ listen(fn) {
47
+ const onMessage = ({ data }) => {
48
+ fn(data);
49
+ };
50
+ window.addEventListener('message', onMessage);
51
+ return () => {
52
+ window.removeEventListener('message', onMessage);
53
+ };
54
+ },
55
+ send(event: string, payload: any, transferable?: Array<any>) {
56
+ contentWindow.postMessage({ event, payload }, '*', transferable);
57
+ },
58
+ });
59
+
60
+ const store: Store = new Store(bridge);
61
+
62
+ const ForwardRef = forwardRef<Props, mixed>((props, ref) => (
63
+ <DevTools ref={ref} bridge={bridge} store={store} {...props} />
64
+ ));
65
+ ForwardRef.displayName = 'DevTools';
66
+
67
+ return ForwardRef;
68
+}
packages/react-devtools-inline/webpack.config.js
new
+74
@@ -0,0 +1,74 @@
1
+const { resolve } = require('path');
2
+const { DefinePlugin } = require('webpack');
3
+const { getGitHubURL, getVersionString } = require('../../shells/utils');
4
+
5
+const NODE_ENV = process.env.NODE_ENV;
6
+if (!NODE_ENV) {
7
+ console.error('NODE_ENV not set');
8
+ process.exit(1);
9
+}
10
+
11
+const __DEV__ = true; // NODE_ENV === 'development';
12
+
13
+const GITHUB_URL = getGitHubURL();
14
+const DEVTOOLS_VERSION = getVersionString();
15
+
16
+module.exports = {
17
+ mode: __DEV__ ? 'development' : 'production',
18
+ devtool: false,
19
+ entry: {
20
+ backend: './src/backend.js',
21
+ frontend: './src/frontend.js',
22
+ },
23
+ output: {
24
+ path: __dirname + '/dist',
25
+ filename: '[name].js',
26
+ library: '[name]',
27
+ libraryTarget: 'commonjs2',
28
+ },
29
+ resolve: {
30
+ alias: {
31
+ src: resolve(__dirname, '../../src'),
32
+ },
33
+ },
34
+ externals: {
35
+ react: 'react',
36
+ 'react-dom': 'react-dom',
37
+ scheduler: 'scheduler',
38
+ },
39
+ plugins: [
40
+ new DefinePlugin({
41
+ __DEV__: __DEV__,
42
+ 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
43
+ 'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
44
+ 'process.env.NODE_ENV': `"${NODE_ENV}"`,
45
+ }),
46
+ ],
47
+ module: {
48
+ rules: [
49
+ {
50
+ test: /\.js$/,
51
+ loader: 'babel-loader',
52
+ options: {
53
+ configFile: resolve(__dirname, '../../babel.config.js'),
54
+ },
55
+ },
56
+ {
57
+ test: /\.css$/,
58
+ use: [
59
+ {
60
+ loader: 'style-loader',
61
+ },
62
+ {
63
+ loader: 'css-loader',
64
+ options: {
65
+ sourceMap: true,
66
+ modules: true,
67
+ localIdentName: '[local]___[hash:base64:5]',
68
+ },
69
+ },
70
+ ],
71
+ },
72
+ ],
73
+ },
74
+};
packages/react-devtools/package.json
+2
-2
@@ -1,6 +1,6 @@
1
{
2
"name": "react-devtools",
3
- "version": "4.0.0-alpha.6",
3
+ "version": "4.0.0-alpha.7",
4
"description": "Use react-devtools outside of the browser",
5
"license": "MIT",
6
"repository": {
@@ -25,7 +25,7 @@
25
"electron": "^5.0.0",
26
"ip": "^1.1.4",
27
"minimist": "^1.2.0",
28
- "react-devtools-core": "4.0.0-alpha.6",
28
+ "react-devtools-core": "4.0.0-alpha.7",
29
"update-notifier": "^2.1.0"
30
}
31
}
shells/browser/shared/src/main.js
-2
@@ -63,7 +63,6 @@ function createPanelIfReactLoaded() {
63
64
let componentsPortalContainer = null;
65
let profilerPortalContainer = null;
66
- let settingsPortalContainer = null;
66
67
let cloneStyleTags = null;
68
let mostRecentOverrideTab = null;
@@ -142,7 +141,6 @@ function createPanelIfReactLoaded() {
141
componentsPortalContainer,
142
overrideTab,
143
profilerPortalContainer,
145
- settingsPortalContainer,
144
showTabBar: false,
145
showWelcomeToTheNewDevToolsDialog: true,
146
store,
shells/dev/src/backend.js
deleted
-37
@@ -1,37 +0,0 @@
1
-/** @flow */
2
-
3
-import Agent from 'src/backend/agent';
4
-import Bridge from 'src/bridge';
5
-import { initBackend } from 'src/backend';
6
-import setupNativeStyleEditor from 'src/backend/NativeStyleEditor/setupNativeStyleEditor';
7
-
8
-const bridge = new Bridge({
9
- listen(fn) {
10
- const listener = event => {
11
- fn(event.data);
12
- };
13
- window.addEventListener('message', listener);
14
- return () => {
15
- window.removeEventListener('message', listener);
16
- };
17
- },
18
- send(event: string, payload: any, transferable?: Array<any>) {
19
- window.parent.postMessage({ event, payload }, '*', transferable);
20
- },
21
-});
22
-
23
-const agent = new Agent(bridge);
24
-
25
-const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
26
-
27
-initBackend(hook, agent, window.parent);
28
-
29
-// Setup React Native style editor if a renderer like react-native-web has injected it.
30
-if (!!hook.resolveRNStyle) {
31
- setupNativeStyleEditor(
32
- bridge,
33
- agent,
34
- hook.resolveRNStyle,
35
- hook.nativeStyleEditorValidAttributes
36
- );
37
-}
shells/dev/src/devtools.js
+13
-41
@@ -3,24 +3,21 @@
3
import { createElement } from 'react';
4
// $FlowFixMe Flow does not yet know about createRoot()
5
import { unstable_createRoot as createRoot } from 'react-dom';
6
-import Bridge from 'src/bridge';
7
-import { installHook } from 'src/hook';
6
+import {
7
+ activate as activateBackend,
8
+ initialize as initializeBackend,
9
+} from 'react-devtools-inline/backend';
10
+import { initialize as initializeFrontend } from 'react-devtools-inline/frontend';
11
import { initDevTools } from 'src/devtools';
9
-import Store from 'src/devtools/store';
10
-import DevTools from 'src/devtools/views/DevTools';
11
-import { getSavedComponentFilters, getAppendComponentStack } from 'src/utils';
12
13
const iframe = ((document.getElementById('target'): any): HTMLIFrameElement);
14
15
const { contentDocument, contentWindow } = iframe;
16
17
-// The renderer interface can't read saved component filters directly,
18
-// because they are stored in localStorage within the context of the extension.
19
-// Instead it relies on the extension to pass filters through.
20
-contentWindow.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = getSavedComponentFilters();
21
-contentWindow.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = getAppendComponentStack();
17
+// Helps with positioning Overlay UI.
18
+contentWindow.__REACT_DEVTOOLS_TARGET_WINDOW__ = window;
19
23
-installHook(contentWindow);
20
+initializeBackend(contentWindow);
21
22
const container = ((document.getElementById('devtools'): any): HTMLElement);
23
@@ -48,46 +45,21 @@ mountButton.addEventListener('click', function() {
45
inject('dist/app.js', () => {
46
initDevTools({
47
connect(cb) {
51
- const bridge = new Bridge({
52
- listen(fn) {
53
- const listener = ({ data }) => {
54
- fn(data);
55
- };
56
- // Preserve the reference to the window we subscribe to, so we can unsubscribe from it when required.
57
- const contentWindowParent = contentWindow.parent;
58
- contentWindowParent.addEventListener('message', listener);
59
- return () => {
60
- contentWindowParent.removeEventListener('message', listener);
61
- };
62
- },
63
- send(event: string, payload: any, transferable?: Array<any>) {
64
- contentWindow.postMessage({ event, payload }, '*', transferable);
65
- },
66
- });
48
+ const DevTools = initializeFrontend(contentWindow);
49
68
- cb(bridge);
69
-
70
- const store = new Store(bridge);
50
+ // Activate the backend only once the DevTools frontend Store has been initialized.
51
+ // Otherwise the Store may miss important initial tree op codes.
52
+ activateBackend(contentWindow);
53
54
const root = createRoot(container);
73
- const batch = root.createBatch();
74
- batch.render(
55
+ root.render(
56
createElement(DevTools, {
76
- bridge,
57
browserTheme: 'light',
58
showTabBar: true,
59
showWelcomeToTheNewDevToolsDialog: true,
80
- store,
60
warnIfLegacyBackendDetected: true,
61
})
62
);
84
- batch.then(() => {
85
- batch.commit();
86
-
87
- // Initialize the backend only once the DevTools frontend Store has been initialized.
88
- // Otherwise the Store may miss important initial tree op codes.
89
- inject('dist/backend.js');
90
- });
63
},
64
65
onReload(reloadFn) {
shells/dev/webpack.config.js
+8
-3
@@ -16,6 +16,8 @@ if (!TARGET) {
16
17
const __DEV__ = NODE_ENV === 'development';
18
19
+const root = resolve(__dirname, '../..');
20
+
21
const GITHUB_URL = getGitHubURL();
22
const DEVTOOLS_VERSION = getVersionString();
23
@@ -24,12 +26,15 @@ const config = {
26
devtool: false,
27
entry: {
28
app: './app/index.js',
27
- backend: './src/backend.js',
29
devtools: './src/devtools.js',
30
},
31
resolve: {
32
alias: {
32
- src: resolve(__dirname, '../../src'),
33
+ 'react-devtools-inline': resolve(
34
+ root,
35
+ 'packages/react-devtools-inline/src/'
36
+ ),
37
+ src: resolve(root, 'src'),
38
},
39
},
40
plugins: [
@@ -45,7 +50,7 @@ const config = {
50
test: /\.js$/,
51
loader: 'babel-loader',
52
options: {
48
- configFile: require.resolve('../../babel.config.js'),
53
+ configFile: resolve(root, 'babel.config.js'),
54
},
55
},
56
{
src/backend/views/Highlighter/Overlay.js
+2
-11
@@ -153,20 +153,11 @@ export default class Overlay {
153
154
constructor() {
155
// Find the root window, because overlays are positioned relative to it.
156
- let currentWindow = window;
157
- while (currentWindow !== currentWindow.parent) {
158
- currentWindow = currentWindow.parent;
159
- }
156
+ let currentWindow = window.__REACT_DEVTOOLS_TARGET_WINDOW__ || window;
157
this.window = currentWindow;
158
159
// When opened in shells/dev, the tooltip should be bound by the app iframe, not by the topmost window.
163
- let tipBoundsWindow = window;
164
- while (
165
- tipBoundsWindow !== tipBoundsWindow.parent &&
166
- !tipBoundsWindow.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')
167
- ) {
168
- tipBoundsWindow = tipBoundsWindow.parent;
169
- }
160
+ let tipBoundsWindow = window.__REACT_DEVTOOLS_TARGET_WINDOW__ || window;
161
this.tipBoundsWindow = tipBoundsWindow;
162
163
const doc = currentWindow.document;
src/devtools/store.js
+1
-1
@@ -114,7 +114,7 @@ export default class Store extends EventEmitter<{|
114
115
// These options may be initially set by a confiugraiton option when constructing the Store.
116
// In the case of "supportsProfiling", the option may be updated based on the injected renderers.
117
- _supportsNativeInspection: boolean = false;
117
+ _supportsNativeInspection: boolean = true;
118
_supportsProfiling: boolean = false;
119
_supportsReloadAndProfile: boolean = false;
120
src/devtools/views/DevTools.js
-3
@@ -59,7 +59,6 @@ export type Props = {|
59
// but individual tabs (e.g. Components, Profiling) can be rendered into portals within their browser panels.
60
componentsPortalContainer?: Element,
61
profilerPortalContainer?: Element,
62
- settingsPortalContainer?: Element,
62
|};
63
64
const componentsTab = {
@@ -85,7 +84,6 @@ export default function DevTools({
84
componentsPortalContainer,
85
overrideTab,
86
profilerPortalContainer,
88
- settingsPortalContainer,
87
showTabBar = false,
88
showWelcomeToTheNewDevToolsDialog = false,
89
store,
@@ -113,7 +111,6 @@ export default function DevTools({
111
browserTheme={browserTheme}
112
componentsPortalContainer={componentsPortalContainer}
113
profilerPortalContainer={profilerPortalContainer}
116
- settingsPortalContainer={settingsPortalContainer}
114
>
115
<ViewElementSourceContext.Provider value={viewElementSource}>
116
<TreeContextController>
src/devtools/views/Settings/SettingsContext.js
+1
-13
@@ -41,7 +41,6 @@ type Props = {|
41
children: React$Node,
42
componentsPortalContainer?: Element,
43
profilerPortalContainer?: Element,
44
- settingsPortalContainer?: Element,
44
|};
45
46
function SettingsContextController({
@@ -49,7 +48,6 @@ function SettingsContextController({
48
children,
49
componentsPortalContainer,
50
profilerPortalContainer,
52
- settingsPortalContainer,
51
}: Props) {
52
const bridge = useContext(BridgeContext);
53
@@ -82,18 +80,8 @@ function SettingsContextController({
80
.documentElement: any): HTMLElement)
81
);
82
}
85
- if (settingsPortalContainer != null) {
86
- array.push(
87
- ((settingsPortalContainer.ownerDocument
88
- .documentElement: any): HTMLElement)
89
- );
90
- }
83
return array;
92
- }, [
93
- componentsPortalContainer,
94
- profilerPortalContainer,
95
- settingsPortalContainer,
96
- ]);
84
+ }, [componentsPortalContainer, profilerPortalContainer]);
85
86
const computedStyle = getComputedStyle((document.body: any));
87
const comfortableLineHeight = parseInt(