tor-browser

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

browser-console-manager.js (4796B)


      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 {
      8  CommandsFactory,
      9 } = require("resource://devtools/shared/commands/commands-factory.js");
     10 
     11 loader.lazyRequireGetter(
     12  this,
     13  "Tools",
     14  "resource://devtools/client/definitions.js",
     15  true
     16 );
     17 loader.lazyRequireGetter(
     18  this,
     19  "l10n",
     20  "resource://devtools/client/webconsole/utils/l10n.js"
     21 );
     22 loader.lazyRequireGetter(
     23  this,
     24  "BrowserConsole",
     25  "resource://devtools/client/webconsole/browser-console.js"
     26 );
     27 
     28 const BC_WINDOW_FEATURES =
     29  "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
     30 
     31 class BrowserConsoleManager {
     32  #browserConsole = null;
     33  #browserConsoleInitializing = null;
     34  #browserConsoleSessionState = false;
     35 
     36  storeBrowserConsoleSessionState() {
     37    this.#browserConsoleSessionState = !!this.getBrowserConsole();
     38  }
     39 
     40  getBrowserConsoleSessionState() {
     41    return this.#browserConsoleSessionState;
     42  }
     43 
     44  /**
     45   * Open a Browser Console for the current commands context.
     46   *
     47   * @param nsIDOMWindow iframeWindow
     48   *        The window where the browser console UI is already loaded.
     49   * @return object
     50   *         A promise object for the opening of the new BrowserConsole instance.
     51   */
     52  async openBrowserConsole(win) {
     53    const hud = new BrowserConsole(this.commands, win, win);
     54    this.#browserConsole = hud;
     55    await hud.init();
     56    return hud;
     57  }
     58 
     59  /**
     60   * Close the opened Browser Console
     61   */
     62  async closeBrowserConsole() {
     63    if (!this.#browserConsole) {
     64      return;
     65    }
     66 
     67    // Ensure destroying the commands,
     68    // even if the console throws during cleanup.
     69    try {
     70      await this.#browserConsole.destroy();
     71    } catch (e) {
     72      console.error(e);
     73    }
     74    this.#browserConsole = null;
     75 
     76    await this.commands.destroy();
     77    this.commands = null;
     78  }
     79 
     80  /**
     81   * Toggle the Browser Console.
     82   */
     83  async toggleBrowserConsole() {
     84    if (this.#browserConsole) {
     85      return this.closeBrowserConsole();
     86    }
     87 
     88    if (this.#browserConsoleInitializing) {
     89      return this.#browserConsoleInitializing;
     90    }
     91 
     92    // Temporarily cache the async startup sequence so that if toggleBrowserConsole
     93    // gets called again we can return this console instead of opening another one.
     94    this.#browserConsoleInitializing = (async () => {
     95      this.commands = await CommandsFactory.forBrowserConsole();
     96      const win = await this.openWindow();
     97      const browserConsole = await this.openBrowserConsole(win);
     98      return browserConsole;
     99    })();
    100 
    101    try {
    102      const browserConsole = await this.#browserConsoleInitializing;
    103      this.#browserConsoleInitializing = null;
    104      return browserConsole;
    105    } catch (e) {
    106      // Ensure always clearing this field, even in case of exception,
    107      // which may happen when closing during initialization.
    108      this.#browserConsoleInitializing = null;
    109      throw e;
    110    }
    111  }
    112 
    113  async openWindow() {
    114    const win = Services.ww.openWindow(
    115      null,
    116      Tools.webConsole.url,
    117      "_blank",
    118      BC_WINDOW_FEATURES,
    119      null
    120    );
    121 
    122    await new Promise(resolve => {
    123      win.addEventListener("DOMContentLoaded", resolve, { once: true });
    124    });
    125 
    126    // It's important to declare the unload *after* the initial "DOMContentLoaded",
    127    // otherwise, since the window is navigated to Tools.webConsole.url, an unload event
    128    // is fired.
    129    win.addEventListener("unload", this.closeBrowserConsole.bind(this), {
    130      once: true,
    131    });
    132 
    133    this.updateWindowTitle(win);
    134    return win;
    135  }
    136 
    137  /**
    138   * Opens or focuses the Browser Console.
    139   */
    140  openBrowserConsoleOrFocus() {
    141    const hud = this.getBrowserConsole();
    142    if (hud) {
    143      hud.iframeWindow.focus();
    144      return Promise.resolve(hud);
    145    }
    146 
    147    return this.toggleBrowserConsole();
    148  }
    149 
    150  /**
    151   * Get the Browser Console instance, if open.
    152   *
    153   * @return object|null
    154   *         A BrowserConsole instance or null if the Browser Console is not
    155   *         open.
    156   */
    157  getBrowserConsole() {
    158    return this.#browserConsole;
    159  }
    160 
    161  /**
    162   * Set the title of the Browser Console window.
    163   *
    164   * @param {Window} win: The BrowserConsole window
    165   */
    166  updateWindowTitle(win) {
    167    let title;
    168    const mode = Services.prefs.getCharPref(
    169      "devtools.browsertoolbox.scope",
    170      null
    171    );
    172    if (mode == "everything") {
    173      title = l10n.getStr("multiProcessBrowserConsole.title");
    174    } else if (mode == "parent-process") {
    175      title = l10n.getStr("parentProcessBrowserConsole.title");
    176    } else {
    177      throw new Error("Unsupported mode: " + mode);
    178    }
    179 
    180    win.document.title = title;
    181  }
    182 }
    183 
    184 exports.BrowserConsoleManager = new BrowserConsoleManager();