diff options
Diffstat (limited to 'devtools/client/webconsole/browser-console-manager.js')
-rw-r--r-- | devtools/client/webconsole/browser-console-manager.js | 186 |
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(); |