michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: let stateBackup = ss.getBrowserState(); michael@0: michael@0: function cleanup() { michael@0: // Reset the pref michael@0: try { michael@0: Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand"); michael@0: } catch (e) {} michael@0: ss.setBrowserState(stateBackup); michael@0: executeSoon(finish); michael@0: } michael@0: michael@0: function test() { michael@0: /** Bug 607016 - If a tab is never restored, attributes (eg. hidden) aren't updated correctly **/ michael@0: waitForExplicitFinish(); michael@0: ignoreAllUncaughtExceptions(); michael@0: michael@0: // Set the pref to true so we know exactly how many tabs should be restoring at michael@0: // any given time. This guarantees that a finishing load won't start another. michael@0: Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true); michael@0: michael@0: // We have our own progress listener for this test, which we'll attach before our state is set michael@0: let progressListener = { michael@0: onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) { michael@0: if (aBrowser.__SS_restoreState == TAB_STATE_RESTORING && michael@0: aStateFlags & Ci.nsIWebProgressListener.STATE_STOP && michael@0: aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK && michael@0: aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) michael@0: progressCallback(aBrowser); michael@0: } michael@0: } michael@0: michael@0: let state = { windows: [{ tabs: [ michael@0: { entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } }, michael@0: { entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } }, // overwriting michael@0: { entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } }, // hiding michael@0: { entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }, // adding michael@0: { entries: [{ url: "http://example.org#5" }], extData: { "uniq": r() } }, // deleting michael@0: { entries: [{ url: "http://example.org#6" }] } // creating michael@0: ], selected: 1 }] }; michael@0: michael@0: function progressCallback(aBrowser) { michael@0: // We'll remove the progress listener after the first one because we aren't michael@0: // loading any other tabs michael@0: window.gBrowser.removeTabsProgressListener(progressListener); michael@0: michael@0: let curState = JSON.parse(ss.getBrowserState()); michael@0: for (let i = 0; i < curState.windows[0].tabs.length; i++) { michael@0: let tabState = state.windows[0].tabs[i]; michael@0: let tabCurState = curState.windows[0].tabs[i]; michael@0: if (tabState.extData) { michael@0: is(tabCurState.extData["uniq"], tabState.extData["uniq"], michael@0: "sanity check that tab has correct extData"); michael@0: } michael@0: else { michael@0: // We aren't expecting there to be any data on extData, but panorama michael@0: // may be setting something, so we need to make sure that if we do have michael@0: // data, we just don't have anything for "uniq". michael@0: ok(!("extData" in tabCurState) || !("uniq" in tabCurState.extData), michael@0: "sanity check that tab doesn't have extData or extData doesn't have 'uniq'"); michael@0: } michael@0: } michael@0: michael@0: // Now we'll set a new unique value on 1 of the tabs michael@0: let newUniq = r(); michael@0: ss.setTabValue(gBrowser.tabs[1], "uniq", newUniq); michael@0: gBrowser.removeTab(gBrowser.tabs[1]); michael@0: let closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0]; michael@0: is(closedTabData.state.extData.uniq, newUniq, michael@0: "(overwriting) new data is stored in extData"); michael@0: michael@0: // hide the next tab before closing it michael@0: gBrowser.hideTab(gBrowser.tabs[1]); michael@0: gBrowser.removeTab(gBrowser.tabs[1]); michael@0: closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0]; michael@0: ok(closedTabData.state.hidden, "(hiding) tab data has hidden == true"); michael@0: michael@0: // set data that's not in a conflicting key michael@0: let stillUniq = r(); michael@0: ss.setTabValue(gBrowser.tabs[1], "stillUniq", stillUniq); michael@0: gBrowser.removeTab(gBrowser.tabs[1]); michael@0: closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0]; michael@0: is(closedTabData.state.extData.stillUniq, stillUniq, michael@0: "(adding) new data is stored in extData"); michael@0: michael@0: // remove the uniq value and make sure it's not there in the closed data michael@0: ss.deleteTabValue(gBrowser.tabs[1], "uniq"); michael@0: gBrowser.removeTab(gBrowser.tabs[1]); michael@0: closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0]; michael@0: // Since Panorama might have put data in, first check if there is extData. michael@0: // If there is explicitly check that "uniq" isn't in it. Otherwise, we're ok michael@0: if ("extData" in closedTabData.state) { michael@0: ok(!("uniq" in closedTabData.state.extData), michael@0: "(deleting) uniq not in existing extData"); michael@0: } michael@0: else { michael@0: ok(true, "(deleting) no data is stored in extData"); michael@0: } michael@0: michael@0: // set unique data on the tab that never had any set, make sure that's saved michael@0: let newUniq2 = r(); michael@0: ss.setTabValue(gBrowser.tabs[1], "uniq", newUniq2); michael@0: gBrowser.removeTab(gBrowser.tabs[1]); michael@0: closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0]; michael@0: is(closedTabData.state.extData.uniq, newUniq2, michael@0: "(creating) new data is stored in extData where there was none"); michael@0: michael@0: cleanup(); michael@0: } michael@0: michael@0: window.gBrowser.addTabsProgressListener(progressListener); michael@0: ss.setBrowserState(JSON.stringify(state)); michael@0: } michael@0: