Bug 1570320 - Rename hudservice into browser-console-manager. r=ochameau.
authorNicolas Chevobbe <nchevobbe@mozilla.com>
Mon, 05 Aug 2019 11:40:58 +0000
changeset 486172 723d5f102a28e3871e0b25d1e81e0c62be213a17
parent 486171 87356d9276c51181c022c981eca992197a7b1c81
child 486173 dfb2d2aae87eab8ff5d63fdbf4d5e1dc9aff0af6
push id36391
push usermalexandru@mozilla.com
push dateMon, 05 Aug 2019 15:55:27 +0000
treeherdermozilla-central@9c91b33629b6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau
bugs1570320
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1570320 - Rename hudservice into browser-console-manager. r=ochameau. The file only manages the browser console, so we're making its name reflect what it does. Differential Revision: https://phabricator.services.mozilla.com/D40441
devtools/client/framework/devtools-browser.js
devtools/client/framework/devtools.js
devtools/client/framework/toolbox.js
devtools/client/menus.js
devtools/client/scratchpad/scratchpad.js
devtools/client/scratchpad/test/browser_scratchpad_open_error_console.js
devtools/client/webconsole/browser-console-manager.js
devtools/client/webconsole/browser-console.js
devtools/client/webconsole/hudservice.js
devtools/client/webconsole/moz.build
devtools/client/webconsole/test/mochitest/browser_console.js
devtools/client/webconsole/test/mochitest/browser_console_chrome_context_message.js
devtools/client/webconsole/test/mochitest/browser_console_clear_cache.js
devtools/client/webconsole/test/mochitest/browser_console_clear_method.js
devtools/client/webconsole/test/mochitest/browser_console_consolejsm_output.js
devtools/client/webconsole/test/mochitest/browser_console_context_menu_entries.js
devtools/client/webconsole/test/mochitest/browser_console_cpow.js
devtools/client/webconsole/test/mochitest/browser_console_dead_objects.js
devtools/client/webconsole/test/mochitest/browser_console_devtools_loader_exception.js
devtools/client/webconsole/test/mochitest/browser_console_error_source_click.js
devtools/client/webconsole/test/mochitest/browser_console_filters.js
devtools/client/webconsole/test/mochitest/browser_console_jsterm_await.js
devtools/client/webconsole/test/mochitest/browser_console_nsiconsolemessage.js
devtools/client/webconsole/test/mochitest/browser_console_open_or_focus.js
devtools/client/webconsole/test/mochitest/browser_console_restore.js
devtools/client/webconsole/test/mochitest/browser_console_webconsole_console_api_calls.js
devtools/client/webconsole/test/mochitest/browser_console_webconsole_ctrlw_close_tab.js
devtools/client/webconsole/test/mochitest/browser_console_webconsole_iframe_messages.js
devtools/client/webconsole/test/mochitest/browser_console_webconsole_private_browsing.js
devtools/client/webconsole/test/mochitest/browser_jsterm_hide_when_devtools_chrome_enabled_false.js
devtools/client/webconsole/test/mochitest/browser_webconsole_network_requests_from_chrome.js
devtools/client/webconsole/test/mochitest/head.js
devtools/docs/tools/console-panel.md
devtools/startup/DevToolsStartup.jsm
toolkit/components/extensions/test/mochitest/test_ext_background_page.html
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -347,18 +347,20 @@ var gDevToolsBrowser = (exports.gDevTool
         break;
       case "webide":
         gDevToolsBrowser.openWebIDE();
         break;
       case "browserToolbox":
         BrowserToolboxProcess.init();
         break;
       case "browserConsole":
-        const { HUDService } = require("devtools/client/webconsole/hudservice");
-        HUDService.openBrowserConsoleOrFocus();
+        const {
+          BrowserConsoleManager,
+        } = require("devtools/client/webconsole/browser-console-manager");
+        BrowserConsoleManager.openBrowserConsoleOrFocus();
         break;
       case "responsiveDesignMode":
         ResponsiveUIManager.toggle(window, window.gBrowser.selectedTab, {
           trigger: "shortcut",
         });
         break;
       case "scratchpad":
         ScratchpadManager.openScratchpad();
--- a/devtools/client/framework/devtools.js
+++ b/devtools/client/framework/devtools.js
@@ -20,18 +20,18 @@ loader.lazyRequireGetter(
 loader.lazyRequireGetter(
   this,
   "ToolboxHostManager",
   "devtools/client/framework/toolbox-host-manager",
   true
 );
 loader.lazyRequireGetter(
   this,
-  "HUDService",
-  "devtools/client/webconsole/hudservice",
+  "BrowserConsoleManager",
+  "devtools/client/webconsole/browser-console-manager",
   true
 );
 loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
 loader.lazyImporter(
   this,
   "ScratchpadManager",
   "resource://devtools/client/scratchpad/scratchpad-manager.jsm"
 );
@@ -423,17 +423,17 @@ DevTools.prototype = {
 
   /**
    * Called from SessionStore.jsm in mozilla-central when saving the current state.
    *
    * @param {Object} state
    *                 A SessionStore state object that gets modified by reference
    */
   saveDevToolsSession: function(state) {
-    state.browserConsole = HUDService.getBrowserConsoleSessionState();
+    state.browserConsole = BrowserConsoleManager.getBrowserConsoleSessionState();
     state.browserToolbox = BrowserToolboxProcess.getBrowserToolboxSessionState();
 
     // Check if the module is loaded to avoid loading ScratchpadManager for no reason.
     state.scratchpads = [];
     if (
       Cu.isModuleLoaded(
         "resource://devtools/client/scratchpad/scratchpad-manager.jsm"
       )
@@ -453,18 +453,18 @@ DevTools.prototype = {
     if (scratchpads) {
       ScratchpadManager.restoreSession(scratchpads);
     }
 
     if (browserToolbox) {
       BrowserToolboxProcess.init();
     }
 
-    if (browserConsole && !HUDService.getBrowserConsole()) {
-      HUDService.toggleBrowserConsole();
+    if (browserConsole && !BrowserConsoleManager.getBrowserConsole()) {
+      BrowserConsoleManager.toggleBrowserConsole();
     }
   },
 
   /**
    * Boolean, true, if we never opened a toolbox.
    * Used to implement the telemetry tracking toolbox opening.
    */
   _firstShowToolbox: true,
@@ -700,18 +700,20 @@ DevTools.prototype = {
     return tabTarget.getFront("webExtensionInspectedWindow");
   },
 
   /**
    * Compatibility layer for web-extensions. Used by DevToolsShim for
    * toolkit/components/extensions/ext-c-toolkit.js
    */
   openBrowserConsole: function() {
-    const { HUDService } = require("devtools/client/webconsole/hudservice");
-    HUDService.openBrowserConsoleOrFocus();
+    const {
+      BrowserConsoleManager,
+    } = require("devtools/client/webconsole/browser-console-manager");
+    BrowserConsoleManager.openBrowserConsoleOrFocus();
   },
 
   /**
    * Evaluate the cross iframes query selectors
    * @oaram {Object} walker
    * @param {Array} selectors
    *        An array of CSS selectors to find the target accessible object.
    *        Several selectors can be needed if the element is nested in frames
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -71,18 +71,18 @@ loader.lazyRequireGetter(
 loader.lazyRequireGetter(
   this,
   "SourceMapURLService",
   "devtools/client/framework/source-map-url-service",
   true
 );
 loader.lazyRequireGetter(
   this,
-  "HUDService",
-  "devtools/client/webconsole/hudservice",
+  "BrowserConsoleManager",
+  "devtools/client/webconsole/browser-console-manager",
   true
 );
 loader.lazyRequireGetter(
   this,
   "viewSource",
   "devtools/client/shared/view-source"
 );
 loader.lazyRequireGetter(
@@ -956,17 +956,17 @@ Toolbox.prototype = {
 
     for (const item of Startup.KeyShortcuts) {
       const { id, toolId, shortcut, modifiers } = item;
       const electronKey = KeyShortcuts.parseXulKey(modifiers, shortcut);
 
       if (id == "browserConsole") {
         // Add key for toggling the browser console from the detached window
         shortcuts.on(electronKey, () => {
-          HUDService.toggleBrowserConsole();
+          BrowserConsoleManager.toggleBrowserConsole();
         });
       } else if (toolId) {
         // KeyShortcuts contain tool-specific and global key shortcuts,
         // here we only need to copy shortcut specific to each tool.
         shortcuts.on(electronKey, () => {
           this.selectTool(toolId, "key_shortcut").then(() =>
             this.fireCustomKey(toolId)
           );
--- a/devtools/client/menus.js
+++ b/devtools/client/menus.js
@@ -115,18 +115,20 @@ exports.menuitems = [
       const window = event.target.ownerDocument.defaultView;
       gDevToolsBrowser.openContentProcessToolbox(window.gBrowser);
     },
   },
   {
     id: "menu_browserConsole",
     l10nKey: "browserConsoleCmd",
     oncommand() {
-      const { HUDService } = require("devtools/client/webconsole/hudservice");
-      HUDService.openBrowserConsoleOrFocus();
+      const {
+        BrowserConsoleManager,
+      } = require("devtools/client/webconsole/browser-console-manager");
+      BrowserConsoleManager.openBrowserConsoleOrFocus();
     },
     keyId: "browserConsole",
   },
   {
     id: "menu_toggleProfilerButtonMenu",
     l10nKey: "toggleProfilerButtonMenu",
     checkbox: true,
     oncommand(event) {
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -122,18 +122,18 @@ loader.lazyRequireGetter(
 );
 loader.lazyRequireGetter(
   this,
   "ObjectClient",
   "devtools/shared/client/object-client"
 );
 loader.lazyRequireGetter(
   this,
-  "HUDService",
-  "devtools/client/webconsole/hudservice",
+  "BrowserConsoleManager",
+  "devtools/client/webconsole/browser-console-manager",
   true
 );
 loader.lazyRequireGetter(
   this,
   "openDocLink",
   "devtools/client/shared/link",
   true
 );
@@ -1581,17 +1581,17 @@ var Scratchpad = {
       aCallback(false);
     }
   },
 
   /**
    * Open the Error Console.
    */
   openErrorConsole: function SP_openErrorConsole() {
-    HUDService.toggleBrowserConsole();
+    BrowserConsoleManager.toggleBrowserConsole();
   },
 
   /**
    * Open the Web Console.
    */
   openWebConsole: async function SP_openWebConsole() {
     const target = await TargetFactory.forTab(this.gBrowser.selectedTab);
     gDevTools.showToolbox(target, "webconsole");
--- a/devtools/client/scratchpad/test/browser_scratchpad_open_error_console.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_open_error_console.js
@@ -1,13 +1,15 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const { HUDService } = require("devtools/client/webconsole/hudservice");
+const {
+  BrowserConsoleManager,
+} = require("devtools/client/webconsole/browser-console-manager");
 
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
@@ -18,21 +20,21 @@ function test() {
   );
 }
 
 function runTests() {
   Services.obs.addObserver(function observer(aSubject) {
     Services.obs.removeObserver(observer, "web-console-created");
     aSubject.QueryInterface(Ci.nsISupportsString);
 
-    const hud = HUDService.getBrowserConsole();
+    const hud = BrowserConsoleManager.getBrowserConsole();
     ok(hud, "browser console is open");
     is(aSubject.data, hud.hudId, "notification hudId is correct");
 
-    HUDService.toggleBrowserConsole().then(finish);
+    BrowserConsoleManager.toggleBrowserConsole().then(finish);
   }, "web-console-created");
 
-  const hud = HUDService.getBrowserConsole();
+  const hud = BrowserConsoleManager.getBrowserConsole();
   ok(!hud, "browser console is not open");
   info("wait for the browser console to open from Scratchpad");
 
   gScratchpadWindow.Scratchpad.openErrorConsole();
 }
rename from devtools/client/webconsole/hudservice.js
rename to devtools/client/webconsole/browser-console-manager.js
--- a/devtools/client/webconsole/hudservice.js
+++ b/devtools/client/webconsole/browser-console-manager.js
@@ -17,54 +17,53 @@ loader.lazyRequireGetter(
   this,
   "BrowserConsole",
   "devtools/client/webconsole/browser-console"
 );
 
 const BC_WINDOW_FEATURES =
   "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
 
-function HUDService() {}
-
-HUDService.prototype = {
-  _browserConsole: null,
-  _browserConsoleInitializing: null,
-
-  _browerConsoleSessionState: false,
+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 given target.
    *
    * @see devtools/framework/target.js for details about targets.
    *
    * @param object target
    *        The target that the browser console will connect to.
    * @param nsIDOMWindow iframeWindow
    *        The window where the browser console UI is already loaded.
    * @param Boolean fissionSupport
    * @return object
    *         A promise object for the opening of the new BrowserConsole instance.
    */
   async openBrowserConsole(target, win, fissionSupport = false) {
-    const hud = new BrowserConsole(target, win, win, this, fissionSupport);
+    const hud = new BrowserConsole(target, win, win, fissionSupport);
     this._browserConsole = hud;
     hud.once("destroyed", () => {
       this._browserConsole = null;
     });
     await hud.init();
     return hud;
-  },
+  }
 
   /**
    * Toggle the Browser Console.
    */
   async toggleBrowserConsole() {
     if (this._browserConsole) {
       const hud = this._browserConsole;
       return hud.destroy();
@@ -142,36 +141,36 @@ HUDService.prototype = {
         fissionSupport
       );
       return browserConsole;
     })();
 
     const browserConsole = await this._browserConsoleInitializing;
     this._browserConsoleInitializing = null;
     return browserConsole;
-  },
+  }
 
   /**
    * 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;
-  },
-};
+  }
+}
 
-exports.HUDService = new HUDService();
+exports.BrowserConsoleManager = new BrowserConsoleManager();
--- a/devtools/client/webconsole/browser-console.js
+++ b/devtools/client/webconsole/browser-console.js
@@ -5,18 +5,18 @@
 "use strict";
 
 var Services = require("Services");
 var WebConsole = require("devtools/client/webconsole/webconsole");
 
 loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
 loader.lazyRequireGetter(
   this,
-  "HUDService",
-  "devtools/client/webconsole/hudservice",
+  "BrowserConsoleManager",
+  "devtools/client/webconsole/browser-console-manager",
   true
 );
 
 /**
  * A BrowserConsole instance is an interactive console initialized *per target*
  * that displays console log data as well as provides an interactive terminal to
  * manipulate the target's document content.
  *
@@ -31,26 +31,18 @@ class BrowserConsole extends WebConsole 
    * @constructor
    * @param object target
    *        The target that the browser console will connect to.
    * @param nsIDOMWindow iframeWindow
    *        The window where the browser console UI is already loaded.
    * @param nsIDOMWindow chromeWindow
    *        The window of the browser console owner.
    * @param Boolean fissionSupport
-   * @param object hudService
-   *        The parent HUD Service
    */
-  constructor(
-    target,
-    iframeWindow,
-    chromeWindow,
-    hudService,
-    fissionSupport = false
-  ) {
+  constructor(target, iframeWindow, chromeWindow, fissionSupport = false) {
     super(target, iframeWindow, chromeWindow, true, fissionSupport);
 
     this._telemetry = new Telemetry();
     this._bcInitializer = null;
     this._bcDestroyer = null;
   }
 
   /**
@@ -126,17 +118,17 @@ var ShutdownObserver = {
 
     Services.obs.addObserver(this, "quit-application-granted");
 
     this._initialized = true;
   },
 
   observe(message, topic) {
     if (topic == "quit-application-granted") {
-      HUDService.storeBrowserConsoleSessionState();
+      BrowserConsoleManager.storeBrowserConsoleSessionState();
       this.uninit();
     }
   },
 
   uninit() {
     Services.obs.removeObserver(this, "quit-application-granted");
   },
 };
--- a/devtools/client/webconsole/moz.build
+++ b/devtools/client/webconsole/moz.build
@@ -10,19 +10,19 @@ DIRS += [
     'enhancers',
     'middleware',
     'reducers',
     'selectors',
     'test',
     'utils',
 ]
 DevToolsModules(
+    'browser-console-manager.js',
     'browser-console.js',
     'constants.js',
-    'hudservice.js',
     'panel.js',
     'store.js',
     'types.js',
     'utils.js',
     'webconsole-connection-proxy.js',
     'webconsole-ui.js',
     'webconsole-wrapper.js',
     'webconsole.js',
--- a/devtools/client/webconsole/test/mochitest/browser_console.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console.js
@@ -23,17 +23,17 @@ const TEST_IMAGE =
   "test/test-image.png";
 
 add_task(async function() {
   await pushPref("devtools.browserconsole.contentMessages", true);
   await addTab(TEST_URI);
 
   const opened = waitForBrowserConsole();
 
-  let hud = HUDService.getBrowserConsole();
+  let hud = BrowserConsoleManager.getBrowserConsole();
   ok(!hud, "browser console is not open");
   info("wait for the browser console to open with ctrl-shift-j");
   EventUtils.synthesizeKey("j", { accelKey: true, shiftKey: true }, window);
 
   hud = await opened;
   ok(hud, "browser console opened");
 
   await setFilterState(hud, {
--- a/devtools/client/webconsole/test/mochitest/browser_console_chrome_context_message.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_chrome_context_message.js
@@ -5,17 +5,17 @@
 // Test that console API calls in the content page appear in the browser console.
 
 "use strict";
 
 add_task(async function() {
   // Show the content messages
   await pushPref("devtools.browserconsole.contentMessages", true);
 
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
   await hud.ui.clearOutput();
   await openNewTabAndConsole(
     `data:text/html,<script>console.log("hello from content")</script>`
   );
 
   const expectedMessages = [
     `Cu.reportError`, // bug 1561930
   ];
--- a/devtools/client/webconsole/test/mochitest/browser_console_clear_cache.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_clear_cache.js
@@ -6,17 +6,17 @@
 
 "use strict";
 
 const TEST_URI = "data:text/html;charset=utf8,Test browser console clear cache";
 
 add_task(async function() {
   await pushPref("devtools.browserconsole.contentMessages", true);
   await addTab(TEST_URI);
-  let hud = await HUDService.toggleBrowserConsole();
+  let hud = await BrowserConsoleManager.toggleBrowserConsole();
   const CACHED_MESSAGE = "CACHED_MESSAGE";
   await logTextToConsole(hud, CACHED_MESSAGE);
 
   info("Click the clear output button");
   const onBrowserConsoleOutputCleared = waitFor(
     () => !findMessage(hud, CACHED_MESSAGE)
   );
   hud.ui.window.document.querySelector(".devtools-clear-icon").click();
@@ -24,18 +24,18 @@ add_task(async function() {
 
   // Check that there are no other messages logged (see Bug 1457478).
   // Log a message to make sure the console handled any prior log.
   await logTextToConsole(hud, "after clear");
   const messages = hud.ui.outputNode.querySelectorAll(".message");
   is(messages.length, 1, "There is only the new message in the output");
 
   info("Close and re-open the browser console");
-  await HUDService.toggleBrowserConsole();
-  hud = await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
+  hud = await BrowserConsoleManager.toggleBrowserConsole();
 
   info("Log a smoke message in order to know that the console is ready");
   await logTextToConsole(hud, "Smoke message");
   is(
     findMessage(hud, CACHED_MESSAGE),
     null,
     "The cached message is not visible anymore"
   );
--- a/devtools/client/webconsole/test/mochitest/browser_console_clear_method.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_clear_method.js
@@ -9,17 +9,17 @@
 // Check that console.clear() does not clear the output of the browser console.
 
 "use strict";
 
 const TEST_URI = "data:text/html;charset=utf8,<p>Bug 1296870";
 
 add_task(async function() {
   await loadTab(TEST_URI);
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
 
   info("Log a new message from the content page");
   ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
     content.wrappedJSObject.console.log("msg");
   });
   await waitForMessage("msg", hud);
 
   info("Send a console.clear() from the content page");
--- a/devtools/client/webconsole/test/mochitest/browser_console_consolejsm_output.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_consolejsm_output.js
@@ -10,17 +10,17 @@
 add_task(async function testCategoryLogs() {
   const consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
   const storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
   storage.clearEvents();
 
   const { console } = ChromeUtils.import("resource://gre/modules/Console.jsm");
   console.log("bug861338-log-cached");
 
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
 
   await checkMessageExists(hud, "bug861338-log-cached");
 
   hud.ui.clearOutput(true);
 
   function testTrace() {
     console.trace();
   }
@@ -44,29 +44,29 @@ add_task(async function testCategoryLogs
   await checkMessageExists(hud, "bug851231-warn");
   await checkMessageExists(hud, "bug851231-error");
   await checkMessageExists(hud, "bug851231-debug");
   await checkMessageExists(hud, "bug851231-dir");
   await checkMessageExists(hud, "console.trace()");
   await checkMessageExists(hud, "foobarTimer");
 
   hud.ui.clearOutput(true);
-  await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
 });
 
 add_task(async function testFilter() {
   const consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
   const storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
   storage.clearEvents();
 
   const { ConsoleAPI } = ChromeUtils.import(
     "resource://gre/modules/Console.jsm"
   );
   const console2 = new ConsoleAPI();
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
 
   // Enable the error category and disable the log category.
   await setFilterState(hud, {
     error: true,
     log: false,
   });
 
   const shouldBeVisible = "Should be visible";
@@ -77,17 +77,17 @@ add_task(async function testFilter() {
 
   await checkMessageExists(hud, shouldBeVisible);
   // Here we can safely assert that the log message is not visible, since the
   // error message was logged after and is visible.
   await checkMessageHidden(hud, shouldBeHidden);
 
   await resetFilters(hud);
   hud.ui.clearOutput(true);
-  await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
 });
 
 // Test that console.profile / profileEnd trigger the right events
 add_task(async function testProfile() {
   const consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
   const storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
   const { console } = ChromeUtils.import("resource://gre/modules/Console.jsm");
 
--- a/devtools/client/webconsole/test/mochitest/browser_console_context_menu_entries.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_context_menu_entries.js
@@ -12,17 +12,17 @@ const TEST_URI =
 add_task(async function() {
   await pushPref("devtools.browserconsole.contentMessages", true);
   // Enable net messages in the console for this test.
   await pushPref("devtools.browserconsole.filter.net", true);
   // This is required for testing the text input in the browser console:
   await pushPref("devtools.chrome.enabled", true);
 
   await addTab(TEST_URI);
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
 
   info("Reload the content window to produce a network log");
   const onNetworkMessage = waitForMessage(hud, "test-console.html");
   ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
     content.wrappedJSObject.location.reload();
   });
   const networkMessage = await onNetworkMessage;
 
@@ -103,17 +103,17 @@ add_task(async function() {
   // Paste may or may not be enabled depending on what ran before this.
   // If emptyClipboard is fixed (666254) we could assert if it's enabled/disabled.
   ok(actualEntries[3].startsWith("#editmenu-paste (editmenu-paste)"));
   is(actualEntries[4], "#editmenu-delete (editmenu-delete) [disabled]");
   is(actualEntries[5], "#editmenu-selectAll (editmenu-select-all) [disabled]");
 
   await hideContextMenu(hud);
   // Close the browser console.
-  await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
 });
 
 function addPrefBasedEntries(expectedEntries) {
   if (Services.prefs.getBoolPref("devtools.webconsole.sidebarToggle", false)) {
     expectedEntries.push("#console-menu-open-sidebar (V) [disabled]");
   }
 
   return expectedEntries;
--- a/devtools/client/webconsole/test/mochitest/browser_console_cpow.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_cpow.js
@@ -11,17 +11,17 @@ const ObjectClient = require("devtools/s
 
 const {
   gDevToolsBrowser,
 } = require("devtools/client/framework/devtools-browser");
 
 add_task(async function() {
   await addTab("about:blank");
 
-  const hud = await HUDService.openBrowserConsoleOrFocus();
+  const hud = await BrowserConsoleManager.openBrowserConsoleOrFocus();
 
   const { message, actor } = await obtainObjectWithCPOW(hud);
   await testFrontEnd(hud, message);
   await testBackEnd(hud, actor);
 });
 
 async function obtainObjectWithCPOW(hud) {
   info("Add a message listener, it will receive an object with a CPOW");
--- a/devtools/client/webconsole/test/mochitest/browser_console_dead_objects.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_dead_objects.js
@@ -10,17 +10,17 @@
 // - Creates a sandbox.
 // - Stores a reference to the sandbox on the chrome window object.
 // - Nukes the sandbox
 // - Tries to use the sandbox. This is the dead object.
 
 "use strict";
 
 add_task(async function() {
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
   ok(hud, "browser console opened");
 
   // Add the reference to the nuked sandbox.
   execute(
     hud,
     "window.nukedSandbox = Cu.Sandbox(null); Cu.nukeSandbox(nukedSandbox);"
   );
 
--- a/devtools/client/webconsole/test/mochitest/browser_console_devtools_loader_exception.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_devtools_loader_exception.js
@@ -10,17 +10,17 @@
 
 const TEST_URI =
   "data:text/html;charset=utf8,<p>browser_console_devtools_loader_exception.js</p>";
 
 add_task(async function() {
   const wcHud = await openNewTabAndConsole(TEST_URI);
   ok(wcHud, "web console opened");
 
-  const bcHud = await HUDService.toggleBrowserConsole();
+  const bcHud = await BrowserConsoleManager.toggleBrowserConsole();
   ok(bcHud, "browser console opened");
 
   // Cause an exception in a script loaded with the DevTools loader.
   const toolbox = gDevTools.getToolbox(wcHud.target);
   const oldPanels = toolbox._toolPanels;
   // non-iterable
   toolbox._toolPanels = {};
 
--- a/devtools/client/webconsole/test/mochitest/browser_console_error_source_click.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_error_source_click.js
@@ -11,17 +11,17 @@
 const TEST_URI =
   "data:text/html;charset=utf8,<p>hello world" +
   "<button onclick='foobar.explode()'>click!</button>";
 
 add_task(async function() {
   await pushPref("devtools.browserconsole.contentMessages", true);
   await addTab(TEST_URI);
 
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
   ok(hud, "browser console opened");
 
   // On e10s, the exception is triggered in child process
   // and is ignored by test harness
   if (!Services.appinfo.browserTabsRemoteAutostart) {
     expectUncaughtException();
   }
 
--- a/devtools/client/webconsole/test/mochitest/browser_console_filters.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_filters.js
@@ -24,17 +24,17 @@ add_task(async function() {
 
   filterState = await getFilterState(hud);
   ok(!filterState.error, "The web console error filter is disabled");
 
   await resetFilters(hud);
   await closeConsole();
   info("web console closed");
 
-  hud = await HUDService.toggleBrowserConsole();
+  hud = await BrowserConsoleManager.toggleBrowserConsole();
   ok(hud, "browser console opened");
 
   filterState = await getFilterState(hud);
   ok(filterState.error, "The browser console error filter is enabled");
 
   info(`toggle "error" filter in browser console`);
   await setFilterState(hud, {
     error: false,
--- a/devtools/client/webconsole/test/mochitest/browser_console_jsterm_await.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_jsterm_await.js
@@ -9,17 +9,17 @@
 const TEST_URI =
   "data:text/html;charset=utf-8,Top-level await Browser Console test";
 
 add_task(async function() {
   // Enable await mapping.
   await pushPref("devtools.debugger.features.map-await-expression", true);
 
   await addTab(TEST_URI);
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
 
   const executeAndWaitForResultMessage = (input, expectedOutput) =>
     executeAndWaitForMessage(hud, input, expectedOutput, ".result");
 
   info("Evaluate a top-level await expression");
   const simpleAwait = `await new Promise(r => setTimeout(() => r(["await1"]), 500))`;
   await executeAndWaitForResultMessage(simpleAwait, `Array [ "await1" ]`);
 
@@ -35,10 +35,10 @@ add_task(async function() {
   );
   ok(
     messagesText.includes(simpleAwait) &&
       messagesText.includes(`Array [ "await1" ]`),
     "The output contains the the expected messages"
   );
 
   info("Close the Browser console");
-  await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
 });
--- a/devtools/client/webconsole/test/mochitest/browser_console_nsiconsolemessage.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_nsiconsolemessage.js
@@ -48,17 +48,17 @@ add_task(async function() {
   ok(
     !text.includes("liveBrowserConsoleMessage"),
     "nsIConsoleMessages are not displayed"
   );
 
   await closeConsole();
 
   info("web console closed");
-  hud = await HUDService.toggleBrowserConsole();
+  hud = await BrowserConsoleManager.toggleBrowserConsole();
   ok(hud, "browser console opened");
 
   await waitFor(() => findMessage(hud, "cachedBrowserConsoleMessage"));
   Services.console.logStringMessage("liveBrowserConsoleMessage2");
   await waitFor(() => findMessage(hud, "liveBrowserConsoleMessage2"));
 
   const msg = await waitFor(() =>
     findMessage(hud, "liveBrowserConsoleMessage")
--- a/devtools/client/webconsole/test/mochitest/browser_console_open_or_focus.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_open_or_focus.js
@@ -11,36 +11,36 @@
 const TEST_MESSAGE = "testmessage";
 const { Tools } = require("devtools/client/definitions");
 
 add_task(async function() {
   let currWindow, hud;
 
   const mainWindow = Services.wm.getMostRecentWindow(null);
 
-  await HUDService.openBrowserConsoleOrFocus();
+  await BrowserConsoleManager.openBrowserConsoleOrFocus();
 
-  hud = HUDService.getBrowserConsole();
+  hud = BrowserConsoleManager.getBrowserConsole();
 
   ok(hud.ui.document.hasFocus(), "Focus in the document");
 
   console.log(TEST_MESSAGE);
 
   await waitFor(() => findMessage(hud, TEST_MESSAGE));
 
   currWindow = Services.wm.getMostRecentWindow(null);
   is(
     currWindow.document.documentURI,
     Tools.webConsole.url,
     "The Browser Console is open and has focus"
   );
   mainWindow.focus();
-  await HUDService.openBrowserConsoleOrFocus();
+  await BrowserConsoleManager.openBrowserConsoleOrFocus();
   currWindow = Services.wm.getMostRecentWindow(null);
   is(
     currWindow.document.documentURI,
     Tools.webConsole.url,
     "The Browser Console is open and has focus"
   );
-  await HUDService.toggleBrowserConsole();
-  hud = HUDService.getBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
+  hud = BrowserConsoleManager.getBrowserConsole();
   ok(!hud, "Browser Console has been closed");
 });
--- a/devtools/client/webconsole/test/mochitest/browser_console_restore.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_restore.js
@@ -5,39 +5,39 @@
 
 // Check that the browser console gets session state is set correctly, and that
 // it re-opens when restore is requested.
 
 "use strict";
 
 add_task(async function() {
   is(
-    HUDService.getBrowserConsoleSessionState(),
+    BrowserConsoleManager.getBrowserConsoleSessionState(),
     false,
     "Session state false by default"
   );
-  HUDService.storeBrowserConsoleSessionState();
+  BrowserConsoleManager.storeBrowserConsoleSessionState();
   is(
-    HUDService.getBrowserConsoleSessionState(),
+    BrowserConsoleManager.getBrowserConsoleSessionState(),
     false,
     "Session state still not true even after setting (since Browser Console is closed)"
   );
 
-  await HUDService.toggleBrowserConsole();
-  HUDService.storeBrowserConsoleSessionState();
+  await BrowserConsoleManager.toggleBrowserConsole();
+  BrowserConsoleManager.storeBrowserConsoleSessionState();
   is(
-    HUDService.getBrowserConsoleSessionState(),
+    BrowserConsoleManager.getBrowserConsoleSessionState(),
     true,
     "Session state true (since Browser Console is opened)"
   );
 
   info(
     "Closing the browser console and waiting for the session restore to reopen it"
   );
-  await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
 
   const opened = waitForBrowserConsole();
   gDevTools.restoreDevToolsSession({
     browserConsole: true,
   });
 
   info("Waiting for the console to open after session restore");
   await opened;
--- a/devtools/client/webconsole/test/mochitest/browser_console_webconsole_console_api_calls.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_webconsole_console_api_calls.js
@@ -29,17 +29,17 @@ const TEST_URI = `data:text/html,<meta c
   console.trace();
   console.assert(false, "err");
 </script>`;
 
 add_task(async function() {
   // Show the content messages
   await pushPref("devtools.browserconsole.contentMessages", true);
 
-  const hud = await HUDService.toggleBrowserConsole();
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
   hud.ui.clearOutput();
 
   await addTab(TEST_URI);
 
   const expectedMessages = [
     contentArgs.log,
     contentArgs.warn,
     contentArgs.error,
--- a/devtools/client/webconsole/test/mochitest/browser_console_webconsole_ctrlw_close_tab.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_webconsole_ctrlw_close_tab.js
@@ -56,17 +56,17 @@ add_task(async function() {
 
   await promise.all([
     tabClosed.promise,
     toolboxDestroyed.promise,
     tabSelected.promise,
   ]);
   info("promise.all resolved. start testing the Browser Console");
 
-  hud = await HUDService.toggleBrowserConsole();
+  hud = await BrowserConsoleManager.toggleBrowserConsole();
   ok(hud, "Browser Console opened");
 
   const deferred = defer();
 
   Services.obs.addObserver(function onDestroy() {
     Services.obs.removeObserver(onDestroy, "web-console-destroyed");
     ok(true, "the Browser Console closed");
 
--- a/devtools/client/webconsole/test/mochitest/browser_console_webconsole_iframe_messages.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_webconsole_iframe_messages.js
@@ -24,17 +24,17 @@ add_task(async function() {
   }
 
   let hud = await openNewTabAndConsole(TEST_URI);
 
   await testMessages(hud);
   await closeConsole();
   info("web console closed");
 
-  hud = await HUDService.toggleBrowserConsole();
+  hud = await BrowserConsoleManager.toggleBrowserConsole();
   await testBrowserConsole(hud);
   await closeConsole();
 });
 
 async function testMessages(hud) {
   for (const message of expectedMessages) {
     info(`checking that the message "${message}" exists`);
     await waitFor(() => findMessage(hud, message));
--- a/devtools/client/webconsole/test/mochitest/browser_console_webconsole_private_browsing.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_webconsole_private_browsing.js
@@ -66,17 +66,17 @@ add_task(async function() {
   ok(
     true,
     "Messages are still displayed after closing and reopening the console"
   );
 
   info("Test browser console");
   await closeConsole(privateTab);
   info("web console closed");
-  hud = await HUDService.toggleBrowserConsole();
+  hud = await BrowserConsoleManager.toggleBrowserConsole();
 
   // Make sure that the cached messages from private tabs are not displayed in the
   // browser console.
   assertNoPrivateMessages(hud);
 
   // Add a non-private message to the console.
   const onBrowserConsoleNonPrivateMessage = waitForMessage(
     hud,
@@ -111,20 +111,20 @@ add_task(async function() {
 
   ok(
     findMessage(hud, NON_PRIVATE_MESSAGE),
     "non-private messages are still shown after private window closed"
   );
   assertNoPrivateMessages(hud);
 
   info("close the browser console");
-  await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
 
   info("reopen the browser console");
-  hud = await HUDService.toggleBrowserConsole();
+  hud = await BrowserConsoleManager.toggleBrowserConsole();
   ok(hud, "browser console reopened");
 
   assertNoPrivateMessages(hud);
 });
 
 function logPrivateMessages(browser) {
   ContentTask.spawn(browser, null, () => content.wrappedJSObject.logMessages());
 }
--- a/devtools/client/webconsole/test/mochitest/browser_jsterm_hide_when_devtools_chrome_enabled_false.js
+++ b/devtools/client/webconsole/test/mochitest/browser_jsterm_hide_when_devtools_chrome_enabled_false.js
@@ -27,43 +27,43 @@ requestLongerTimeout(2);
 
 add_task(async function() {
   let browserConsole, webConsole, objInspector;
 
   // We don't use `pushPref()` because we need to revert the same pref later
   // in the test.
   Services.prefs.setBoolPref("devtools.chrome.enabled", true);
 
-  browserConsole = await HUDService.toggleBrowserConsole();
+  browserConsole = await BrowserConsoleManager.toggleBrowserConsole();
   objInspector = await logObject(browserConsole);
   testJSTermIsVisible(browserConsole);
   await testObjectInspectorPropertiesAreSet(objInspector);
 
   const browserTab = await addTab("data:text/html;charset=utf8,hello world");
   webConsole = await openConsole(browserTab);
   objInspector = await logObject(webConsole);
   testJSTermIsVisible(webConsole);
   await testObjectInspectorPropertiesAreSet(objInspector);
   await closeConsole(browserTab);
 
-  await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
   Services.prefs.setBoolPref("devtools.chrome.enabled", false);
 
-  browserConsole = await HUDService.toggleBrowserConsole();
+  browserConsole = await BrowserConsoleManager.toggleBrowserConsole();
   objInspector = await logObject(browserConsole);
   testJSTermIsNotVisible(browserConsole);
 
   webConsole = await openConsole(browserTab);
   objInspector = await logObject(webConsole);
   testJSTermIsVisible(webConsole);
   await testObjectInspectorPropertiesAreSet(objInspector);
 
   info("Close webconsole and browser console");
   await closeConsole(browserTab);
-  await HUDService.toggleBrowserConsole();
+  await BrowserConsoleManager.toggleBrowserConsole();
 });
 
 async function logObject(hud) {
   const prop = "browser_console_hide_jsterm_test";
   const { node } = await executeAndWaitForMessage(
     hud,
     `new Object({ ${prop}: true })`,
     prop,
--- a/devtools/client/webconsole/test/mochitest/browser_webconsole_network_requests_from_chrome.js
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_network_requests_from_chrome.js
@@ -23,17 +23,17 @@ add_task(async function() {
       ) {
         good = false;
       }
     },
   };
   Services.console.registerListener(listener);
 
   // trigger a lazy-load of the HUD Service
-  HUDService;
+  BrowserConsoleManager;
 
   await sendRequestFromChrome();
 
   ok(
     good,
     "No exception was thrown when sending a network request from a chrome window"
   );
 
--- a/devtools/client/webconsole/test/mochitest/head.js
+++ b/devtools/client/webconsole/test/mochitest/head.js
@@ -31,17 +31,19 @@ Services.scriptloader.loadSubScript(
 
 // Import helpers for the new debugger
 /* import-globals-from ../../../debugger/test/mochitest/helpers.js*/
 Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/helpers.js",
   this
 );
 
-var { HUDService } = require("devtools/client/webconsole/hudservice");
+var {
+  BrowserConsoleManager,
+} = require("devtools/client/webconsole/browser-console-manager");
 var WCUL10n = require("devtools/client/webconsole/utils/l10n");
 const DOCS_GA_PARAMS = `?${new URLSearchParams({
   utm_source: "mozilla",
   utm_medium: "firefox-console-errors",
   utm_campaign: "default",
 })}`;
 const GA_PARAMS = `?${new URLSearchParams({
   utm_source: "mozilla",
@@ -55,20 +57,20 @@ registerCleanupFunction(async function()
   Services.prefs.clearUserPref("devtools.webconsole.ui.filterbar");
 
   // Reset all filter prefs between tests. First flushPrefEnv in case one of the
   // filter prefs has been pushed for the test
   await SpecialPowers.flushPrefEnv();
   Services.prefs.getChildList("devtools.webconsole.filter").forEach(pref => {
     Services.prefs.clearUserPref(pref);
   });
-  const browserConsole = HUDService.getBrowserConsole();
+  const browserConsole = BrowserConsoleManager.getBrowserConsole();
   if (browserConsole) {
     browserConsole.ui.clearOutput(true);
-    await HUDService.toggleBrowserConsole();
+    await BrowserConsoleManager.toggleBrowserConsole();
   }
 });
 
 /**
  * Add a new tab and open the toolbox in it, and select the webconsole.
  *
  * @param string url
  *        The URL for the tab to be opened.
@@ -924,17 +926,17 @@ function selectNode(hud, node) {
 }
 
 async function waitForBrowserConsole() {
   return new Promise(resolve => {
     Services.obs.addObserver(function observer(subject) {
       Services.obs.removeObserver(observer, "web-console-created");
       subject.QueryInterface(Ci.nsISupportsString);
 
-      const hud = HUDService.getBrowserConsole();
+      const hud = BrowserConsoleManager.getBrowserConsole();
       ok(hud, "browser console is open");
       is(subject.data, hud.hudId, "notification hudId is correct");
 
       executeSoon(() => resolve(hud));
     }, "web-console-created");
   });
 }
 
--- a/devtools/docs/tools/console-panel.md
+++ b/devtools/docs/tools/console-panel.md
@@ -4,68 +4,64 @@ The Console panel is responsible for ren
 
 ## Architecture
 
 Internal architecture of the Console panel (the client side) is described
 on the following diagram.
 
 <figure class="hero">
   <pre class="diagram">
-┌───────────────────────────────────┐          ┌───────────────────────────────────┐
-│             DevTools              │          │          WebConsolePanel          │
-│  [client/framework/devtools.js]   │          │            [panel.js]             │
-└───────────────────────────────────┘          └───────────────────────────────────┘
-                  │                                               │
-                                                                  │
-        openBrowserConsole() or                                   │
-        toggleBrowserConsole()                                    │
-                  │                                               │
-                  ▼                                               │
-┌───────────────────────────────────┐                             │
-│            HUDService             │                             │
-│          [hudservice.js]          │                           {hud}
-└───────────────────────────────────┘                             │
-                  │                                               │
-                  │                                               │
-                  │                                               │
-          {_browserConsole}                                       │
-                  │                                               │
-                  │                                               │
-                  │                                               │
-                  │                                               │
-                  ▼ 0..1                                          ▼ 1
-      ┌────────────────────────┐                       ┌────────────────────────┐
-      │     BrowserConsole     │                       │       WebConsole       │
-      │  [browser-console.js]  │─ ─ ─ ─ ─extends─ ─ ─ ▶│    [webconsole.js]     │
-      └────────────────────────┘                       └────────────────────────┘
-                                                                  │
-                                                                {ui}
-                                                                  │
-                                                                  ▼ 1
-                                                     ┌────────────────────────┐                     ┌─────────────────────────────────┐
-                                                     │      WebConsoleUI      │                    1│    WebConsoleConnectionProxy    │
-                                                     │   [webconsole-ui.js]   │─────{proxy}────────▶│[webconsole-connection-proxy.js] │
-                                                     └────────────────────────┘                     └─────────────────────────────────┘
-                                                                  │                                                  │
-                                                                  │
-                                                             {wrapper}                                               │
-                                                                  │
-                                                                  │                                                  │
-                                                                  ▼ 1
-                                                     ┌────────────────────────┐                                      │
-                                                     │   WebConsoleWrapper    │
-                                                     │[webconsole-wrapper.js] │◀ ─ ─ ─ ─ ─ ─ calls methods from─ ─ ─ ┘
-                                                     └────────────────────────┘
-                                                                  │
-                                                              <renders>
-                                                                  │
-                                                                  ▼
-                                                     ┌────────────────────────┐
-                                                     │          App           │
-                                                     └────────────────────────┘
+┌──────────────────────────────┐               ┌────────────────────────┐
+│           DevTools           │               │    WebConsolePanel     │
+│[client/framework/devtools.js]│               │       [panel.js]       │
+└──────────────────────────────┘               └────────────────────────┘
+                │                                           │
+                                                            │
+     openBrowserConsole() or                                │
+     toggleBrowserConsole()                                 │
+                │                                           │
+                ▼                                           │
+┌──────────────────────────────┐                          {hud}
+│    BrowserConsoleManager     │                            │
+│ [browser-console-manager.js] │                            │
+└──────────────────────────────┘                            │
+                │                                           │
+                │                                           │
+      {_browserConsole}                                     │
+                │                                           │
+                ▼ 0..1                                      ▼ 1
+┌──────────────────────────────┐               ┌────────────────────────┐
+│        BrowserConsole        │               │       WebConsole       │
+│     [browser-console.js]     │─ ─ extends ─ ▶│    [webconsole.js]     │
+└──────────────────────────────┘               └──────────────1─────────┘
+                                                            │
+                                                          {ui}
+                                                            │
+                                                            ▼ 1
+                                               ┌────────────────────────┐             ┌─────────────────────────────────┐
+                                               │      WebConsoleUI      │            1│    WebConsoleConnectionProxy    │
+                                               │   [webconsole-ui.js]   │───{proxy}──▶│[webconsole-connection-proxy.js] │
+                                               └────────────────────────┘             └─────────────────────────────────┘
+                                                            │                                          │
+                                                       {wrapper}
+                                                            │                                          │
+                                                            │
+                                                            │                                          │
+                                                            ▼ 1
+                                               ┌────────────────────────┐                              │
+                                               │   WebConsoleWrapper    │
+                                               │[webconsole-wrapper.js] │◀ ─ ─ ─calls methods from ─ ─ ┘
+                                               └────────────────────────┘
+                                                            │
+                                                        <renders>
+                                                            │
+                                                            ▼
+                                               ┌────────────────────────┐
+                                               │          App           │
+                                               └────────────────────────┘
     </pre>
   <figcaption>Elements between curly bracket on arrows represent the property name of the reference (for example, the WebConsolePanel as a `hud` property that is a reference to the WebConsole instance)</figcaption>
 </figure>
 
 ## Components
 
 The Console panel UI is built on top of [React](../frontend/react.md). It defines set of React components in `components` directory
 The React architecture is described on the following diagram.
--- a/devtools/startup/DevToolsStartup.jsm
+++ b/devtools/startup/DevToolsStartup.jsm
@@ -877,18 +877,20 @@ DevToolsStartup.prototype = {
       relatedToCurrent: true,
     });
   },
 
   handleConsoleFlag: function(cmdLine) {
     const window = Services.wm.getMostRecentWindow("devtools:webconsole");
     if (!window) {
       const require = this.initDevTools("CommandLine");
-      const { HUDService } = require("devtools/client/webconsole/hudservice");
-      HUDService.toggleBrowserConsole().catch(console.error);
+      const {
+        BrowserConsoleManager,
+      } = require("devtools/client/webconsole/browser-console-manager");
+      BrowserConsoleManager.toggleBrowserConsole().catch(console.error);
     } else {
       // the Browser Console was already open
       window.focus();
     }
 
     if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) {
       cmdLine.preventDefault = true;
     }
--- a/toolkit/components/extensions/test/mochitest/test_ext_background_page.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_background_page.html
@@ -1,81 +1,84 @@
 <!DOCTYPE HTML>
 <html>
-<head>
-  <title>WebExtension test</title>
-  <meta charset="utf-8">
-  <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
-  <script type="text/javascript" src="head.js"></script>
-  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
+  <head>
+    <title>WebExtension test</title>
+    <meta charset="utf-8">
+    <script src="/tests/SimpleTest/SimpleTest.js"></script>
+    <script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+    <script src="head.js" type="text/javascript"></script>
+    <link href="/tests/SimpleTest/test.css" rel="stylesheet"/>
+  </head>
+  <body>
 
-<script type="text/javascript">
-"use strict";
+    <script type="text/javascript">
+      "use strict";
 
-/* eslint-disable mozilla/balanced-listeners */
+      /* eslint-disable mozilla/balanced-listeners */
 
-add_task(async function testAlertNotShownInBackgroundWindow() {
-  let extension = ExtensionTestUtils.loadExtension({
-    background: function() {
-      alert("I am an alert in the background.");
+      add_task(async function testAlertNotShownInBackgroundWindow() {
+        let extension = ExtensionTestUtils.loadExtension({
+          background: function () {
+            alert("I am an alert in the background.");
 
-      browser.test.notifyPass("alertCalled");
-    },
-  });
+            browser.test.notifyPass("alertCalled");
+          }
+        });
 
-  let consoleOpened = loadChromeScript(() => {
-    const {sendAsyncMessage, assert} = this;
-    assert.ok(!Services.wm.getEnumerator("alert:alert").hasMoreElements(),
-              "Alerts should not be present at the start of the test.");
+        let consoleOpened = loadChromeScript(() => {
+          const {sendAsyncMessage, assert} = this;
+          assert.ok(!Services.wm.getEnumerator("alert:alert").hasMoreElements(), "Alerts should not be present at the start of the test.");
 
-    Services.obs.addObserver(function observer() {
-      sendAsyncMessage("web-console-created");
-      Services.obs.removeObserver(observer, "web-console-created");
-    }, "web-console-created");
-  });
-  let opened = consoleOpened.promiseOneMessage("web-console-created");
-
-  consoleMonitor.start([{message: /alert\(\) is not supported in background windows/},
-                        {message: /I am an alert in the background/}]);
+          Services.obs.addObserver(function observer() {
+            sendAsyncMessage("web-console-created");
+            Services.obs.removeObserver(observer, "web-console-created");
+          }, "web-console-created");
+        });
+        let opened = consoleOpened.promiseOneMessage("web-console-created");
 
-  await extension.startup();
-  await extension.awaitFinish("alertCalled");
+        consoleMonitor.start([
+          {
+            message: /alert\(\) is not supported in background windows/
+          }, {
+            message: /I am an alert in the background/
+          }
+        ]);
+
+        await extension.startup();
+        await extension.awaitFinish("alertCalled");
 
-  let chromeScript = loadChromeScript(async () => {
-    const {assert} = this;
-    assert.ok(!Services.wm.getEnumerator("alert:alert").hasMoreElements(),
-              "Alerts should not be present after calling alert().");
-  });
-  chromeScript.destroy();
+        let chromeScript = loadChromeScript(async () => {
+          const {assert} = this;
+          assert.ok(!Services.wm.getEnumerator("alert:alert").hasMoreElements(), "Alerts should not be present after calling alert().");
+        });
+        chromeScript.destroy();
 
-  await consoleMonitor.finished();
+        await consoleMonitor.finished();
 
-  await opened;
-  consoleOpened.destroy();
+        await opened;
+        consoleOpened.destroy();
 
-  chromeScript = loadChromeScript(async () => {
-    const {sendAsyncMessage} = this;
-    let {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
-    require("devtools/client/framework/devtools-browser");
-    let {HUDService} = require("devtools/client/webconsole/hudservice");
+        chromeScript = loadChromeScript(async () => {
+          const {sendAsyncMessage} = this;
+          let {require} = ChromeUtils.import ("resource://devtools/shared/Loader.jsm");
+          require("devtools/client/framework/devtools-browser");
+          let {BrowserConsoleManager} = require("devtools/client/webconsole/browser-console-manager");
 
-    // And then double check that we have an actual browser console.
-    let haveConsole = !!HUDService.getBrowserConsole();
+          // And then double check that we have an actual browser console.
+          let haveConsole = !!BrowserConsoleManager.getBrowserConsole();
 
-    if (haveConsole) {
-      await HUDService.toggleBrowserConsole();
-    }
-    sendAsyncMessage("done", haveConsole);
-  });
+          if (haveConsole) {
+            await BrowserConsoleManager.toggleBrowserConsole();
+          }
+          sendAsyncMessage("done", haveConsole);
+        });
 
-  let consoleShown = await chromeScript.promiseOneMessage("done");
-  ok(consoleShown, "console was shown");
-  chromeScript.destroy();
+        let consoleShown = await chromeScript.promiseOneMessage("done");
+        ok(consoleShown, "console was shown");
+        chromeScript.destroy();
 
-  await extension.unload();
-});
-</script>
+        await extension.unload();
+      });
+    </script>
 
-</body>
+  </body>
 </html>