|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 let state = {windows:[{tabs:[ |
|
5 {entries:[{url:"http://example.com#1"}]}, |
|
6 {entries:[{url:"http://example.com#2"}]}, |
|
7 {entries:[{url:"http://example.com#3"}]}, |
|
8 {entries:[{url:"http://example.com#4"}]}, |
|
9 {entries:[{url:"http://example.com#5"}], hidden: true}, |
|
10 {entries:[{url:"http://example.com#6"}], hidden: true}, |
|
11 {entries:[{url:"http://example.com#7"}], hidden: true}, |
|
12 {entries:[{url:"http://example.com#8"}], hidden: true} |
|
13 ]}]}; |
|
14 |
|
15 function test() { |
|
16 waitForExplicitFinish(); |
|
17 |
|
18 registerCleanupFunction(function () { |
|
19 Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs"); |
|
20 }); |
|
21 |
|
22 // First stage: restoreHiddenTabs = true |
|
23 // Second stage: restoreHiddenTabs = false |
|
24 test_loadTabs(true, function () { |
|
25 test_loadTabs(false, finish); |
|
26 }); |
|
27 } |
|
28 |
|
29 function test_loadTabs(restoreHiddenTabs, callback) { |
|
30 Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", restoreHiddenTabs); |
|
31 |
|
32 let expectedTabs = restoreHiddenTabs ? 8 : 4; |
|
33 let firstProgress = true; |
|
34 |
|
35 newWindowWithState(state, function (win, needsRestore, isRestoring) { |
|
36 if (firstProgress) { |
|
37 firstProgress = false; |
|
38 is(isRestoring, 3, "restoring 3 tabs concurrently"); |
|
39 } else { |
|
40 ok(isRestoring < 4, "restoring max. 3 tabs concurrently"); |
|
41 } |
|
42 |
|
43 // We're explicity checking for (isRestoring == 1) here because the test |
|
44 // progress listener is called before the session store one. So when we're |
|
45 // called with one tab left to restore we know that the last tab has |
|
46 // finished restoring and will soon be handled by the SS listener. |
|
47 let tabsNeedingRestore = win.gBrowser.tabs.length - needsRestore; |
|
48 if (isRestoring == 1 && tabsNeedingRestore == expectedTabs) { |
|
49 is(win.gBrowser.visibleTabs.length, 4, "only 4 visible tabs"); |
|
50 |
|
51 TabsProgressListener.uninit(); |
|
52 executeSoon(callback); |
|
53 } |
|
54 }); |
|
55 } |
|
56 |
|
57 let TabsProgressListener = { |
|
58 init: function (win) { |
|
59 this.window = win; |
|
60 Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false); |
|
61 }, |
|
62 |
|
63 uninit: function () { |
|
64 Services.obs.removeObserver(this, "sessionstore-debug-tab-restored"); |
|
65 |
|
66 delete this.window; |
|
67 delete this.callback; |
|
68 }, |
|
69 |
|
70 setCallback: function (callback) { |
|
71 this.callback = callback; |
|
72 }, |
|
73 |
|
74 observe: function (browser) { |
|
75 TabsProgressListener.onRestored(browser); |
|
76 }, |
|
77 |
|
78 onRestored: function (browser) { |
|
79 if (this.callback && browser.__SS_restoreState == TAB_STATE_RESTORING) |
|
80 this.callback.apply(null, [this.window].concat(this.countTabs())); |
|
81 }, |
|
82 |
|
83 countTabs: function () { |
|
84 let needsRestore = 0, isRestoring = 0; |
|
85 |
|
86 for (let i = 0; i < this.window.gBrowser.tabs.length; i++) { |
|
87 let browser = this.window.gBrowser.tabs[i].linkedBrowser; |
|
88 if (browser.__SS_restoreState == TAB_STATE_RESTORING) |
|
89 isRestoring++; |
|
90 else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE) |
|
91 needsRestore++; |
|
92 } |
|
93 |
|
94 return [needsRestore, isRestoring]; |
|
95 } |
|
96 } |
|
97 |
|
98 // ---------- |
|
99 function newWindowWithState(state, callback) { |
|
100 let opts = "chrome,all,dialog=no,height=800,width=800"; |
|
101 let win = window.openDialog(getBrowserURL(), "_blank", opts); |
|
102 |
|
103 registerCleanupFunction(function () win.close()); |
|
104 |
|
105 whenWindowLoaded(win, function onWindowLoaded(aWin) { |
|
106 TabsProgressListener.init(aWin); |
|
107 TabsProgressListener.setCallback(callback); |
|
108 |
|
109 ss.setWindowState(aWin, JSON.stringify(state), true); |
|
110 }); |
|
111 } |