tor-browser

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

webext-panels.js (6355B)


      1 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 // Via webext-panels.xhtml
      7 /* import-globals-from browser.js */
      8 /* global windowRoot */
      9 
     10 ChromeUtils.defineESModuleGetters(this, {
     11  ExtensionParent: "resource://gre/modules/ExtensionParent.sys.mjs",
     12 });
     13 
     14 const { ExtensionUtils } = ChromeUtils.importESModule(
     15  "resource://gre/modules/ExtensionUtils.sys.mjs"
     16 );
     17 
     18 var { promiseEvent } = ExtensionUtils;
     19 
     20 function getBrowser(panel) {
     21  let browser = document.getElementById("webext-panels-browser");
     22  if (browser) {
     23    return Promise.resolve(browser);
     24  }
     25 
     26  if (panel.viewType === "sidebar" && gSidebarRevampEnabled) {
     27    if (!customElements.get("sidebar-panel-header")) {
     28      ChromeUtils.importESModule(
     29        "chrome://browser/content/sidebar/sidebar-panel-header.mjs",
     30        { global: "current" }
     31      );
     32    }
     33    const heading =
     34      panel.extension.manifest.sidebar_action.default_title ??
     35      panel.extension.name;
     36    document.getElementById("sidebar-panel-header").heading = heading;
     37  }
     38 
     39  let stack = document.getElementById("webext-panels-stack");
     40  if (!stack) {
     41    stack = document.createXULElement("stack");
     42    stack.setAttribute("flex", "1");
     43    stack.setAttribute("id", "webext-panels-stack");
     44    document.documentElement.appendChild(stack);
     45  }
     46 
     47  browser = document.createXULElement("browser");
     48  browser.setAttribute("id", "webext-panels-browser");
     49  browser.setAttribute("type", "content");
     50  browser.setAttribute("flex", "1");
     51  browser.setAttribute("disableglobalhistory", "true");
     52  browser.setAttribute("messagemanagergroup", "webext-browsers");
     53  browser.setAttribute("webextension-view-type", panel.viewType);
     54  browser.setAttribute("context", "contentAreaContextMenu");
     55  browser.setAttribute("tooltip", "aHTMLTooltip");
     56  browser.setAttribute("autocompletepopup", "PopupAutoComplete");
     57 
     58  if (gAllowTransparentBrowser) {
     59    browser.setAttribute("transparent", "true");
     60  }
     61 
     62  // Ensure that the browser is going to run in the same bc group as the other
     63  // extension pages from the same addon.
     64  browser.setAttribute(
     65    "initialBrowsingContextGroupId",
     66    panel.extension.policy.browsingContextGroupId
     67  );
     68 
     69  let readyPromise;
     70  if (panel.extension.remote) {
     71    browser.setAttribute("remote", "true");
     72    let oa = E10SUtils.predictOriginAttributes({ browser });
     73    browser.setAttribute(
     74      "remoteType",
     75      E10SUtils.getRemoteTypeForURI(
     76        panel.uri,
     77        /* remote */ true,
     78        /* fission */ false,
     79        E10SUtils.EXTENSION_REMOTE_TYPE,
     80        null,
     81        oa
     82      )
     83    );
     84    browser.setAttribute("maychangeremoteness", "true");
     85 
     86    readyPromise = promiseEvent(browser, "XULFrameLoaderCreated");
     87  } else {
     88    readyPromise = Promise.resolve();
     89  }
     90 
     91  stack.appendChild(browser);
     92 
     93  browser.addEventListener(
     94    "DoZoomEnlargeBy10",
     95    () => {
     96      let { ZoomManager } = browser.ownerGlobal;
     97      let zoom = browser.fullZoom;
     98      zoom += 0.1;
     99      if (zoom > ZoomManager.MAX) {
    100        zoom = ZoomManager.MAX;
    101      }
    102      browser.fullZoom = zoom;
    103    },
    104    true
    105  );
    106  browser.addEventListener(
    107    "DoZoomReduceBy10",
    108    () => {
    109      let { ZoomManager } = browser.ownerGlobal;
    110      let zoom = browser.fullZoom;
    111      zoom -= 0.1;
    112      if (zoom < ZoomManager.MIN) {
    113        zoom = ZoomManager.MIN;
    114      }
    115      browser.fullZoom = zoom;
    116    },
    117    true
    118  );
    119  browser.addEventListener("DOMWindowClose", event => {
    120    if (panel.viewType == "sidebar") {
    121      windowRoot.ownerGlobal.SidebarController.hide();
    122    }
    123    // Prevent DOMWindowClose events originated from
    124    // extensions sidebar and devtools panels to bubble up
    125    // to the gBrowser DOMWindowClose listener and
    126    // be mistaken as being originated from a tab being closed
    127    // (See Bug 1926373)
    128    event.stopPropagation();
    129  });
    130 
    131  const initBrowser = () => {
    132    ExtensionParent.apiManager.emit(
    133      "extension-browser-inserted",
    134      browser,
    135      panel.browserInsertedData
    136    );
    137 
    138    browser.messageManager.loadFrameScript(
    139      "chrome://extensions/content/ext-browser-content.js",
    140      false,
    141      true
    142    );
    143 
    144    let options = {};
    145    if (panel.browserStyle) {
    146      options.stylesheets = ["chrome://browser/content/extension.css"];
    147    }
    148    browser.messageManager.sendAsyncMessage("Extension:InitBrowser", options);
    149    return browser;
    150  };
    151 
    152  browser.addEventListener("DidChangeBrowserRemoteness", initBrowser);
    153  return readyPromise.then(initBrowser);
    154 }
    155 
    156 // Stub tabbrowser implementation to make sure that links from inside
    157 // extension sidebar panels open in new tabs, see bug 1488055.
    158 var gBrowser = {
    159  get selectedBrowser() {
    160    return document.getElementById("webext-panels-browser");
    161  },
    162 
    163  getTabForBrowser() {
    164    return null;
    165  },
    166 };
    167 
    168 function updatePosition() {
    169  // We need both of these to make sure we update the position
    170  // after any lower level updates have finished.
    171  requestAnimationFrame(() =>
    172    setTimeout(() => {
    173      let browser = document.getElementById("webext-panels-browser");
    174      if (browser && browser.isRemoteBrowser) {
    175        browser.frameLoader.requestUpdatePosition();
    176      }
    177    }, 0)
    178  );
    179 }
    180 
    181 function loadPanel(extensionId, extensionUrl, browserStyle) {
    182  let browserEl = document.getElementById("webext-panels-browser");
    183  if (browserEl) {
    184    if (browserEl.currentURI.spec === extensionUrl) {
    185      return;
    186    }
    187    // Forces runtime disconnect.  Remove the stack (parent).
    188    browserEl.parentNode.remove();
    189  }
    190 
    191  let policy = WebExtensionPolicy.getByID(extensionId);
    192 
    193  let sidebar = {
    194    uri: extensionUrl,
    195    extension: policy.extension,
    196    browserStyle,
    197    viewType: "sidebar",
    198  };
    199 
    200  getBrowser(sidebar).then(browser => {
    201    let uri = Services.io.newURI(policy.getURL());
    202    let triggeringPrincipal =
    203      Services.scriptSecurityManager.createContentPrincipal(uri, {});
    204    browser.fixupAndLoadURIString(extensionUrl, { triggeringPrincipal });
    205  });
    206 }
    207 
    208 XPCOMUtils.defineLazyPreferenceGetter(
    209  this,
    210  "gAllowTransparentBrowser",
    211  "browser.tabs.allow_transparent_browser",
    212  false
    213 );
    214 
    215 XPCOMUtils.defineLazyPreferenceGetter(
    216  this,
    217  "gSidebarRevampEnabled",
    218  "sidebar.revamp",
    219  false
    220 );