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: function checkState(tab) { michael@0: // Go back and then forward, and make sure that the state objects received michael@0: // from the popState event are as we expect them to be. michael@0: // michael@0: // We also add a node to the document's body when after going back and make michael@0: // sure it's still there after we go forward -- this is to test that the two michael@0: // history entries correspond to the same document. michael@0: michael@0: let popStateCount = 0; michael@0: michael@0: tab.linkedBrowser.addEventListener('popstate', function(aEvent) { michael@0: let contentWindow = tab.linkedBrowser.contentWindow; michael@0: if (popStateCount == 0) { michael@0: popStateCount++; michael@0: michael@0: is(tab.linkedBrowser.contentWindow.testState, 'foo', michael@0: 'testState after going back'); michael@0: michael@0: ok(aEvent.state, "Event should have a state property."); michael@0: is(JSON.stringify(tab.linkedBrowser.contentWindow.history.state), JSON.stringify({obj1:1}), michael@0: "first popstate object."); michael@0: michael@0: // Add a node with id "new-elem" to the document. michael@0: let doc = contentWindow.document; michael@0: ok(!doc.getElementById("new-elem"), michael@0: "doc shouldn't contain new-elem before we add it."); michael@0: let elem = doc.createElement("div"); michael@0: elem.id = "new-elem"; michael@0: doc.body.appendChild(elem); michael@0: michael@0: contentWindow.history.forward(); michael@0: } michael@0: else if (popStateCount == 1) { michael@0: popStateCount++; michael@0: is(aEvent.state.obj3.toString(), '/^a$/', "second popstate object."); michael@0: michael@0: // Make sure that the new-elem node is present in the document. If it's michael@0: // not, then this history entry has a different doc identifier than the michael@0: // previous entry, which is bad. michael@0: let doc = contentWindow.document; michael@0: let newElem = doc.getElementById("new-elem"); michael@0: ok(newElem, "doc should contain new-elem."); michael@0: newElem.parentNode.removeChild(newElem); michael@0: ok(!doc.getElementById("new-elem"), "new-elem should be removed."); michael@0: michael@0: // Clean up after ourselves and finish the test. michael@0: tab.linkedBrowser.removeEventListener("popstate", arguments.callee, true); michael@0: gBrowser.removeTab(tab); michael@0: finish(); michael@0: } michael@0: }, true); michael@0: michael@0: // Set some state in the page's window. When we go back(), the page should michael@0: // be retrieved from bfcache, and this state should still be there. michael@0: tab.linkedBrowser.contentWindow.testState = 'foo'; michael@0: michael@0: // Now go back. This should trigger the popstate event handler above. michael@0: tab.linkedBrowser.contentWindow.history.back(); michael@0: } michael@0: michael@0: function test() { michael@0: // Tests session restore functionality of history.pushState and michael@0: // history.replaceState(). (Bug 500328) michael@0: michael@0: waitForExplicitFinish(); michael@0: michael@0: // We open a new blank window, let it load, and then load in michael@0: // http://example.com. We need to load the blank window first, otherwise the michael@0: // docshell gets confused and doesn't have a current history entry. michael@0: let tab = gBrowser.addTab("about:blank"); michael@0: let browser = tab.linkedBrowser; michael@0: michael@0: whenBrowserLoaded(browser, function() { michael@0: browser.loadURI("http://example.com", null, null); michael@0: michael@0: whenBrowserLoaded(browser, function() { michael@0: // After these push/replaceState calls, the window should have three michael@0: // history entries: michael@0: // testURL (state object: null) <-- oldest michael@0: // testURL (state object: {obj1:1}) michael@0: // testURL?page2 (state object: {obj3:/^a$/}) <-- newest michael@0: let contentWindow = tab.linkedBrowser.contentWindow; michael@0: let history = contentWindow.history; michael@0: history.pushState({obj1:1}, "title-obj1"); michael@0: history.pushState({obj2:2}, "title-obj2", "?page2"); michael@0: history.replaceState({obj3:/^a$/}, "title-obj3"); michael@0: michael@0: SyncHandlers.get(tab.linkedBrowser).flush(); michael@0: let state = ss.getTabState(tab); michael@0: gBrowser.removeTab(tab); michael@0: michael@0: // Restore the state into a new tab. Things don't work well when we michael@0: // restore into the old tab, but that's not a real use case anyway. michael@0: let tab2 = gBrowser.addTab("about:blank"); michael@0: ss.setTabState(tab2, state, true); michael@0: michael@0: // Run checkState() once the tab finishes loading its restored state. michael@0: whenTabRestored(tab2, function() { michael@0: SimpleTest.executeSoon(function() { michael@0: checkState(tab2); michael@0: }); michael@0: }); michael@0: michael@0: }); michael@0: }); michael@0: }