1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/tabview/test/browser_tabview_bug595601.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,167 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore); 1.8 + 1.9 +const TAB_STATE_NEEDS_RESTORE = 1; 1.10 +const TAB_STATE_RESTORING = 2; 1.11 + 1.12 +let stateBackup = ss.getBrowserState(); 1.13 + 1.14 +let state = {windows:[{tabs:[ 1.15 + // first group 1.16 + {entries:[{url:"http://example.com#1"}],extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#1\",\"groupID\":2}"}}, 1.17 + {entries:[{url:"http://example.com#2"}],extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#2\",\"groupID\":2}"}}, 1.18 + {entries:[{url:"http://example.com#3"}],extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#3\",\"groupID\":2}"}}, 1.19 + {entries:[{url:"http://example.com#4"}],extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#4\",\"groupID\":2}"}}, 1.20 + 1.21 + // second group 1.22 + {entries:[{url:"http://example.com#5"}],hidden:true,extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#5\",\"groupID\":1}"}}, 1.23 + {entries:[{url:"http://example.com#6"}],hidden:true,extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#6\",\"groupID\":1}"}}, 1.24 + {entries:[{url:"http://example.com#7"}],hidden:true,extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#7\",\"groupID\":1}"}}, 1.25 + {entries:[{url:"http://example.com#8"}],hidden:true,extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#8\",\"groupID\":1}"}} 1.26 +],selected:4,extData:{ 1.27 + "tabview-groups":"{\"nextID\":8,\"activeGroupId\":1}","tabview-group":"{\"1\":{\"bounds\":{\"left\":15,\"top\":10,\"width\":415,\"height\":367},\"userSize\":{\"x\":415,\"y\":367},\"title\":\"\",\"id\":1},\"2\":{\"bounds\":{\"left\":286,\"top\":488,\"width\":418,\"height\":313},\"title\":\"\",\"id\":2}}", 1.28 + "tabview-ui":"{\"pageBounds\":{\"left\":0,\"top\":0,\"width\":940,\"height\":1075}}" 1.29 +}}]}; 1.30 + 1.31 +function test() { 1.32 + waitForExplicitFinish(); 1.33 + 1.34 + Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", false); 1.35 + 1.36 + TabsProgressListener.init(); 1.37 + 1.38 + registerCleanupFunction(function () { 1.39 + TabsProgressListener.uninit(); 1.40 + 1.41 + Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs"); 1.42 + 1.43 + gBrowser.selectedTab = gBrowser.tabs[0]; 1.44 + ss.setBrowserState(stateBackup); 1.45 + }); 1.46 + 1.47 + TabView._initFrame(function () { 1.48 + executeSoon(testRestoreWithHiddenTabs); 1.49 + }); 1.50 +} 1.51 + 1.52 +function testRestoreWithHiddenTabs() { 1.53 + TabsProgressListener.setCallback(function (needsRestore, isRestoring) { 1.54 + if (needsRestore <= 4) { 1.55 + TabsProgressListener.unsetCallback(); 1.56 + is(needsRestore, 4, "4/8 tabs restored"); 1.57 + } 1.58 + }); 1.59 + 1.60 + waitForBrowserState(state, 4, function () { 1.61 + is(gBrowser.tabs.length, 8, "there are now eight tabs"); 1.62 + is(gBrowser.visibleTabs.length, 4, "four visible tabs"); 1.63 + 1.64 + let cw = TabView.getContentWindow(); 1.65 + is(cw.GroupItems.groupItems.length, 2, "there are now two groupItems"); 1.66 + 1.67 + testSwitchToInactiveGroup(); 1.68 + }); 1.69 +} 1.70 + 1.71 +function testSwitchToInactiveGroup() { 1.72 + let firstProgress = true; 1.73 + 1.74 + TabsProgressListener.setCallback(function (needsRestore, isRestoring) { 1.75 + if (firstProgress) { 1.76 + firstProgress = false; 1.77 + is(isRestoring, 3, "restoring 3 tabs concurrently"); 1.78 + } else { 1.79 + ok(isRestoring < 4, "restoring max. 3 tabs concurrently"); 1.80 + } 1.81 + 1.82 + if (needsRestore) 1.83 + return; 1.84 + 1.85 + TabsProgressListener.unsetCallback(); 1.86 + 1.87 + is(gBrowser.visibleTabs.length, 4, "four visible tabs"); 1.88 + waitForFocus(finish); 1.89 + }); 1.90 + 1.91 + gBrowser.selectedTab = gBrowser.tabs[4]; 1.92 +} 1.93 + 1.94 +function waitForBrowserState(state, numTabs, callback) { 1.95 + let tabContainer = gBrowser.tabContainer; 1.96 + tabContainer.addEventListener("SSTabRestored", function onRestored() { 1.97 + if (--numTabs <= 0) { 1.98 + tabContainer.removeEventListener("SSTabRestored", onRestored, true); 1.99 + executeSoon(callback); 1.100 + } 1.101 + }, true); 1.102 + 1.103 + ss.setBrowserState(JSON.stringify(state)); 1.104 +} 1.105 + 1.106 +function countTabs() { 1.107 + let needsRestore = 0, isRestoring = 0; 1.108 + let windowsEnum = Services.wm.getEnumerator("navigator:browser"); 1.109 + 1.110 + while (windowsEnum.hasMoreElements()) { 1.111 + let window = windowsEnum.getNext(); 1.112 + if (window.closed) 1.113 + continue; 1.114 + 1.115 + for (let i = 0; i < window.gBrowser.tabs.length; i++) { 1.116 + let browser = window.gBrowser.tabs[i].linkedBrowser; 1.117 + if (browser.__SS_restoreState == TAB_STATE_RESTORING) 1.118 + isRestoring++; 1.119 + else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE) 1.120 + needsRestore++; 1.121 + } 1.122 + } 1.123 + 1.124 + return [needsRestore, isRestoring]; 1.125 +} 1.126 + 1.127 +let TabsProgressListener = { 1.128 + init: function () { 1.129 + gBrowser.addTabsProgressListener(this); 1.130 + }, 1.131 + 1.132 + uninit: function () { 1.133 + this.unsetCallback(); 1.134 + gBrowser.removeTabsProgressListener(this); 1.135 + }, 1.136 + 1.137 + setCallback: function (callback) { 1.138 + this.callback = callback; 1.139 + }, 1.140 + 1.141 + unsetCallback: function () { 1.142 + delete this.callback; 1.143 + }, 1.144 + 1.145 + onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) { 1.146 + let isNetwork = aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK; 1.147 + let isWindow = aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW; 1.148 + 1.149 + if (!(this.callback && isNetwork && isWindow)) 1.150 + return; 1.151 + 1.152 + let self = this; 1.153 + let finalize = function () { 1.154 + if (wasRestoring) 1.155 + delete aBrowser.__wasRestoring; 1.156 + 1.157 + self.callback.apply(null, countTabs()); 1.158 + }; 1.159 + 1.160 + let isRestoring = aBrowser.__SS_restoreState == TAB_STATE_RESTORING; 1.161 + let wasRestoring = !aBrowser.__SS_restoreState && aBrowser.__wasRestoring; 1.162 + let hasStopped = aStateFlags & Ci.nsIWebProgressListener.STATE_STOP; 1.163 + 1.164 + if (isRestoring && !hasStopped) 1.165 + aBrowser.__wasRestoring = true; 1.166 + 1.167 + if (hasStopped && (isRestoring || wasRestoring)) 1.168 + finalize(); 1.169 + } 1.170 +}