Bug 667314 - Don't loop infinitely when closing the selected tab in the Ctrl+Tab panel. r=gavin AURORA_BASE_20110705
authorDão Gottwald <dao@mozilla.com>
Tue, 05 Jul 2011 16:57:32 +0200
changeset 72608 5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0
parent 72607 6c2d53b981778cf99865f2f085cb76bdf9ed8b16
child 72609 be16eb53b9034840b9bdb6d7c6b5ed5a9ec93ff0
child 72788 4a74ff2faa69b09b3aaf1c451e4de142b4a81d2c
push idunknown
push userunknown
push dateunknown
reviewersgavin
bugs667314
milestone7.0a1
Bug 667314 - Don't loop infinitely when closing the selected tab in the Ctrl+Tab panel. r=gavin
browser/base/content/browser-tabPreviews.js
browser/base/content/tabbrowser.xml
browser/base/content/test/browser_ctrlTab.js
--- a/browser/base/content/browser-tabPreviews.js
+++ b/browser/base/content/browser-tabPreviews.js
@@ -210,25 +210,27 @@ var ctrlTab = {
   get canvasWidth () Math.min(tabPreviews.width,
                               Math.ceil(screen.availWidth * .85 / this.tabPreviewCount)),
   get canvasHeight () Math.round(this.canvasWidth * tabPreviews.aspectRatio),
 
   get tabList () {
     if (this._tabList)
       return this._tabList;
 
-    let list = gBrowser.visibleTabs;
-
-    if (this._closing)
-      this.detachTab(this._closing, list);
+    // Using gBrowser.tabs instead of gBrowser.visibleTabs, as the latter
+    // exlcudes closing tabs, breaking the following loop in case the the
+    // selected tab is closing.
+    let list = Array.filter(gBrowser.tabs, function (tab) !tab.hidden);
 
     // Rotate the list until the selected tab is first
     while (!list[0].selected)
       list.push(list.shift());
 
+    list = list.filter(function (tab) !tab.closing);
+
     if (this.recentlyUsedLimit != 0) {
       let recentlyUsedTabs = this._recentlyUsedTabs;
       if (this.recentlyUsedLimit > 0)
         recentlyUsedTabs = this._recentlyUsedTabs.slice(0, this.recentlyUsedLimit);
       for (let i = recentlyUsedTabs.length - 1; i >= 0; i--) {
         list.splice(list.indexOf(recentlyUsedTabs[i]), 1);
         list.unshift(recentlyUsedTabs[i]);
       }
@@ -365,21 +367,20 @@ var ctrlTab = {
   attachTab: function ctrlTab_attachTab(aTab, aPos) {
     if (aPos == 0)
       this._recentlyUsedTabs.unshift(aTab);
     else if (aPos)
       this._recentlyUsedTabs.splice(aPos, 0, aTab);
     else
       this._recentlyUsedTabs.push(aTab);
   },
-  detachTab: function ctrlTab_detachTab(aTab, aTabs) {
-    var tabs = aTabs || this._recentlyUsedTabs;
-    var i = tabs.indexOf(aTab);
+  detachTab: function ctrlTab_detachTab(aTab) {
+    var i = this._recentlyUsedTabs.indexOf(aTab);
     if (i >= 0)
-      tabs.splice(i, 1);
+      this._recentlyUsedTabs.splice(i, 1);
   },
 
   open: function ctrlTab_open() {
     if (this.isOpen)
       return;
 
     allTabs.close();
 
@@ -493,20 +494,18 @@ var ctrlTab = {
   },
 
   removeClosingTabFromUI: function ctrlTab_removeClosingTabFromUI(aTab) {
     if (this.tabCount == 2) {
       this.close();
       return;
     }
 
-    this._closing = aTab;
     this._tabList = null;
     this.updatePreviews();
-    this._closing = null;
 
     if (this.selected.hidden)
       this.advanceFocus(false);
     if (this.selected == this.showAllButton)
       this.advanceFocus(false);
 
     // If the current tab is removed, another tab can steal our focus.
     if (aTab == gBrowser.selectedTab && this.panel.state == "open") {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -91,17 +91,17 @@
       </field>
       <field name="tabs" readonly="true">
         this.tabContainer.childNodes;
       </field>
       <property name="visibleTabs" readonly="true">
         <getter><![CDATA[
           return Array.filter(this.tabs, function(tab) {
             return !tab.hidden && !tab.closing;
-          }, this);
+          });
         ]]></getter>
       </property>
       <field name="mURIFixup" readonly="true">
         Components.classes["@mozilla.org/docshell/urifixup;1"]
                   .getService(Components.interfaces.nsIURIFixup);
       </field>
       <field name="mFaviconService" readonly="true">
         Components.classes["@mozilla.org/browser/favicon-service;1"]
--- a/browser/base/content/test/browser_ctrlTab.js
+++ b/browser/base/content/test/browser_ctrlTab.js
@@ -23,16 +23,26 @@ function test() {
   { // test for bug 445369
     let tabs = gBrowser.tabs.length;
     pressCtrlTab();
     EventUtils.synthesizeKey("w", { ctrlKey: true });
     is(gBrowser.tabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes one tab");
     releaseCtrl();
   }
 
+  { // test for bug 667314
+    let tabs = gBrowser.tabs.length;
+    pressCtrlTab();
+    pressCtrlTab(true);
+    EventUtils.synthesizeKey("w", { ctrlKey: true });
+    is(gBrowser.tabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes the selected tab");
+    releaseCtrl();
+  }
+
+  gBrowser.addTab();
   checkTabs(3);
   ctrlTabTest([2, 1, 0], 9, 1);
 
   gBrowser.addTab();
   checkTabs(4);
 
   { // test for bug 445369
     selectTabs([1, 2, 0]);