diff --git a/browser/base/content/tabview/groupitems.js b/browser/base/content/tabview/groupitems.js index 9c30414d19a..224e90af64e 100644 --- a/browser/base/content/tabview/groupitems.js +++ b/browser/base/content/tabview/groupitems.js @@ -1747,18 +1747,35 @@ let GroupItems = { } if (groupItemData) { + var toClose = this.groupItems.concat(); for (var id in groupItemData) { - let groupItem = groupItemData[id]; - if (this.groupItemStorageSanity(groupItem)) { - var options = { - dontPush: true, - immediately: true - }; - - new GroupItem([], Utils.extend({}, groupItem, options)); + let data = groupItemData[id]; + if (this.groupItemStorageSanity(data)) { + let groupItem = this.groupItem(data.id); + if (groupItem) { + groupItem.userSize = data.userSize; + groupItem.setTitle(data.title); + groupItem.setBounds(data.bounds, true); + + let index = toClose.indexOf(groupItem); + if (index != -1) + toClose.splice(index, 1); + } else { + var options = { + dontPush: true, + immediately: true + }; + + new GroupItem([], Utils.extend({}, data, options)); + } } } + + toClose.forEach(function(groupItem) { + groupItem.close(); + }); } + // set active group item if (activeGroupId) { let activeGroupItem = this.groupItem(activeGroupId); @@ -1778,11 +1795,6 @@ let GroupItems = { // Loads the storage data for groups. // Returns true if there was global group data. load: function GroupItems_load() { - var toClose = this.groupItems.concat(); - toClose.forEach(function(groupItem) { - groupItem.close(); - }); - let groupItemsData = Storage.readGroupItemsData(gWindow); let groupItemData = Storage.readGroupItemData(gWindow); this.reconstitute(groupItemsData, groupItemData); diff --git a/browser/base/content/tabview/ui.js b/browser/base/content/tabview/ui.js index b74d8515f9d..495a53c2f63 100644 --- a/browser/base/content/tabview/ui.js +++ b/browser/base/content/tabview/ui.js @@ -106,6 +106,10 @@ let UI = { transitionMode: "", wasInTabView: false }, + + // Variable: _storageBusyCount + // Used to keep track of how many calls to storageBusy vs storageReady. + _storageBusyCount: 0, // ---------- // Function: init @@ -509,26 +513,53 @@ let UI = { }, #endif + // ---------- + // Function: storageBusy + // Pauses the storage activity that conflicts with sessionstore updates and + // private browsing mode switches. Calls can be nested. + storageBusy: function UI_storageBusy() { + if (!this._storageBusyCount) + TabItems.pauseReconnecting(); + + this._storageBusyCount++; + }, + + // ---------- + // Function: storageReady + // Resumes the activity paused by storageBusy, and updates for any new group + // information in sessionstore. Calls can be nested. + storageReady: function UI_storageReady() { + this._storageBusyCount--; + if (!this._storageBusyCount) { + let hasGroupItemsData = GroupItems.load(); + if (!hasGroupItemsData) + this.reset(false); + + TabItems.resumeReconnecting(); + } + }, + // ---------- // Function: _addTabActionHandlers // Adds handlers to handle tab actions. _addTabActionHandlers: function UI__addTabActionHandlers() { var self = this; - // session restore - function srObserver(aSubject, aTopic, aData) { - if (aTopic != "sessionstore-browser-state-restored") - return; - - let hasGroupItemsData = GroupItems.load(); - if (!hasGroupItemsData) - self.reset(false); + // session restore events + function handleSSWindowStateBusy() { + self.storageBusy(); } - - Services.obs.addObserver(srObserver, "sessionstore-browser-state-restored", false); + + function handleSSWindowStateReady() { + self.storageReady(); + } + + gWindow.addEventListener("SSWindowStateBusy", handleSSWindowStateBusy, false); + gWindow.addEventListener("SSWindowStateReady", handleSSWindowStateReady, false); this._cleanupFunctions.push(function() { - Services.obs.removeObserver(srObserver, "sessionstore-browser-state-restored"); + gWindow.removeEventListener("SSWindowStateBusy", handleSSWindowStateBusy, false); + gWindow.removeEventListener("SSWindowStateReady", handleSSWindowStateReady, false); }); // Private Browsing: @@ -551,7 +582,7 @@ let UI = { if (aData == "enter" || aData == "exit") { self._privateBrowsing.transitionMode = aData; GroupItems.pauseUpdatingTabBar(); - TabItems.pauseReconnecting(); + self.storageBusy(); } } else if (aTopic == "private-browsing-transition-complete") { // We use .transitionMode here, as aData is empty. @@ -560,7 +591,7 @@ let UI = { self.showTabView(false); self._privateBrowsing.transitionMode = ""; - TabItems.resumeReconnecting(); + self.storageReady(); GroupItems.resumeUpdatingTabBar(); } } diff --git a/browser/base/content/test/tabview/browser_tabview_bug608037.js b/browser/base/content/test/tabview/browser_tabview_bug608037.js index ddcc6a819e3..42ad7cc9658 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug608037.js +++ b/browser/base/content/test/tabview/browser_tabview_bug608037.js @@ -83,17 +83,21 @@ function onTabViewWindowLoaded() { is(groupItems[0].getChildren().length, 2, "The group has two tab items"); tabTwo = undoCloseTab(0); - ok(TabView.isVisible(), "Tab View is still visible after restoring a tab"); - is(groupItems[0].getChildren().length, 3, "The group has three tab items"); + tabTwo.tabItem.addSubscriber(tabTwo, "reconnected", function() { + tabTwo.tabItem.removeSubscriber(tabTwo, "reconnected"); - // clean up and finish - let endGame = function() { - window.removeEventListener("tabviewhidden", endGame, false); - - gBrowser.removeTab(tabOne); - gBrowser.removeTab(tabTwo); - finish(); - } - window.addEventListener("tabviewhidden", endGame, false); - TabView.toggle(); + ok(TabView.isVisible(), "Tab View is still visible after restoring a tab"); + is(groupItems[0].getChildren().length, 3, "The group still has three tab items"); + + // clean up and finish + let endGame = function() { + window.removeEventListener("tabviewhidden", endGame, false); + + gBrowser.removeTab(tabOne); + gBrowser.removeTab(tabTwo); + finish(); + } + window.addEventListener("tabviewhidden", endGame, false); + TabView.toggle(); + }); }