main
js 86 lines 2.58 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and 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 * @noflow
8 */
9
10 import * as React from 'react';
11 import {createRoot} from 'react-dom/client';
12 import {
13 activate as activateBackend,
14 createBridge as createBackendBridge,
15 initialize as initializeBackend,
16 } from 'react-devtools-inline/backend';
17 import {
18 createBridge as createFrontendBridge,
19 createStore,
20 initialize as createDevTools,
21 } from 'react-devtools-inline/frontend';
22 import {__DEBUG__} from 'react-devtools-shared/src/constants';
23
24 function inject(contentDocument, sourcePath, callback) {
25 const script = contentDocument.createElement('script');
26 script.onload = callback;
27 script.src = sourcePath;
28
29 ((contentDocument.body: any): HTMLBodyElement).appendChild(script);
30 }
31
32 function init(appIframe, devtoolsContainer, appSource) {
33 const {contentDocument, contentWindow} = appIframe;
34
35 // Wire each DevTools instance directly to its app.
36 // By default, DevTools dispatches "message" events on the window,
37 // but this means that only one instance of DevTools can live on a page.
38 const wall = {
39 _listeners: [],
40 listen(listener) {
41 if (__DEBUG__) {
42 console.log('[Shell] Wall.listen()');
43 }
44
45 wall._listeners.push(listener);
46 return () => {
47 const index = wall._listeners.indexOf(listener);
48 if (index !== -1) {
49 wall._listeners.splice(index, 1);
50 }
51 };
52 },
53 send(event, payload) {
54 if (__DEBUG__) {
55 console.log('[Shell] Wall.send()', {event, payload});
56 }
57
58 wall._listeners.forEach(listener => listener({event, payload}));
59 },
60 };
61
62 const backendBridge = createBackendBridge(contentWindow, wall);
63
64 initializeBackend(contentWindow);
65
66 const frontendBridge = createFrontendBridge(contentWindow, wall);
67 const store = createStore(frontendBridge);
68 const DevTools = createDevTools(contentWindow, {
69 bridge: frontendBridge,
70 store,
71 });
72
73 inject(contentDocument, appSource, () => {
74 createRoot(devtoolsContainer).render(<DevTools />);
75 });
76
77 activateBackend(contentWindow, {bridge: backendBridge});
78 }
79
80 const appIframeLeft = document.getElementById('iframe-left');
81 const appIframeRight = document.getElementById('iframe-right');
82 const devtoolsContainerLeft = document.getElementById('devtools-left');
83 const devtoolsContainerRight = document.getElementById('devtools-right');
84
85 init(appIframeLeft, devtoolsContainerLeft, 'dist/multi-left.js');
86 init(appIframeRight, devtoolsContainerRight, 'dist/multi-right.js');