michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: let state = {windows:[{tabs:[ michael@0: {entries:[{url:"http://example.com#1"}]}, michael@0: {entries:[{url:"http://example.com#2"}]}, michael@0: {entries:[{url:"http://example.com#3"}]}, michael@0: {entries:[{url:"http://example.com#4"}]}, michael@0: {entries:[{url:"http://example.com#5"}], hidden: true}, michael@0: {entries:[{url:"http://example.com#6"}], hidden: true}, michael@0: {entries:[{url:"http://example.com#7"}], hidden: true}, michael@0: {entries:[{url:"http://example.com#8"}], hidden: true} michael@0: ]}]}; michael@0: michael@0: function test() { michael@0: waitForExplicitFinish(); michael@0: michael@0: registerCleanupFunction(function () { michael@0: Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs"); michael@0: }); michael@0: michael@0: // First stage: restoreHiddenTabs = true michael@0: // Second stage: restoreHiddenTabs = false michael@0: test_loadTabs(true, function () { michael@0: test_loadTabs(false, finish); michael@0: }); michael@0: } michael@0: michael@0: function test_loadTabs(restoreHiddenTabs, callback) { michael@0: Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", restoreHiddenTabs); michael@0: michael@0: let expectedTabs = restoreHiddenTabs ? 8 : 4; michael@0: let firstProgress = true; michael@0: michael@0: newWindowWithState(state, function (win, needsRestore, isRestoring) { michael@0: if (firstProgress) { michael@0: firstProgress = false; michael@0: is(isRestoring, 3, "restoring 3 tabs concurrently"); michael@0: } else { michael@0: ok(isRestoring < 4, "restoring max. 3 tabs concurrently"); michael@0: } michael@0: michael@0: // We're explicity checking for (isRestoring == 1) here because the test michael@0: // progress listener is called before the session store one. So when we're michael@0: // called with one tab left to restore we know that the last tab has michael@0: // finished restoring and will soon be handled by the SS listener. michael@0: let tabsNeedingRestore = win.gBrowser.tabs.length - needsRestore; michael@0: if (isRestoring == 1 && tabsNeedingRestore == expectedTabs) { michael@0: is(win.gBrowser.visibleTabs.length, 4, "only 4 visible tabs"); michael@0: michael@0: TabsProgressListener.uninit(); michael@0: executeSoon(callback); michael@0: } michael@0: }); michael@0: } michael@0: michael@0: let TabsProgressListener = { michael@0: init: function (win) { michael@0: this.window = win; michael@0: Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false); michael@0: }, michael@0: michael@0: uninit: function () { michael@0: Services.obs.removeObserver(this, "sessionstore-debug-tab-restored"); michael@0: michael@0: delete this.window; michael@0: delete this.callback; michael@0: }, michael@0: michael@0: setCallback: function (callback) { michael@0: this.callback = callback; michael@0: }, michael@0: michael@0: observe: function (browser) { michael@0: TabsProgressListener.onRestored(browser); michael@0: }, michael@0: michael@0: onRestored: function (browser) { michael@0: if (this.callback && browser.__SS_restoreState == TAB_STATE_RESTORING) michael@0: this.callback.apply(null, [this.window].concat(this.countTabs())); michael@0: }, michael@0: michael@0: countTabs: function () { michael@0: let needsRestore = 0, isRestoring = 0; michael@0: michael@0: for (let i = 0; i < this.window.gBrowser.tabs.length; i++) { michael@0: let browser = this.window.gBrowser.tabs[i].linkedBrowser; michael@0: if (browser.__SS_restoreState == TAB_STATE_RESTORING) michael@0: isRestoring++; michael@0: else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE) michael@0: needsRestore++; michael@0: } michael@0: michael@0: return [needsRestore, isRestoring]; michael@0: } michael@0: } michael@0: michael@0: // ---------- michael@0: function newWindowWithState(state, callback) { michael@0: let opts = "chrome,all,dialog=no,height=800,width=800"; michael@0: let win = window.openDialog(getBrowserURL(), "_blank", opts); michael@0: michael@0: registerCleanupFunction(function () win.close()); michael@0: michael@0: whenWindowLoaded(win, function onWindowLoaded(aWin) { michael@0: TabsProgressListener.init(aWin); michael@0: TabsProgressListener.setCallback(callback); michael@0: michael@0: ss.setWindowState(aWin, JSON.stringify(state), true); michael@0: }); michael@0: }