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 72334 5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0
parent 72333 6c2d53b981778cf99865f2f085cb76bdf9ed8b16
child 72335 4a74ff2faa69b09b3aaf1c451e4de142b4a81d2c
child 72336 be16eb53b9034840b9bdb6d7c6b5ed5a9ec93ff0
push id20700
push userdgottwald@mozilla.com
push dateTue, 05 Jul 2011 14:58:09 +0000
treeherdermozilla-central@5eb553dd2cea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs667314
milestone7.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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]);