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.     },
    
  47.     send(event, payload) {
    
  48.       if (__DEBUG__) {
    
  49.         console.log('[Shell] Wall.send()', {event, payload});
    
  50.       }
    
  51. 
    
  52.       wall._listeners.forEach(listener => listener({event, payload}));
    
  53.     },
    
  54.   };
    
  55. 
    
  56.   const backendBridge = createBackendBridge(contentWindow, wall);
    
  57. 
    
  58.   initializeBackend(contentWindow);
    
  59. 
    
  60.   const frontendBridge = createFrontendBridge(contentWindow, wall);
    
  61.   const store = createStore(frontendBridge);
    
  62.   const DevTools = createDevTools(contentWindow, {
    
  63.     bridge: frontendBridge,
    
  64.     store,
    
  65.   });
    
  66. 
    
  67.   inject(contentDocument, appSource, () => {
    
  68.     createRoot(devtoolsContainer).render(<DevTools />);
    
  69.   });
    
  70. 
    
  71.   activateBackend(contentWindow, {bridge: backendBridge});
    
  72. }
    
  73. 
    
  74. const appIframeLeft = document.getElementById('iframe-left');
    
  75. const appIframeRight = document.getElementById('iframe-right');
    
  76. const devtoolsContainerLeft = document.getElementById('devtools-left');
    
  77. const devtoolsContainerRight = document.getElementById('devtools-right');
    
  78. 
    
  79. init(appIframeLeft, devtoolsContainerLeft, 'dist/multi-left.js');
    
  80. init(appIframeRight, devtoolsContainerRight, 'dist/multi-right.js');