summaryrefslogtreecommitdiffstats
path: root/browser/base/content/webext-panels.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--browser/base/content/webext-panels.js184
1 files changed, 184 insertions, 0 deletions
diff --git a/browser/base/content/webext-panels.js b/browser/base/content/webext-panels.js
new file mode 100644
index 0000000000..d9f8b03a29
--- /dev/null
+++ b/browser/base/content/webext-panels.js
@@ -0,0 +1,184 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Via webext-panels.xhtml
+/* import-globals-from browser.js */
+/* import-globals-from nsContextMenu.js */
+
+ChromeUtils.defineESModuleGetters(this, {
+ ExtensionParent: "resource://gre/modules/ExtensionParent.sys.mjs",
+});
+
+const { ExtensionUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/ExtensionUtils.sys.mjs"
+);
+
+var { promiseEvent } = ExtensionUtils;
+
+function getBrowser(panel) {
+ let browser = document.getElementById("webext-panels-browser");
+ if (browser) {
+ return Promise.resolve(browser);
+ }
+
+ let stack = document.getElementById("webext-panels-stack");
+ if (!stack) {
+ stack = document.createXULElement("stack");
+ stack.setAttribute("flex", "1");
+ stack.setAttribute("id", "webext-panels-stack");
+ document.documentElement.appendChild(stack);
+ }
+
+ browser = document.createXULElement("browser");
+ browser.setAttribute("id", "webext-panels-browser");
+ browser.setAttribute("type", "content");
+ browser.setAttribute("flex", "1");
+ browser.setAttribute("disableglobalhistory", "true");
+ browser.setAttribute("messagemanagergroup", "webext-browsers");
+ browser.setAttribute("webextension-view-type", panel.viewType);
+ browser.setAttribute("context", "contentAreaContextMenu");
+ browser.setAttribute("tooltip", "aHTMLTooltip");
+ browser.setAttribute("autocompletepopup", "PopupAutoComplete");
+
+ // Ensure that the browser is going to run in the same bc group as the other
+ // extension pages from the same addon.
+ browser.setAttribute(
+ "initialBrowsingContextGroupId",
+ panel.extension.policy.browsingContextGroupId
+ );
+
+ let readyPromise;
+ if (panel.extension.remote) {
+ browser.setAttribute("remote", "true");
+ let oa = E10SUtils.predictOriginAttributes({ browser });
+ browser.setAttribute(
+ "remoteType",
+ E10SUtils.getRemoteTypeForURI(
+ panel.uri,
+ /* remote */ true,
+ /* fission */ false,
+ E10SUtils.EXTENSION_REMOTE_TYPE,
+ null,
+ oa
+ )
+ );
+ browser.setAttribute("maychangeremoteness", "true");
+
+ readyPromise = promiseEvent(browser, "XULFrameLoaderCreated");
+ } else {
+ readyPromise = Promise.resolve();
+ }
+
+ stack.appendChild(browser);
+
+ browser.addEventListener(
+ "DoZoomEnlargeBy10",
+ () => {
+ let { ZoomManager } = browser.ownerGlobal;
+ let zoom = browser.fullZoom;
+ zoom += 0.1;
+ if (zoom > ZoomManager.MAX) {
+ zoom = ZoomManager.MAX;
+ }
+ browser.fullZoom = zoom;
+ },
+ true
+ );
+ browser.addEventListener(
+ "DoZoomReduceBy10",
+ () => {
+ let { ZoomManager } = browser.ownerGlobal;
+ let zoom = browser.fullZoom;
+ zoom -= 0.1;
+ if (zoom < ZoomManager.MIN) {
+ zoom = ZoomManager.MIN;
+ }
+ browser.fullZoom = zoom;
+ },
+ true
+ );
+
+ const initBrowser = () => {
+ ExtensionParent.apiManager.emit(
+ "extension-browser-inserted",
+ browser,
+ panel.browserInsertedData
+ );
+
+ browser.messageManager.loadFrameScript(
+ "chrome://extensions/content/ext-browser-content.js",
+ false,
+ true
+ );
+
+ let options =
+ panel.browserStyle !== false
+ ? { stylesheets: ExtensionParent.extensionStylesheets }
+ : {};
+ browser.messageManager.sendAsyncMessage("Extension:InitBrowser", options);
+ return browser;
+ };
+
+ browser.addEventListener("DidChangeBrowserRemoteness", initBrowser);
+ return readyPromise.then(initBrowser);
+}
+
+// Stub tabbrowser implementation for use by the tab-modal alert code.
+var gBrowser = {
+ get selectedBrowser() {
+ return document.getElementById("webext-panels-browser");
+ },
+
+ getTabForBrowser(browser) {
+ return null;
+ },
+
+ getTabModalPromptBox(browser) {
+ if (!browser.tabModalPromptBox) {
+ browser.tabModalPromptBox = new TabModalPromptBox(browser);
+ }
+ return browser.tabModalPromptBox;
+ },
+};
+
+function updatePosition() {
+ // We need both of these to make sure we update the position
+ // after any lower level updates have finished.
+ requestAnimationFrame(() =>
+ setTimeout(() => {
+ let browser = document.getElementById("webext-panels-browser");
+ if (browser && browser.isRemoteBrowser) {
+ browser.frameLoader.requestUpdatePosition();
+ }
+ }, 0)
+ );
+}
+
+function loadPanel(extensionId, extensionUrl, browserStyle) {
+ let browserEl = document.getElementById("webext-panels-browser");
+ if (browserEl) {
+ if (browserEl.currentURI.spec === extensionUrl) {
+ return;
+ }
+ // Forces runtime disconnect. Remove the stack (parent).
+ browserEl.parentNode.remove();
+ }
+
+ let policy = WebExtensionPolicy.getByID(extensionId);
+
+ let sidebar = {
+ uri: extensionUrl,
+ extension: policy.extension,
+ browserStyle,
+ viewType: "sidebar",
+ };
+
+ getBrowser(sidebar).then(browser => {
+ let uri = Services.io.newURI(policy.getURL());
+ let triggeringPrincipal =
+ Services.scriptSecurityManager.createContentPrincipal(uri, {});
+ browser.fixupAndLoadURIString(extensionUrl, { triggeringPrincipal });
+ });
+}