Bug 1331601 - Copy tab listener state flags in RDM. r=ochameau
authorJ. Ryan Stinnett <jryans@gmail.com>
Thu, 19 Jan 2017 13:25:14 -0600
changeset 464576 0de2f57ed353e10176053d1e83f95d42f031c1be
parent 464575 48136ce8a357144b3d9af7f7075a41569a94b865
child 464577 bdfebb742afe2d328e63fefb08ba283cc95718e7
push id42370
push usermwein@mozilla.com
push dateSat, 21 Jan 2017 03:10:58 +0000
Bug 1331601 - Copy tab listener state flags in RDM. r=ochameau When starting and stopping RDM, we need want to ensure tab listener state flags are preserved for the tab involved, which is a bit tricky with the tab dance RDM is doing. The state flags ensure the browser will call the correct handlers when switching tabs to update the primary browser UI. For example, this is needed to correctly update the enabled state of the view source command for the current tab. MozReview-Commit-ID: 7lKY0DKxgJH
--- a/devtools/client/responsive.html/browser/swap.js
+++ b/devtools/client/responsive.html/browser/swap.js
@@ -59,16 +59,23 @@ function swapToInnerBrowser({ tab, conta
       // 1. Create a temporary, hidden tab to load the tool UI.
       let containerTab = gBrowser.addTab(containerURL, {
         skipAnimation: true,
       let containerBrowser = containerTab.linkedBrowser;
+      // Copy tab listener state flags to container tab.  Each tab gets its own tab
+      // listener and state flags which cache document loading progress.  The state flags
+      // are checked when switching tabs to update the browser UI.  The later step of
+      // `swapBrowsersAndCloseOther` will fold the state back into the main tab.
+      let stateFlags = gBrowser._tabListeners.get(tab).mStateFlags;
+      gBrowser._tabListeners.get(containerTab).mStateFlags = stateFlags;
       // 2. Mark the tool tab browser's docshell as active so the viewport frame
       //    is created eagerly and will be ready to swap.
       // This line is crucial when the tool UI is loaded into a background tab.
       // Without it, the viewport browser's frame is created lazily, leading to
       // a multi-second delay before it would be possible to `swapFrameLoaders`.
       // Even worse than the delay, there appears to be no obvious event fired
       // after the frame is set lazily, so it's unclear how to know that work
       // has finished.
@@ -142,16 +149,21 @@ function swapToInnerBrowser({ tab, conta
       // 4. Swap tab content from the browser within the viewport in the tool UI
       //    to the regular browser tab, preserving all state via
       //    `gBrowser._swapBrowserDocShells`.
       dispatchDevToolsBrowserSwap(innerBrowser, contentBrowser);
       gBrowser._swapBrowserDocShells(contentTab, innerBrowser);
       innerBrowser = null;
+      // Copy tab listener state flags to content tab.  See similar comment in `start`
+      // above for more details.
+      let stateFlags = gBrowser._tabListeners.get(tab).mStateFlags;
+      gBrowser._tabListeners.get(contentTab).mStateFlags = stateFlags;
       // 5. Force the original browser tab to be remote since web content is
       //    loaded in the child process, and we're about to swap the content
       //    into this tab.
       gBrowser.updateBrowserRemoteness(tab.linkedBrowser, true, {
         remoteType: contentBrowser.remoteType,
       // 6. Swap the content into the original browser tab and close the