Bug 1505791 - Separate the browser panel from the notification box. r=dao,bgrins
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Thu, 08 Nov 2018 15:31:37 +0000
changeset 445262 d19c246b34889f3795bf5075d498fd2f2367d930
parent 445261 600944fac4ead2f3f9284a16f1eef3e5f2ff3f05
child 445263 e58d4f72e162f2025121904315191d253e1df817
push id35014
push userdvarga@mozilla.com
push dateFri, 09 Nov 2018 10:01:40 +0000
treeherdermozilla-central@5e7636ec12c5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, bgrins
bugs1505791
milestone65.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 1505791 - Separate the browser panel from the notification box. r=dao,bgrins This clarifies the intention of each caller, and opens up the possibility of converting the notificationbox element to a class that creates the DOM nodes on demand. Differential Revision: https://phabricator.services.mozilla.com/D10577
browser/base/content/browser-gestureSupport.js
browser/base/content/tabbrowser.js
browser/base/content/test/general/browser_bug462673.js
devtools/client/framework/test/browser_toolbox_hosts.js
devtools/client/framework/test/browser_toolbox_hosts_size.js
devtools/client/framework/toolbox-hosts.js
testing/mochitest/browser-test.js
--- a/browser/base/content/browser-gestureSupport.js
+++ b/browser/base/content/browser-gestureSupport.js
@@ -722,17 +722,17 @@ var gHistorySwipeAnimation = {
     gHistorySwipeAnimation._removeBoxes();
   },
 
   /**
    * Adds the boxes that contain the arrows used during the swipe animation.
    */
   _addBoxes: function HSA__addBoxes() {
     let browserStack =
-      document.getAnonymousElementByAttribute(gBrowser.getNotificationBox(),
+      document.getAnonymousElementByAttribute(gBrowser.getPanel(),
                                               "class", "browserStack");
     this._container = this._createElement("historySwipeAnimationContainer",
                                           "stack");
     browserStack.appendChild(this._container);
 
     this._prevBox = this._createElement("historySwipeAnimationPreviousArrow",
                                         "box");
     this._prevBox.collapsed = true;
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -290,19 +290,19 @@ window._gBrowser = {
     browser.setAttribute("blank", "true");
     if (gBrowserAllowScriptsToCloseInitialTabs) {
       browser.setAttribute("allowscriptstoclose", "true");
     }
     browser.droppedLinkHandler = handleDroppedLink;
     browser.loadURI = _loadURI.bind(null, browser);
 
     let uniqueId = this._generateUniquePanelID();
-    let notificationbox = this.getNotificationBox(browser);
-    notificationbox.id = uniqueId;
-    this.tabpanels.appendChild(notificationbox);
+    let panel = this.getPanel(browser);
+    panel.id = uniqueId;
+    this.tabpanels.appendChild(panel);
 
     let tab = this.tabs[0];
     tab.linkedPanel = uniqueId;
     this._selectedTab = tab;
     this._selectedBrowser = browser;
     tab.permanentKey = browser.permanentKey;
     tab._tPos = 0;
     tab._fullyOpen = true;
@@ -502,18 +502,24 @@ window._gBrowser = {
   /**
    * Create a findbar instance.
    * @param aTab the tab to create the find bar for.
    * @return the created findbar, or null if the window or tab is closed/closing.
    */
   async _createFindBar(aTab) {
     let findBar = document.createXULElement("findbar");
     let browser = this.getBrowserForTab(aTab);
-    let browserContainer = this.getBrowserContainer(browser);
-    browserContainer.appendChild(findBar);
+
+    // The findbar should be inserted after the browserStack and, if present for
+    // this tab, after the StatusPanel as well.
+    let insertAfterElement = browser.parentNode;
+    if (insertAfterElement.nextElementSibling == StatusPanel.panel) {
+      insertAfterElement = StatusPanel.panel;
+    }
+    insertAfterElement.insertAdjacentElement("afterend", findBar);
 
     await new Promise(r => requestAnimationFrame(r));
     delete aTab._pendingFindBar;
     if (window.closed || aTab.closing) {
       return null;
     }
 
     findBar.browser = browser;
@@ -524,19 +530,18 @@ window._gBrowser = {
     let event = document.createEvent("Events");
     event.initEvent("TabFindInitialized", true, false);
     aTab.dispatchEvent(event);
 
     return findBar;
   },
 
   _appendStatusPanel() {
-    let browser = this.selectedBrowser;
-    let browserContainer = this.getBrowserContainer(browser);
-    browserContainer.insertBefore(StatusPanel.panel, browser.parentNode.nextElementSibling);
+    this.selectedBrowser.parentNode.insertAdjacentElement("afterend",
+                                                          StatusPanel.panel);
   },
 
   _updateTabBarForPinnedTabs() {
     this.tabContainer._unlockTabSizing();
     this.tabContainer._positionPinnedTabs();
     this.tabContainer._updateCloseButtons();
   },
 
@@ -635,28 +640,28 @@ window._gBrowser = {
   getBrowserForOuterWindowID(aID) {
     return this._outerWindowIDBrowserMap.get(aID);
   },
 
   getTabForBrowser(aBrowser) {
     return this._tabForBrowser.get(aBrowser);
   },
 
-  getNotificationBox(aBrowser) {
-    return this.getSidebarContainer(aBrowser).parentNode;
-  },
-
-  getSidebarContainer(aBrowser) {
+  getPanel(aBrowser) {
     return this.getBrowserContainer(aBrowser).parentNode;
   },
 
   getBrowserContainer(aBrowser) {
     return (aBrowser || this.selectedBrowser).parentNode.parentNode;
   },
 
+  getNotificationBox(aBrowser) {
+    return this.getBrowserContainer(aBrowser).firstElementChild;
+  },
+
   getTabModalPromptBox(aBrowser) {
     let browser = (aBrowser || this.selectedBrowser);
     if (!browser.tabModalPromptBox) {
       browser.tabModalPromptBox = new TabModalPromptBox(browser);
     }
     return browser.tabModalPromptBox;
   },
 
@@ -1730,17 +1735,17 @@ window._gBrowser = {
   removePreloadedBrowser() {
     if (!this._isPreloadingEnabled()) {
       return;
     }
 
     let browser = this._getPreloadedBrowser();
 
     if (browser) {
-      browser.remove();
+      this.getPanel(browser).remove();
     }
   },
 
   _getPreloadedBrowser() {
     if (!this._isPreloadingEnabled()) {
       return null;
     }
 
@@ -1781,18 +1786,18 @@ window._gBrowser = {
     }
 
     let remoteType =
       E10SUtils.getRemoteTypeForURI(BROWSER_NEW_TAB_URL,
         gMultiProcessBrowser);
     let browser = this._createBrowser({ isPreloadBrowser: true, remoteType });
     this._preloadedBrowser = browser;
 
-    let notificationbox = this.getNotificationBox(browser);
-    this.tabpanels.appendChild(notificationbox);
+    let panel = this.getPanel(browser);
+    this.tabpanels.appendChild(panel);
 
     if (remoteType != E10SUtils.NOT_REMOTE) {
       // For remote browsers, we need to make sure that the webProgress is
       // instantiated, otherwise the parent won't get informed about the state
       // of the preloaded browser until it gets attached to a tab.
       browser.webProgress;
     }
 
@@ -1904,43 +1909,39 @@ window._gBrowser = {
     // This will be used by gecko to control the name of the opened
     // window.
     if (name) {
       // XXX: The `name` property is special in HTML and XUL. Should
       // we use a different attribute name for this?
       b.setAttribute("name", name);
     }
 
-    // Create the browserStack container
-    let stack = document.createXULElement("stack");
-    stack.className = "browserStack";
-    stack.appendChild(b);
-    stack.setAttribute("flex", "1");
+    let notificationbox = document.createXULElement("notificationbox");
+    notificationbox.setAttribute("notificationside", "top");
 
     // We set large flex on both containers to allow the devtools toolbox to
     // set a flex attribute. We don't want the toolbox to actually take up free
     // space, but we do want it to collapse when the window shrinks, and with
     // flex=0 it can't. When the toolbox is on the bottom it's a sibling of
-    // browserSidebarContainer, and when it's on the side it's a sibling of
+    // browserStack, and when it's on the side it's a sibling of
     // browserContainer.
+    let stack = document.createXULElement("stack");
+    stack.className = "browserStack";
+    stack.appendChild(b);
+    stack.setAttribute("flex", "10000");
+
     let browserContainer = document.createXULElement("vbox");
     browserContainer.className = "browserContainer";
+    browserContainer.appendChild(notificationbox);
     browserContainer.appendChild(stack);
     browserContainer.setAttribute("flex", "10000");
 
     let browserSidebarContainer = document.createXULElement("hbox");
     browserSidebarContainer.className = "browserSidebarContainer";
     browserSidebarContainer.appendChild(browserContainer);
-    browserSidebarContainer.setAttribute("flex", "10000");
-
-    // Add the Message and the Browser to the box
-    let notificationbox = document.createXULElement("notificationbox");
-    notificationbox.setAttribute("flex", "1");
-    notificationbox.setAttribute("notificationside", "top");
-    notificationbox.appendChild(browserSidebarContainer);
 
     // Prevent the superfluous initial load of a blank document
     // if we're going to load something other than about:blank.
     if (!uriIsAboutBlank) {
       b.setAttribute("nodefaultsrc", "true");
     }
 
     return b;
@@ -2066,29 +2067,29 @@ window._gBrowser = {
       }
     }
 
     let { uriIsAboutBlank, remoteType, usingPreloadedContent } =
     aTab._browserParams;
     delete aTab._browserParams;
     delete aTab._cachedCurrentURI;
 
-    let notificationbox = this.getNotificationBox(browser);
+    let panel = this.getPanel(browser);
     let uniqueId = this._generateUniquePanelID();
-    notificationbox.id = uniqueId;
+    panel.id = uniqueId;
     aTab.linkedPanel = uniqueId;
 
     // Inject the <browser> into the DOM if necessary.
-    if (!notificationbox.parentNode) {
+    if (!panel.parentNode) {
       // NB: this appendChild call causes us to run constructors for the
       // browser element, which fires off a bunch of notifications. Some
       // of those notifications can cause code to run that inspects our
       // state, so it is important that the tab element is fully
       // initialized by this point.
-      this.tabpanels.appendChild(notificationbox);
+      this.tabpanels.appendChild(panel);
     }
 
     // wire up a progress listener for the new browser object.
     let tabListener = new TabProgressListener(aTab, browser, uriIsAboutBlank, usingPreloadedContent);
     const filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
       .createInstance(Ci.nsIWebProgress);
     filter.addProgressListener(tabListener, Ci.nsIWebProgress.NOTIFY_ALL);
     browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
@@ -2185,17 +2186,17 @@ window._gBrowser = {
     // Reset the findbar and remove it if it is attached to the tab.
     if (tab._findBar) {
       tab._findBar.close(true);
       tab._findBar.remove();
       delete tab._findBar;
     }
 
     aBrowser.destroy();
-    this.getNotificationBox(aBrowser).remove();
+    this.getPanel(aBrowser).remove();
     tab.removeAttribute("linkedpanel");
 
     this._createLazyBrowser(tab);
 
     let evt = new CustomEvent("TabBrowserDiscarded", { bubbles: true });
     tab.dispatchEvent(evt);
   },
 
@@ -2497,18 +2498,17 @@ window._gBrowser = {
       }
     } catch (e) {
       Cu.reportError("Failed to create tab");
       Cu.reportError(e);
       t.remove();
       if (t.linkedBrowser) {
         this._tabFilters.delete(t);
         this._tabListeners.delete(t);
-        let notificationbox = this.getNotificationBox(t.linkedBrowser);
-        notificationbox.remove();
+        this.getPanel(t.linkedBrowser).remove();
       }
       throw e;
     }
 
     // Hack to ensure that the about:newtab, and about:welcome favicon is loaded
     // instantaneously, to avoid flickering and improve perceived performance.
     this.setDefaultIcon(t, aURIObject);
 
@@ -3095,17 +3095,17 @@ window._gBrowser = {
     this.selectedTab._selected = true;
     this.tabContainer._setPositionalAttributes();
 
     // Removing the panel requires fixing up selectedPanel immediately
     // (see below), which would be hindered by the potentially expensive
     // browser removal. So we remove the browser and the panel in two
     // steps.
 
-    var panel = this.getNotificationBox(browser);
+    var panel = this.getPanel(browser);
 
     // In the multi-process case, it's possible an asynchronous tab switch
     // is still underway. If so, then it's possible that the last visible
     // browser is the one we're in the process of removing. There's the
     // risk of displaying preloaded browsers that are at the end of the
     // deck if we remove the browser before the switch is complete, so
     // we alert the switcher in order to show a spinner instead.
     if (this._switcher) {
--- a/browser/base/content/test/general/browser_bug462673.js
+++ b/browser/base/content/test/general/browser_bug462673.js
@@ -24,13 +24,13 @@ add_task(async function() {
   var newBrowser = newTab.linkedBrowser;
   win.gBrowser.removeTab(tab);
   ok(!win.closed, "Window stays open");
   if (!win.closed) {
     is(win.gBrowser.tabContainer.childElementCount, 1, "Window has one tab");
     is(win.gBrowser.browsers.length, 1, "Window has one browser");
     is(win.gBrowser.selectedTab, newTab, "Remaining tab is selected");
     is(win.gBrowser.selectedBrowser, newBrowser, "Browser for remaining tab is selected");
-    is(win.gBrowser.tabbox.selectedPanel, newBrowser.parentNode.parentNode.parentNode.parentNode, "Panel for remaining tab is selected");
+    is(win.gBrowser.tabbox.selectedPanel, newBrowser.parentNode.parentNode.parentNode, "Panel for remaining tab is selected");
   }
 
   await promiseWindowClosed(win);
 });
--- a/devtools/client/framework/test/browser_toolbox_hosts.js
+++ b/devtools/client/framework/test/browser_toolbox_hosts.js
@@ -31,59 +31,59 @@ add_task(async function runTest() {
   toolbox = target = null;
   gBrowser.removeCurrentTab();
 });
 
 function testBottomHost() {
   checkHostType(toolbox, BOTTOM);
 
   // test UI presence
-  const nbox = gBrowser.getNotificationBox();
-  const iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-bottom-iframe");
+  const panel = gBrowser.getPanel();
+  const iframe = panel.querySelector(".devtools-toolbox-bottom-iframe");
   ok(iframe, "toolbox bottom iframe exists");
 
   checkToolboxLoaded(iframe);
 }
 
 async function testLeftHost() {
   await toolbox.switchHost(LEFT);
   checkHostType(toolbox, LEFT);
 
   // test UI presence
-  const nbox = gBrowser.getNotificationBox();
-  const bottom = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-bottom-iframe");
+  const panel = gBrowser.getPanel();
+  const bottom = panel.querySelector(".devtools-toolbox-bottom-iframe");
   ok(!bottom, "toolbox bottom iframe doesn't exist");
 
-  const iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-side-iframe");
+  const iframe = panel.querySelector(".devtools-toolbox-side-iframe");
   ok(iframe, "toolbox side iframe exists");
 
   checkToolboxLoaded(iframe);
 }
 
 async function testRightHost() {
   await toolbox.switchHost(RIGHT);
   checkHostType(toolbox, RIGHT);
 
   // test UI presence
-  const nbox = gBrowser.getNotificationBox();
-  const bottom = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-bottom-iframe");
+  const panel = gBrowser.getPanel();
+  const bottom = panel.querySelector(".devtools-toolbox-bottom-iframe");
   ok(!bottom, "toolbox bottom iframe doesn't exist");
 
-  const iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-side-iframe");
+  const iframe = panel.querySelector(".devtools-toolbox-side-iframe");
   ok(iframe, "toolbox side iframe exists");
 
   checkToolboxLoaded(iframe);
 }
 
 async function testWindowHost() {
   await toolbox.switchHost(WINDOW);
   checkHostType(toolbox, WINDOW);
 
-  const nbox = gBrowser.getNotificationBox();
-  const sidebar = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-side-iframe");
+  const panel = gBrowser.getPanel();
+  const sidebar = panel.querySelector(".devtools-toolbox-side-iframe");
   ok(!sidebar, "toolbox sidebar iframe doesn't exist");
 
   const win = Services.wm.getMostRecentWindow("devtools:toolbox");
   ok(win, "toolbox separate window exists");
 
   const iframe = win.document.getElementById("toolbox-iframe");
   checkToolboxLoaded(iframe);
 }
--- a/devtools/client/framework/test/browser_toolbox_hosts_size.js
+++ b/devtools/client/framework/test/browser_toolbox_hosts_size.js
@@ -12,55 +12,55 @@ var {Toolbox} = require("devtools/client
 
 add_task(async function() {
   // Set size prefs to make the hosts way too big, so that the size has
   // to be clamped to fit into the browser window.
   Services.prefs.setIntPref("devtools.toolbox.footer.height", 10000);
   Services.prefs.setIntPref("devtools.toolbox.sidebar.width", 10000);
 
   const tab = await addTab(URL);
-  const nbox = gBrowser.getNotificationBox();
-  const {clientHeight: nboxHeight, clientWidth: nboxWidth} = nbox;
+  const panel = gBrowser.getPanel();
+  const {clientHeight: panelHeight, clientWidth: panelWidth} = panel;
   const target = await TargetFactory.forTab(tab);
   const toolbox = await gDevTools.showToolbox(target);
 
-  is(nbox.clientHeight, nboxHeight, "Opening the toolbox hasn't changed the height of the nbox");
-  is(nbox.clientWidth, nboxWidth, "Opening the toolbox hasn't changed the width of the nbox");
+  is(panel.clientHeight, panelHeight, "Opening the toolbox hasn't changed the height of the panel");
+  is(panel.clientWidth, panelWidth, "Opening the toolbox hasn't changed the width of the panel");
 
-  let iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-bottom-iframe");
-  is(iframe.clientHeight, nboxHeight - 25, "The iframe fits within the available space");
+  let iframe = panel.querySelector(".devtools-toolbox-bottom-iframe");
+  is(iframe.clientHeight, panelHeight - 25, "The iframe fits within the available space");
 
   await toolbox.switchHost(Toolbox.HostType.RIGHT);
-  iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-side-iframe");
+  iframe = panel.querySelector(".devtools-toolbox-side-iframe");
   iframe.style.minWidth = "1px"; // Disable the min width set in css
-  is(iframe.clientWidth, nboxWidth - 25, "The iframe fits within the available space");
+  is(iframe.clientWidth, panelWidth - 25, "The iframe fits within the available space");
 
   await cleanup(toolbox);
 });
 
 add_task(async function() {
   // Set size prefs to something reasonable, so we can check to make sure
   // they are being set properly.
   Services.prefs.setIntPref("devtools.toolbox.footer.height", 100);
   Services.prefs.setIntPref("devtools.toolbox.sidebar.width", 100);
 
   const tab = await addTab(URL);
-  const nbox = gBrowser.getNotificationBox();
-  const {clientHeight: nboxHeight, clientWidth: nboxWidth} = nbox;
+  const panel = gBrowser.getPanel();
+  const {clientHeight: panelHeight, clientWidth: panelWidth} = panel;
   const target = await TargetFactory.forTab(tab);
   const toolbox = await gDevTools.showToolbox(target);
 
-  is(nbox.clientHeight, nboxHeight, "Opening the toolbox hasn't changed the height of the nbox");
-  is(nbox.clientWidth, nboxWidth, "Opening the toolbox hasn't changed the width of the nbox");
+  is(panel.clientHeight, panelHeight, "Opening the toolbox hasn't changed the height of the panel");
+  is(panel.clientWidth, panelWidth, "Opening the toolbox hasn't changed the width of the panel");
 
-  let iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-bottom-iframe");
+  let iframe = panel.querySelector(".devtools-toolbox-bottom-iframe");
   is(iframe.clientHeight, 100, "The iframe is resized properly");
 
   await toolbox.switchHost(Toolbox.HostType.RIGHT);
-  iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-side-iframe");
+  iframe = panel.querySelector(".devtools-toolbox-side-iframe");
   iframe.style.minWidth = "1px"; // Disable the min width set in css
   is(iframe.clientWidth, 100, "The iframe is resized properly");
 
   await cleanup(toolbox);
 });
 
 async function cleanup(toolbox) {
   Services.prefs.clearUserPref("devtools.toolbox.host");
--- a/devtools/client/framework/toolbox-hosts.js
+++ b/devtools/client/framework/toolbox-hosts.js
@@ -45,33 +45,34 @@ BottomHost.prototype = {
   /**
    * Create a box at the bottom of the host tab.
    */
   create: async function() {
     await gDevToolsBrowser.loadBrowserStyleSheet(this.hostTab.ownerGlobal);
 
     const gBrowser = this.hostTab.ownerDocument.defaultView.gBrowser;
     const ownerDocument = gBrowser.ownerDocument;
-    this._nbox = gBrowser.getNotificationBox(this.hostTab.linkedBrowser);
+    this._browserContainer =
+      gBrowser.getBrowserContainer(this.hostTab.linkedBrowser);
 
     this._splitter = ownerDocument.createXULElement("splitter");
     this._splitter.setAttribute("class", "devtools-horizontal-splitter");
     // Avoid resizing notification containers
     this._splitter.setAttribute("resizebefore", "flex");
 
     this.frame = ownerDocument.createXULElement("iframe");
     this.frame.flex = 1; // Required to be able to shrink when the window shrinks
     this.frame.className = "devtools-toolbox-bottom-iframe";
     this.frame.height = Math.min(
       Services.prefs.getIntPref(this.heightPref),
-      this._nbox.clientHeight - MIN_PAGE_SIZE
+      this._browserContainer.clientHeight - MIN_PAGE_SIZE
     );
 
-    this._nbox.appendChild(this._splitter);
-    this._nbox.appendChild(this.frame);
+    this._browserContainer.appendChild(this._splitter);
+    this._browserContainer.appendChild(this.frame);
 
     this.frame.tooltip = "aHTMLTooltip";
 
     // we have to load something so we can switch documents if we have to
     this.frame.setAttribute("src", "about:blank");
 
     const frame = await new Promise(resolve => {
       const domHelper = new DOMHelpers(this.frame.contentWindow);
@@ -102,20 +103,20 @@ BottomHost.prototype = {
   /**
    * Destroy the bottom dock.
    */
   destroy: function() {
     if (!this._destroyed) {
       this._destroyed = true;
 
       Services.prefs.setIntPref(this.heightPref, this.frame.height);
-      this._nbox.removeChild(this._splitter);
-      this._nbox.removeChild(this.frame);
+      this._browserContainer.removeChild(this._splitter);
+      this._browserContainer.removeChild(this.frame);
       this.frame = null;
-      this._nbox = null;
+      this._browserContainer = null;
       this._splitter = null;
     }
 
     return promise.resolve(null);
   },
 };
 
 /**
@@ -132,43 +133,43 @@ class SidebarHost {
 
   /**
    * Create a box in the sidebar of the host tab.
    */
   async create() {
     await gDevToolsBrowser.loadBrowserStyleSheet(this.hostTab.ownerGlobal);
     const gBrowser = this.hostTab.ownerDocument.defaultView.gBrowser;
     const ownerDocument = gBrowser.ownerDocument;
-    this._browser = gBrowser.getBrowserContainer(this.hostTab.linkedBrowser);
-    this._sidebar = gBrowser.getSidebarContainer(this.hostTab.linkedBrowser);
+    this._browserContainer = gBrowser.getBrowserContainer(this.hostTab.linkedBrowser);
+    this._browserPanel = gBrowser.getPanel(this.hostTab.linkedBrowser);
 
     this._splitter = ownerDocument.createXULElement("splitter");
     this._splitter.setAttribute("class", "devtools-side-splitter");
 
     this.frame = ownerDocument.createXULElement("iframe");
     this.frame.flex = 1; // Required to be able to shrink when the window shrinks
     this.frame.className = "devtools-toolbox-side-iframe";
 
     this.frame.width = Math.min(
       Services.prefs.getIntPref(this.widthPref),
-      this._sidebar.clientWidth - MIN_PAGE_SIZE
+      this._browserPanel.clientWidth - MIN_PAGE_SIZE
     );
 
     // We should consider the direction when changing the dock position.
     const topWindow = this.hostTab.ownerDocument.defaultView.top;
     const topDoc = topWindow.document.documentElement;
     const isLTR = topWindow.getComputedStyle(topDoc).direction === "ltr";
 
     if (isLTR && this.type == "right" ||
         !isLTR && this.type == "left") {
-      this._sidebar.appendChild(this._splitter);
-      this._sidebar.appendChild(this.frame);
+      this._browserPanel.appendChild(this._splitter);
+      this._browserPanel.appendChild(this.frame);
     } else {
-      this._sidebar.insertBefore(this.frame, this._browser);
-      this._sidebar.insertBefore(this._splitter, this._browser);
+      this._browserPanel.insertBefore(this.frame, this._browserContainer);
+      this._browserPanel.insertBefore(this._splitter, this._browserContainer);
     }
 
     this.frame.tooltip = "aHTMLTooltip";
     this.frame.setAttribute("src", "about:blank");
 
     const frame = await new Promise(resolve => {
       const domHelper = new DOMHelpers(this.frame.contentWindow);
       const frameLoad = () => {
@@ -198,18 +199,18 @@ class SidebarHost {
   /**
    * Destroy the sidebar.
    */
   destroy() {
     if (!this._destroyed) {
       this._destroyed = true;
 
       Services.prefs.setIntPref(this.widthPref, this.frame.width);
-      this._sidebar.removeChild(this._splitter);
-      this._sidebar.removeChild(this.frame);
+      this._browserPanel.removeChild(this._splitter);
+      this._browserPanel.removeChild(this.frame);
     }
 
     return promise.resolve(null);
   }
 }
 
 /**
  * Host object for the in-browser left sidebar
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -912,22 +912,17 @@ Tester.prototype = {
             sidebar.setAttribute("src", "about:blank");
           }
 
           // Destroy BackgroundPageThumbs resources.
           let {BackgroundPageThumbs} =
             ChromeUtils.import("resource://gre/modules/BackgroundPageThumbs.jsm", {});
           BackgroundPageThumbs._destroy();
 
-          // Destroy preloaded browsers.
-          if (gBrowser._preloadedBrowser) {
-            let browser = gBrowser._preloadedBrowser;
-            gBrowser._preloadedBrowser = null;
-            gBrowser.getNotificationBox(browser).remove();
-          }
+          gBrowser.removePreloadedBrowser();
         }
 
         // Schedule GC and CC runs before finishing in order to detect
         // DOM windows leaked by our tests or the tested code. Note that we
         // use a shrinking GC so that the JS engine will discard JIT code and
         // JIT caches more aggressively.
 
         let shutdownCleanup = aCallback => {