summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/browser-console-manager.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/webconsole/browser-console-manager.js')
-rw-r--r--devtools/client/webconsole/browser-console-manager.js186
1 files changed, 186 insertions, 0 deletions
diff --git a/devtools/client/webconsole/browser-console-manager.js b/devtools/client/webconsole/browser-console-manager.js
new file mode 100644
index 0000000000..b38391f685
--- /dev/null
+++ b/devtools/client/webconsole/browser-console-manager.js
@@ -0,0 +1,186 @@
+/* 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/. */
+
+"use strict";
+
+const {
+ CommandsFactory,
+} = require("resource://devtools/shared/commands/commands-factory.js");
+
+loader.lazyRequireGetter(
+ this,
+ "Tools",
+ "resource://devtools/client/definitions.js",
+ true
+);
+loader.lazyRequireGetter(
+ this,
+ "l10n",
+ "resource://devtools/client/webconsole/utils/l10n.js"
+);
+loader.lazyRequireGetter(
+ this,
+ "BrowserConsole",
+ "resource://devtools/client/webconsole/browser-console.js"
+);
+
+const BC_WINDOW_FEATURES =
+ "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
+
+class BrowserConsoleManager {
+ constructor() {
+ this._browserConsole = null;
+ this._browserConsoleInitializing = null;
+ this._browerConsoleSessionState = false;
+ }
+
+ storeBrowserConsoleSessionState() {
+ this._browerConsoleSessionState = !!this.getBrowserConsole();
+ }
+
+ getBrowserConsoleSessionState() {
+ return this._browerConsoleSessionState;
+ }
+
+ /**
+ * Open a Browser Console for the current commands context.
+ *
+ * @param nsIDOMWindow iframeWindow
+ * The window where the browser console UI is already loaded.
+ * @return object
+ * A promise object for the opening of the new BrowserConsole instance.
+ */
+ async openBrowserConsole(win) {
+ const hud = new BrowserConsole(this.commands, win, win);
+ this._browserConsole = hud;
+ await hud.init();
+ return hud;
+ }
+
+ /**
+ * Close the opened Browser Console
+ */
+ async closeBrowserConsole() {
+ if (!this._browserConsole) {
+ return;
+ }
+
+ // Ensure destroying the commands,
+ // even if the console throws during cleanup.
+ try {
+ await this._browserConsole.destroy();
+ } catch (e) {
+ console.error(e);
+ }
+ this._browserConsole = null;
+
+ await this.commands.destroy();
+ this.commands = null;
+ }
+
+ /**
+ * Toggle the Browser Console.
+ */
+ async toggleBrowserConsole() {
+ if (this._browserConsole) {
+ return this.closeBrowserConsole();
+ }
+
+ if (this._browserConsoleInitializing) {
+ return this._browserConsoleInitializing;
+ }
+
+ // Temporarily cache the async startup sequence so that if toggleBrowserConsole
+ // gets called again we can return this console instead of opening another one.
+ this._browserConsoleInitializing = (async () => {
+ this.commands = await CommandsFactory.forBrowserConsole();
+ const win = await this.openWindow();
+ const browserConsole = await this.openBrowserConsole(win);
+ return browserConsole;
+ })();
+
+ try {
+ const browserConsole = await this._browserConsoleInitializing;
+ this._browserConsoleInitializing = null;
+ return browserConsole;
+ } catch (e) {
+ // Ensure always clearing this field, even in case of exception,
+ // which may happen when closing during initialization.
+ this._browserConsoleInitializing = null;
+ throw e;
+ }
+ }
+
+ async openWindow() {
+ const win = Services.ww.openWindow(
+ null,
+ Tools.webConsole.url,
+ "_blank",
+ BC_WINDOW_FEATURES,
+ null
+ );
+
+ await new Promise(resolve => {
+ win.addEventListener("DOMContentLoaded", resolve, { once: true });
+ });
+
+ // It's important to declare the unload *after* the initial "DOMContentLoaded",
+ // otherwise, since the window is navigated to Tools.webConsole.url, an unload event
+ // is fired.
+ win.addEventListener("unload", this.closeBrowserConsole.bind(this), {
+ once: true,
+ });
+
+ this.updateWindowTitle(win);
+ return win;
+ }
+
+ /**
+ * Opens or focuses the Browser Console.
+ */
+ openBrowserConsoleOrFocus() {
+ const hud = this.getBrowserConsole();
+ if (hud) {
+ hud.iframeWindow.focus();
+ return Promise.resolve(hud);
+ }
+
+ return this.toggleBrowserConsole();
+ }
+
+ /**
+ * Get the Browser Console instance, if open.
+ *
+ * @return object|null
+ * A BrowserConsole instance or null if the Browser Console is not
+ * open.
+ */
+ getBrowserConsole() {
+ return this._browserConsole;
+ }
+
+ /**
+ * Set the title of the Browser Console window.
+ *
+ * @param {Window} win: The BrowserConsole window
+ */
+ updateWindowTitle(win) {
+ let title;
+ const mode = Services.prefs.getCharPref(
+ "devtools.browsertoolbox.scope",
+ null
+ );
+ if (mode == "everything") {
+ title = l10n.getStr("multiProcessBrowserConsole.title");
+ } else if (mode == "parent-process") {
+ title = l10n.getStr("parentProcessBrowserConsole.title");
+ } else {
+ throw new Error("Unsupported mode: " + mode);
+ }
+
+ win.document.title = title;
+ }
+}
+
+exports.BrowserConsoleManager = new BrowserConsoleManager();