Bug 1247137 - Show spinner if switching away from browser that goes away immediately. r?billm draft
authorMike Conley <mconley@mozilla.com>
Wed, 04 May 2016 12:36:01 -0700
changeset 363969 48c10d88bb6c7745ba3929523821e27b67322d84
parent 363286 369a5ee3a2880a4a98df3a00bf3db8d8f36b181b
child 520179 33ad80aa33cde5907290fc0bd5e7911bc3bff04d
push id17352
push usermconley@mozilla.com
push dateThu, 05 May 2016 22:09:54 +0000
reviewersbillm
bugs1247137
milestone49.0a1
Bug 1247137 - Show spinner if switching away from browser that goes away immediately. r?billm MozReview-Commit-ID: ACQ7cBNn1TE
browser/base/content/tabbrowser.xml
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2495,16 +2495,26 @@
 
             // 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);
 
+            // 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) {
+              this._switcher.onTabRemoved(aTab);
+            }
+
             // This will unload the document. An unload handler could remove
             // dependant tabs, so it's important that the tabbrowser is now in
             // a consistent state (tab removed, tab positions updated, etc.).
             browser.parentNode.removeChild(browser);
 
             // Release the browser in case something is erroneously holding a
             // reference to the tab after its removal.
             this._tabForBrowser.delete(aTab.linkedBrowser);
@@ -3643,16 +3653,29 @@
                 if (this.getTabState(tab) == this.STATE_LOADING) {
                   this.onLayersReady(tab.linkedBrowser);
                 } else if (this.getTabState(tab) == this.STATE_UNLOADING) {
                   this.onLayersCleared(tab.linkedBrowser);
                 }
               }
             },
 
+            // Called when a tab has been removed, and the browser node is
+            // about to be removed from the DOM.
+            onTabRemoved: function(tab) {
+              if (this.lastVisibleTab == tab) {
+                // The browser that was being presented to the user is
+                // going to be removed during this tick of the event loop.
+                // This will cause us to show a tab spinner instead.
+                this.preActions();
+                this.lastVisibleTab = null;
+                this.postActions();
+              }
+            },
+
             // Called when the user asks to switch to a given tab.
             requestTab: function(tab) {
               if (tab === this.requestedTab) {
                 return;
               }
 
               // Instrumentation to figure out bug 1166351 - if the binding
               // on the browser we're switching to has gone away, try to find out