michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: const STATE = { michael@0: windows: [{ michael@0: tabs: [{ michael@0: entries: [{ url: "about:mozilla" }], michael@0: hidden: true, michael@0: extData: {"tabview-tab": '{"url":"about:mozilla","groupID":1}'} michael@0: },{ michael@0: entries: [{ url: "about:robots" }], michael@0: hidden: false, michael@0: extData: {"tabview-tab": '{"url":"about:robots","groupID":1}'}, michael@0: }], michael@0: selected: 1, michael@0: extData: { michael@0: "tabview-groups": '{"nextID":2,"activeGroupId":1, "totalNumber":1}', michael@0: "tabview-group": michael@0: '{"1":{"bounds":{"left":15,"top":5,"width":280,"height":232},"id":1}}' michael@0: } michael@0: }] michael@0: }; michael@0: michael@0: /** michael@0: * Make sure that tabs are restored on demand as otherwise the tab will start michael@0: * loading immediately and we can't check whether it shows cached data. michael@0: */ michael@0: add_task(function setup() { michael@0: Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true); michael@0: michael@0: registerCleanupFunction(() => { michael@0: Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand"); michael@0: }); michael@0: }); michael@0: michael@0: /** michael@0: * Ensure that a pending tab shows cached data. michael@0: */ michael@0: add_task(function () { michael@0: // Open a new window. michael@0: let win = OpenBrowserWindow(); michael@0: yield promiseDelayedStartupFinished(win); michael@0: michael@0: // Set the window to a specific state. michael@0: let ss = Cc["@mozilla.org/browser/sessionstore;1"] michael@0: .getService(Ci.nsISessionStore) michael@0: .setWindowState(win, JSON.stringify(STATE), true); michael@0: michael@0: // Open Panorama. michael@0: yield promiseTabViewShown(win); michael@0: michael@0: let [tab1, tab2] = win.gBrowser.tabs; michael@0: let cw = win.TabView.getContentWindow(); michael@0: michael@0: // Update the two tabs in reverse order. Panorama will first try to update michael@0: // the second tab but will put it back onto the queue once it detects that michael@0: // it hasn't loaded yet. It will then try to update the first tab. michael@0: cw.TabItems.update(tab2); michael@0: cw.TabItems.update(tab1); michael@0: michael@0: let tabItem1 = tab1._tabViewTabItem; michael@0: let tabItem2 = tab2._tabViewTabItem; michael@0: michael@0: // Wait for the first tabItem to be updated. Calling update() on the second michael@0: // tabItem won't send a notification as that is pushed back onto the queue. michael@0: yield promiseTabItemUpdated(tabItem1); michael@0: michael@0: // Check that the first tab doesn't show cached data, the second one does. michael@0: ok(!tabItem1.isShowingCachedData(), "doesn't show cached data"); michael@0: ok(tabItem2.isShowingCachedData(), "shows cached data"); michael@0: michael@0: // Cleanup. michael@0: yield promiseWindowClosed(win); michael@0: }); michael@0: michael@0: function promiseTabItemUpdated(tabItem) { michael@0: let deferred = Promise.defer(); michael@0: michael@0: tabItem.addSubscriber("updated", function onUpdated() { michael@0: tabItem.removeSubscriber("updated", onUpdated); michael@0: deferred.resolve(); michael@0: }); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function promiseAllTabItemsUpdated(win) { michael@0: let deferred = Promise.defer(); michael@0: afterAllTabItemsUpdated(deferred.resolve, win); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function promiseDelayedStartupFinished(win) { michael@0: let deferred = Promise.defer(); michael@0: whenDelayedStartupFinished(win, deferred.resolve); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function promiseTabViewShown(win) { michael@0: let deferred = Promise.defer(); michael@0: showTabView(deferred.resolve, win); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function promiseWindowClosed(win) { michael@0: let deferred = Promise.defer(); michael@0: michael@0: Services.obs.addObserver(function obs(subject, topic) { michael@0: if (subject == win) { michael@0: Services.obs.removeObserver(obs, topic); michael@0: deferred.resolve(); michael@0: } michael@0: }, "domwindowclosed", false); michael@0: michael@0: win.close(); michael@0: return deferred.promise; michael@0: }