/* 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();