|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 function checkState(tab) { |
|
6 // Go back and then forward, and make sure that the state objects received |
|
7 // from the popState event are as we expect them to be. |
|
8 // |
|
9 // We also add a node to the document's body when after going back and make |
|
10 // sure it's still there after we go forward -- this is to test that the two |
|
11 // history entries correspond to the same document. |
|
12 |
|
13 let popStateCount = 0; |
|
14 |
|
15 tab.linkedBrowser.addEventListener('popstate', function(aEvent) { |
|
16 let contentWindow = tab.linkedBrowser.contentWindow; |
|
17 if (popStateCount == 0) { |
|
18 popStateCount++; |
|
19 |
|
20 is(tab.linkedBrowser.contentWindow.testState, 'foo', |
|
21 'testState after going back'); |
|
22 |
|
23 ok(aEvent.state, "Event should have a state property."); |
|
24 is(JSON.stringify(tab.linkedBrowser.contentWindow.history.state), JSON.stringify({obj1:1}), |
|
25 "first popstate object."); |
|
26 |
|
27 // Add a node with id "new-elem" to the document. |
|
28 let doc = contentWindow.document; |
|
29 ok(!doc.getElementById("new-elem"), |
|
30 "doc shouldn't contain new-elem before we add it."); |
|
31 let elem = doc.createElement("div"); |
|
32 elem.id = "new-elem"; |
|
33 doc.body.appendChild(elem); |
|
34 |
|
35 contentWindow.history.forward(); |
|
36 } |
|
37 else if (popStateCount == 1) { |
|
38 popStateCount++; |
|
39 is(aEvent.state.obj3.toString(), '/^a$/', "second popstate object."); |
|
40 |
|
41 // Make sure that the new-elem node is present in the document. If it's |
|
42 // not, then this history entry has a different doc identifier than the |
|
43 // previous entry, which is bad. |
|
44 let doc = contentWindow.document; |
|
45 let newElem = doc.getElementById("new-elem"); |
|
46 ok(newElem, "doc should contain new-elem."); |
|
47 newElem.parentNode.removeChild(newElem); |
|
48 ok(!doc.getElementById("new-elem"), "new-elem should be removed."); |
|
49 |
|
50 // Clean up after ourselves and finish the test. |
|
51 tab.linkedBrowser.removeEventListener("popstate", arguments.callee, true); |
|
52 gBrowser.removeTab(tab); |
|
53 finish(); |
|
54 } |
|
55 }, true); |
|
56 |
|
57 // Set some state in the page's window. When we go back(), the page should |
|
58 // be retrieved from bfcache, and this state should still be there. |
|
59 tab.linkedBrowser.contentWindow.testState = 'foo'; |
|
60 |
|
61 // Now go back. This should trigger the popstate event handler above. |
|
62 tab.linkedBrowser.contentWindow.history.back(); |
|
63 } |
|
64 |
|
65 function test() { |
|
66 // Tests session restore functionality of history.pushState and |
|
67 // history.replaceState(). (Bug 500328) |
|
68 |
|
69 waitForExplicitFinish(); |
|
70 |
|
71 // We open a new blank window, let it load, and then load in |
|
72 // http://example.com. We need to load the blank window first, otherwise the |
|
73 // docshell gets confused and doesn't have a current history entry. |
|
74 let tab = gBrowser.addTab("about:blank"); |
|
75 let browser = tab.linkedBrowser; |
|
76 |
|
77 whenBrowserLoaded(browser, function() { |
|
78 browser.loadURI("http://example.com", null, null); |
|
79 |
|
80 whenBrowserLoaded(browser, function() { |
|
81 // After these push/replaceState calls, the window should have three |
|
82 // history entries: |
|
83 // testURL (state object: null) <-- oldest |
|
84 // testURL (state object: {obj1:1}) |
|
85 // testURL?page2 (state object: {obj3:/^a$/}) <-- newest |
|
86 let contentWindow = tab.linkedBrowser.contentWindow; |
|
87 let history = contentWindow.history; |
|
88 history.pushState({obj1:1}, "title-obj1"); |
|
89 history.pushState({obj2:2}, "title-obj2", "?page2"); |
|
90 history.replaceState({obj3:/^a$/}, "title-obj3"); |
|
91 |
|
92 SyncHandlers.get(tab.linkedBrowser).flush(); |
|
93 let state = ss.getTabState(tab); |
|
94 gBrowser.removeTab(tab); |
|
95 |
|
96 // Restore the state into a new tab. Things don't work well when we |
|
97 // restore into the old tab, but that's not a real use case anyway. |
|
98 let tab2 = gBrowser.addTab("about:blank"); |
|
99 ss.setTabState(tab2, state, true); |
|
100 |
|
101 // Run checkState() once the tab finishes loading its restored state. |
|
102 whenTabRestored(tab2, function() { |
|
103 SimpleTest.executeSoon(function() { |
|
104 checkState(tab2); |
|
105 }); |
|
106 }); |
|
107 |
|
108 }); |
|
109 }); |
|
110 } |