|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
5 |
|
6 function SHistoryListener() { |
|
7 } |
|
8 |
|
9 SHistoryListener.prototype = { |
|
10 retval: true, |
|
11 last: "initial", |
|
12 |
|
13 OnHistoryNewEntry: function (aNewURI) { |
|
14 this.last = "newentry"; |
|
15 }, |
|
16 |
|
17 OnHistoryGoBack: function (aBackURI) { |
|
18 this.last = "goback"; |
|
19 return this.retval; |
|
20 }, |
|
21 |
|
22 OnHistoryGoForward: function (aForwardURI) { |
|
23 this.last = "goforward"; |
|
24 return this.retval; |
|
25 }, |
|
26 |
|
27 OnHistoryGotoIndex: function (aIndex, aGotoURI) { |
|
28 this.last = "gotoindex"; |
|
29 return this.retval; |
|
30 }, |
|
31 |
|
32 OnHistoryPurge: function (aNumEntries) { |
|
33 this.last = "purge"; |
|
34 return this.retval; |
|
35 }, |
|
36 |
|
37 OnHistoryReload: function (aReloadURI, aReloadFlags) { |
|
38 this.last = "reload"; |
|
39 return this.retval; |
|
40 }, |
|
41 |
|
42 OnHistoryReplaceEntry: function (aIndex) {}, |
|
43 |
|
44 QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener, |
|
45 Ci.nsISupportsWeakReference]) |
|
46 }; |
|
47 |
|
48 let gFirstListener = new SHistoryListener(); |
|
49 let gSecondListener = new SHistoryListener(); |
|
50 |
|
51 function test() { |
|
52 TestRunner.run(); |
|
53 } |
|
54 |
|
55 function runTests() { |
|
56 yield setup(); |
|
57 let browser = gBrowser.selectedBrowser; |
|
58 checkListeners("initial", "listeners initialized"); |
|
59 |
|
60 // Check if all history listeners are always notified. |
|
61 info("# part 1"); |
|
62 browser.loadURI("http://www.example.com/"); |
|
63 yield whenPageShown(browser); |
|
64 checkListeners("newentry", "shistory has a new entry"); |
|
65 ok(browser.canGoBack, "we can go back"); |
|
66 |
|
67 browser.goBack(); |
|
68 yield whenPageShown(browser); |
|
69 checkListeners("goback", "back to the first shentry"); |
|
70 ok(browser.canGoForward, "we can go forward"); |
|
71 |
|
72 browser.goForward(); |
|
73 yield whenPageShown(browser); |
|
74 checkListeners("goforward", "forward to the second shentry"); |
|
75 |
|
76 browser.reload(); |
|
77 yield whenPageShown(browser); |
|
78 checkListeners("reload", "current shentry reloaded"); |
|
79 |
|
80 browser.gotoIndex(0); |
|
81 yield whenPageShown(browser); |
|
82 checkListeners("gotoindex", "back to the first index"); |
|
83 |
|
84 // Check nsISHistoryInternal.notifyOnHistoryReload |
|
85 info("# part 2"); |
|
86 ok(notifyReload(), "reloading has not been canceled"); |
|
87 checkListeners("reload", "saw the reload notification"); |
|
88 |
|
89 // Let the first listener cancel the reload action. |
|
90 info("# part 3"); |
|
91 resetListeners(); |
|
92 gFirstListener.retval = false; |
|
93 ok(!notifyReload(), "reloading has been canceled"); |
|
94 checkListeners("reload", "saw the reload notification"); |
|
95 |
|
96 // Let both listeners cancel the reload action. |
|
97 info("# part 4"); |
|
98 resetListeners(); |
|
99 gSecondListener.retval = false; |
|
100 ok(!notifyReload(), "reloading has been canceled"); |
|
101 checkListeners("reload", "saw the reload notification"); |
|
102 |
|
103 // Let the second listener cancel the reload action. |
|
104 info("# part 5"); |
|
105 resetListeners(); |
|
106 gFirstListener.retval = true; |
|
107 ok(!notifyReload(), "reloading has been canceled"); |
|
108 checkListeners("reload", "saw the reload notification"); |
|
109 } |
|
110 |
|
111 function checkListeners(aLast, aMessage) { |
|
112 is(gFirstListener.last, aLast, aMessage); |
|
113 is(gSecondListener.last, aLast, aMessage); |
|
114 } |
|
115 |
|
116 function resetListeners() { |
|
117 gFirstListener.last = gSecondListener.last = "initial"; |
|
118 } |
|
119 |
|
120 function notifyReload() { |
|
121 let browser = gBrowser.selectedBrowser; |
|
122 let shistory = browser.docShell.sessionHistory; |
|
123 shistory.QueryInterface(Ci.nsISHistoryInternal); |
|
124 return shistory.notifyOnHistoryReload(browser.currentURI, 0); |
|
125 } |
|
126 |
|
127 function setup(aCallback) { |
|
128 let tab = gBrowser.selectedTab = gBrowser.addTab("about:mozilla"); |
|
129 let browser = tab.linkedBrowser; |
|
130 registerCleanupFunction(function () gBrowser.removeTab(tab)); |
|
131 |
|
132 whenPageShown(browser, function () { |
|
133 gFirstListener = new SHistoryListener(); |
|
134 gSecondListener = new SHistoryListener(); |
|
135 |
|
136 let shistory = browser.docShell.sessionHistory; |
|
137 shistory.addSHistoryListener(gFirstListener); |
|
138 shistory.addSHistoryListener(gSecondListener); |
|
139 |
|
140 registerCleanupFunction(function () { |
|
141 shistory.removeSHistoryListener(gFirstListener); |
|
142 shistory.removeSHistoryListener(gSecondListener); |
|
143 }); |
|
144 |
|
145 (aCallback || TestRunner.next)(); |
|
146 }); |
|
147 } |
|
148 |
|
149 function whenPageShown(aBrowser, aCallback) { |
|
150 aBrowser.addEventListener("pageshow", function onLoad() { |
|
151 aBrowser.removeEventListener("pageshow", onLoad, true); |
|
152 executeSoon(aCallback || TestRunner.next); |
|
153 }, true); |
|
154 } |
|
155 |
|
156 let TestRunner = { |
|
157 run: function () { |
|
158 waitForExplicitFinish(); |
|
159 this._iter = runTests(); |
|
160 this.next(); |
|
161 }, |
|
162 |
|
163 next: function () { |
|
164 try { |
|
165 TestRunner._iter.next(); |
|
166 } catch (e if e instanceof StopIteration) { |
|
167 TestRunner.finish(); |
|
168 } |
|
169 }, |
|
170 |
|
171 finish: function () { |
|
172 finish(); |
|
173 } |
|
174 }; |