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,
});
gBrowser.hideTab(containerTab);
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