tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

toolbox-init.js (4513B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const { require } = ChromeUtils.importESModule(
      8  "resource://devtools/shared/loader/Loader.sys.mjs"
      9 );
     10 
     11 // URL constructor doesn't support about: scheme
     12 const href = window.location.href.replace("about:", "http://");
     13 const url = new window.URL(href);
     14 
     15 // `host` is the frame element loading the toolbox.
     16 let host = window.browsingContext.embedderElement;
     17 
     18 // If there's no containerElement (which happens when loading about:devtools-toolbox as
     19 // a top level document), use the current window.
     20 if (!host) {
     21  host = {
     22    contentWindow: window,
     23    contentDocument: document,
     24    // toolbox-host-manager.js wants to set attributes on the frame that contains it,
     25    // but that is fine to skip and doesn't make sense when using the current window.
     26    setAttribute() {},
     27    ownerDocument: document,
     28    // toolbox-host-manager.js wants to listen for unload events from outside the frame,
     29    // but this is fine to skip since the toolbox code listens inside the frame as well,
     30    // and there is no outer document in this case.
     31    addEventListener() {},
     32  };
     33 }
     34 
     35 const onLoad = new Promise(r => {
     36  host.contentWindow.addEventListener("DOMContentLoaded", r, { once: true });
     37 });
     38 
     39 async function showErrorPage(doc, errorMessage) {
     40  const win = doc.defaultView;
     41  const { BrowserLoader } = ChromeUtils.importESModule(
     42    "resource://devtools/shared/loader/browser-loader.sys.mjs"
     43  );
     44  const browserRequire = BrowserLoader({
     45    window: win,
     46    useOnlyShared: true,
     47  }).require;
     48 
     49  const React = browserRequire("devtools/client/shared/vendor/react");
     50  const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
     51  const DebugTargetErrorPage = React.createFactory(
     52    require("resource://devtools/client/framework/components/DebugTargetErrorPage.js")
     53  );
     54  const { LocalizationHelper } = browserRequire("devtools/shared/l10n");
     55  const L10N = new LocalizationHelper(
     56    "devtools/client/locales/toolbox.properties"
     57  );
     58 
     59  // mount the React component into our XUL container once the DOM is ready
     60  await onLoad;
     61 
     62  // Update the tab title.
     63  document.title = L10N.getStr("toolbox.debugTargetInfo.tabTitleError");
     64 
     65  const mountEl = doc.querySelector("#toolbox-error-mount");
     66  const element = DebugTargetErrorPage({
     67    errorMessage,
     68    L10N,
     69  });
     70  ReactDOM.render(element, mountEl);
     71 
     72  // make sure we unmount the component when the page is destroyed
     73  win.addEventListener(
     74    "unload",
     75    () => {
     76      ReactDOM.unmountComponentAtNode(mountEl);
     77    },
     78    { once: true }
     79  );
     80 }
     81 
     82 async function initToolbox(url, host) {
     83  const {
     84    gDevTools,
     85  } = require("resource://devtools/client/framework/devtools.js");
     86 
     87  const {
     88    commandsFromURL,
     89  } = require("resource://devtools/client/framework/commands-from-url.js");
     90  const {
     91    Toolbox,
     92  } = require("resource://devtools/client/framework/toolbox.js");
     93 
     94  // Specify the default tool to open
     95  const tool = url.searchParams.get("tool");
     96 
     97  try {
     98    const commands = await commandsFromURL(url);
     99    const toolbox = gDevTools.getToolboxForCommands(commands);
    100    if (toolbox && toolbox.isDestroying()) {
    101      // If a toolbox already exists for the commands, wait for current
    102      // toolbox destroy to be finished.
    103      await toolbox.destroy();
    104    }
    105 
    106    // Display an error page if we are connected to a remote target and we lose it
    107    commands.descriptorFront.once("descriptor-destroyed", function () {
    108      // Prevent trying to display the error page if the toolbox tab is being destroyed
    109      if (host.contentDocument) {
    110        const error = new Error("Debug target was disconnected");
    111        showErrorPage(host.contentDocument, `${error}`);
    112      }
    113    });
    114 
    115    const options = { customIframe: host };
    116    await gDevTools.showToolbox(commands, {
    117      toolId: tool,
    118      hostType: Toolbox.HostType.PAGE,
    119      hostOptions: options,
    120    });
    121  } catch (error) {
    122    // When an error occurs, show error page with message.
    123    console.error("Exception while loading the toolbox", error);
    124    showErrorPage(host.contentDocument, `${error}`);
    125  }
    126 }
    127 
    128 // Only use this method to attach the toolbox if some query parameters are given
    129 if (url.search.length > 1) {
    130  initToolbox(url, host);
    131 }
    132 // TODO: handle no params in about:devtool-toolbox
    133 // https://bugzilla.mozilla.org/show_bug.cgi?id=1526996