Bug 586211 - Restore hidden tabs after visible ones. r=zpao, a=beta5+
authorDan Witte <dwitte@mozilla.com>
Fri, 27 Aug 2010 08:12:02 -0700
changeset 51576 118b011d4d52c979578021733c10d124e4a4b871
parent 51575 a64bb4bf114d49f49f7d94f0e70a70e5db9de263
child 51577 e3fe95511fc288d39bd7fc93f33eaa6b90421665
push idunknown
push userunknown
push dateunknown
reviewerszpao, beta5
bugs586211
milestone2.0b5pre
Bug 586211 - Restore hidden tabs after visible ones. r=zpao, a=beta5+
browser/components/sessionstore/src/nsSessionStore.js
browser/components/sessionstore/test/browser/browser_480148.js
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -2073,29 +2073,43 @@ SessionStoreService.prototype = {
       browser.userTypedValue = activePageData ? activePageData.url || null : null;
       
       // keep the data around to prevent dataloss in case
       // a tab gets closed before it's been properly restored
       browser.__SS_data = tabData;
     }
     
     if (aTabs.length > 0) {
+      // Load hidden tabs last, by pushing them to the end of the list
+      let unhiddenTabs = aTabs.length;
+      for (let t = 0; t < unhiddenTabs; ) {
+        if (aTabs[t].hidden) {
+          aTabs = aTabs.concat(aTabs.splice(t, 1));
+          aTabData = aTabData.concat(aTabData.splice(t, 1));
+          if (aSelectTab > t)
+            --aSelectTab;
+          --unhiddenTabs;
+          continue;
+        }
+        ++t;
+      }
+
       // Determine if we can optimize & load visible tabs first
       let maxVisibleTabs = Math.ceil(tabbrowser.tabContainer.mTabstrip.scrollClientSize /
-                                     aTabs[aTabs.length - 1].clientWidth);
+                                     aTabs[unhiddenTabs - 1].clientWidth);
 
       // make sure we restore visible tabs first, if there are enough
-      if (maxVisibleTabs < aTabs.length && aSelectTab > 1) {
+      if (maxVisibleTabs < unhiddenTabs && aSelectTab > 1) {
         let firstVisibleTab = 0;
-        if (aTabs.length - maxVisibleTabs > aSelectTab) {
+        if (unhiddenTabs - maxVisibleTabs > aSelectTab) {
           // aSelectTab is leftmost since we scroll to it when possible
           firstVisibleTab = aSelectTab - 1;
         } else {
           // aSelectTab is rightmost or no more room to scroll right
-          firstVisibleTab = aTabs.length - maxVisibleTabs;
+          firstVisibleTab = unhiddenTabs - maxVisibleTabs;
         }
         aTabs = aTabs.splice(firstVisibleTab, maxVisibleTabs).concat(aTabs);
         aTabData = aTabData.splice(firstVisibleTab, maxVisibleTabs).concat(aTabData);
         aSelectTab -= firstVisibleTab;
       }
 
       // make sure to restore the selected tab first (if any)
       if (aSelectTab-- && aTabs[aSelectTab]) {
--- a/browser/components/sessionstore/test/browser/browser_480148.js
+++ b/browser/components/sessionstore/test/browser/browser_480148.js
@@ -47,20 +47,26 @@ function browserWindowsCount() {
 function test() {
   /** Test for Bug 484108 **/
   is(browserWindowsCount(), 1, "Only one browser window should be open initially");
 
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
   waitForExplicitFinish();
 
   // builds the tests state based on a few parameters
-  function buildTestState(num, selected) {
+  function buildTestState(num, selected, hidden) {
     let state = { windows: [ { "tabs": [], "selected": selected } ] };
-    while (num--)
+    while (num--) {
       state.windows[0].tabs.push({entries: [{url: "http://example.com/"}]});
+      let i = state.windows[0].tabs.length - 1;
+      if (hidden.length > 0 && i == hidden[0]) {
+        state.windows[0].tabs[i].hidden = true;
+        hidden.splice(0, 1);
+      }
+    }
     return state;
   }
 
   // builds an array of the indexs we expect to see in the order they get loaded
   function buildExpectedOrder(num, selected, shown) {
     // assume selected is 1-based index
     selected--;
     let expected = [selected];
@@ -75,27 +81,27 @@ function test() {
       if (expected.indexOf(i) == -1) {
         expected.push(i);
       }
     }
     return expected;
   }
 
   // the number of tests we're running
-  let numTests = 4;
+  let numTests = 6;
   let completedTests = 0;
 
   let tabMinWidth = parseInt(getComputedStyle(gBrowser.selectedTab, null).minWidth);
 
-  function runTest(testNum, totalTabs, selectedTab, shownTabs, order) {
+  function runTest(testNum, totalTabs, selectedTab, shownTabs, hiddenTabs, order) {
     let test = {
       QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
                                              Ci.nsISupportsWeakReference]),
 
-      state: buildTestState(totalTabs, selectedTab),
+      state: buildTestState(totalTabs, selectedTab, hiddenTabs),
       numTabsToShow: shownTabs,
       expectedOrder: order,
       actualOrder: [],
       windowWidth: null,
       callback: null,
       window: null,
 
       handleSSTabRestoring: function (aEvent) {
@@ -152,15 +158,17 @@ function test() {
         this.window.addEventListener("SSTabRestoring", this, false);
         this.window.addEventListener("load", this, false);
       }
     };
     test.run();
   }
 
   // actually create & run the tests
-  runTest(1, 13, 1, 6,  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
-  runTest(2, 13, 13, 6, [12, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6]);
-  runTest(3, 13, 4, 6,  [3, 4, 5, 6, 7, 8, 0, 1, 2, 9, 10, 11, 12]);
-  runTest(4, 13, 11, 6, [10, 7, 8, 9, 11, 12, 0, 1, 2, 3, 4, 5, 6]);
+  runTest(1, 13, 1,  6, [],         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
+  runTest(2, 13, 13, 6, [],         [12, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6]);
+  runTest(3, 13, 4,  6, [],         [3, 4, 5, 6, 7, 8, 0, 1, 2, 9, 10, 11, 12]);
+  runTest(4, 13, 11, 6, [],         [10, 7, 8, 9, 11, 12, 0, 1, 2, 3, 4, 5, 6]);
+  runTest(5, 13, 13, 6, [0, 4, 9],  [12, 6, 7, 8, 10, 11, 1, 2, 3, 5, 0, 4, 9]);
+  runTest(6, 13, 4,  6, [1, 7, 12], [3, 4, 5, 6, 8, 9, 0, 2, 10, 11, 1, 7, 12]);
 
   // finish() is run by the last test to finish, so no cleanup down here
 }