Bug 531534 - 'Close message window on delete' does not work when messages are opened in tabs; r=asuth ui-r=clarkbw
authorJim <squibblyflabbetydoo@gmail.com>
Fri, 14 Jan 2011 20:52:02 +0000
changeset 6958 95805deaae99505aad06c9191f1d42c4c02fb5f7
parent 6957 ebb269ce8610a07f183f7f9cc30449fe486a695a
child 6959 d3121c483250becfb0d69689b527179867fe36aa
push idunknown
push userunknown
push dateunknown
reviewersasuth, clarkbw
bugs531534
Bug 531534 - 'Close message window on delete' does not work when messages are opened in tabs; r=asuth ui-r=clarkbw
mail/base/content/folderDisplay.js
mail/base/content/messageDisplay.js
mail/base/content/messageWindow.js
mail/components/preferences/advanced.xul
mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
mail/test/mozmill/folder-display/test-close-window-on-delete.js
--- a/mail/base/content/folderDisplay.js
+++ b/mail/base/content/folderDisplay.js
@@ -1147,16 +1147,19 @@ FolderDisplayWidget.prototype = {
    * our message selection. We might know it's coming; if we do then
    * this._nextViewIndexAfterDelete should know what view index to select next.
    * For the imap mark-as-deleted we won't know beforehand.
    */
   onMessagesRemoved: function FolderDisplayWidget_onMessagesRemoved() {
     FolderDisplayListenerManager._fireListeners("onMessagesRemoved",
                                                 [this]);
 
+    if (this.messageDisplay.onMessagesRemoved())
+      return;
+
     // - we saw this coming
     let rowCount = this.view.dbView.rowCount;
     if (!this._massMoveActive && (this._nextViewIndexAfterDelete != null)) {
       // adjust the index if it is after the last row...
       // (this can happen if the "mail.delete_matches_sort_order" pref is not
       //  set and the message is the last message in the view.)
       if (this._nextViewIndexAfterDelete >= rowCount)
         this._nextViewIndexAfterDelete = rowCount - 1;
--- a/mail/base/content/messageDisplay.js
+++ b/mail/base/content/messageDisplay.js
@@ -262,16 +262,27 @@ MessageDisplayWidget.prototype = {
       //  take care of.
       return false;
     }
     // Else defer to showSummary to work it out based on thread selection.
     return this._showSummary();
   },
 
   /**
+   * FolderDisplayWidget will alert us when a message has been removed so that
+   * we can decide whether we want to handle it here, e.g. by closing the
+   * window/tab.
+   *
+   * @return true if the MessageDisplayWidget handled this event and the
+   *         FolderDisplayWidget should stop processing
+   */
+  onMessagesRemoved: function MessageDisplayWidget_onMessagesRemoved() {
+  },
+
+  /**
    * If we are already summarized and we get a new request to summarize, require
    *  that the selection has been stable for at least this many milliseconds
    *  before resummarizing.
    * Unit tests know about this variable and poke at it, so don't change the name
    *  without making sure you update the unit tests.  (Not that you would commit
    *  code without first running all tests yourself...)
    * @private
    */
@@ -536,16 +547,24 @@ MessageTabDisplayWidget.prototype = {
         return true;
 
       // No summaries in a message tab
       this.singleMessageDisplay = true;
       return false;
     }
   },
 
+  onMessagesRemoved: function MessageTabDisplayWidget_onMessagesRemoved() {
+    if (this.folderDisplay.treeSelection.count == 0 &&
+        pref.getBoolPref("mail.close_message_window.on_delete")) {
+      document.getElementById("tabmail").closeTab(this.folderDisplay._tabInfo);
+      return true;
+    }
+  },
+
   /**
    * A message tab should never ever be blank.  Close the tab if we become
    *  blank.
    */
   clearDisplay: function MessageTabDisplayWidget_clearDisplay() {
     if (!this.closing) {
       this.closing = true;
       document.getElementById('tabmail').closeTab(this.folderDisplay._tabInfo);
--- a/mail/base/content/messageWindow.js
+++ b/mail/base/content/messageWindow.js
@@ -167,29 +167,16 @@ StandaloneFolderDisplayWidget.prototype 
   _getDefaultColumnsForCurrentFolder: function () { return {}; },
   _persistColumnStates: function () {},
   _saveColumnStates: function () {},
   _restoreColumnStates: function() {},
 
   onMessageCountsChanged:
       function StandaloneFolderDisplayWidget_onMessageCountsChaned() {
     UpdateStatusMessageCounts();
-  },
-
-  onMessagesRemoved: function StandaloneFolderDisplayWidget_onMessagesRemoved() {
-    // Close the stand alone window if there's nothing selected (i.e. the
-    // message that was displayed is now deleted) and the pref to close window
-    // on delete is set
-    if (this.treeSelection.count == 0 &&
-        pref.getBoolPref("mail.close_message_window.on_delete")) {
-      window.close();
-    }
-    else {
-      this.__proto__.__proto__.onMessagesRemoved.call(this);
-    }
   }
 };
 
 /**
  * Display widget abstraction for a standalone message display.  Right now
  *  I think this means the standalone message window, and not the 'message in a
  *  tab' thing, which is really just a perverted configuration of the 3-pane
  *  format.
@@ -300,16 +287,25 @@ StandaloneMessageDisplayWidget.prototype
     // at all.
     if (!this.aboutToLoadMessage &&
         this.folderDisplay.view.dbView.rowCount == 0) {
       window.close();
       return true;
     }
     return false;
   },
+
+  onMessagesRemoved:
+      function StandaloneMessageDisplayWidget_onMessagesRemoved() {
+    if (this.folderDisplay.treeSelection.count == 0 &&
+        pref.getBoolPref("mail.close_message_window.on_delete")) {
+      window.close();
+      return true;
+    }
+  },
 };
 
 var messagepaneObserver = {
 
   canHandleMultipleItems: false,
 
   onDrop: function (aEvent, aData, aDragSession)
   {
--- a/mail/components/preferences/advanced.xul
+++ b/mail/components/preferences/advanced.xul
@@ -256,19 +256,19 @@
                   <radio id="newWindow" value="0" label="&reuseExpRadio0.label;"
                          accesskey="&reuseExpRadio0.accesskey;"/>
                   <radio id="existingWindow" value="1"
                          label="&reuseExpRadio1.label;"
                          accesskey="&reuseExpRadio1.accesskey;"/>
                 </radiogroup>
               </hbox>
               <hbox>
-                <checkbox id="closeMsgWindowOnDelete"
-                          label="&closeMsgWindowOnMoveOrDelete.label;"
-                          accesskey="&closeMsgWindowOnDelete.accesskey;"
+                <checkbox id="closeMsgOnMoveOrDelete"
+                          label="&closeMsgOnMoveOrDelete.label;"
+                          accesskey="&closeMsgOnMoveOrDelete.accesskey;"
                           preference="mail.close_message_window.on_delete"/>
               </hbox>
             </vbox>
 
           </groupbox>
 
           <groupbox>
             <caption label="&display.caption;"/>
--- a/mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
+++ b/mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
@@ -40,18 +40,18 @@
 <!ENTITY secondsLabel.label            "seconds">
 <!ENTITY openMsgIn.label               "Open messages in:">
 <!ENTITY openMsgInNewTab.label         "A new tab">
 <!ENTITY openMsgInNewTab.accesskey     "t">
 <!ENTITY reuseExpRadio0.label          "A new message window">
 <!ENTITY reuseExpRadio0.accesskey      "n">
 <!ENTITY reuseExpRadio1.label          "An existing message window">
 <!ENTITY reuseExpRadio1.accesskey      "e">
-<!ENTITY closeMsgWindowOnMoveOrDelete.label  "Close message window on move or delete">
-<!ENTITY closeMsgWindowOnDelete.accesskey "C">
+<!ENTITY closeMsgOnMoveOrDelete.label  "Close message window/tab on move or delete">
+<!ENTITY closeMsgOnMoveOrDelete.accesskey "C">
 
 <!-- Update -->
 <!ENTITY autoCheck.label                "Automatically check for updates to:">
 <!ENTITY enableAppUpdate.label          "&brandShortName;">
 <!ENTITY enableAppUpdate.accesskey      "h">
 <!ENTITY enableAddonsUpdate.label       "Installed Add-ons">
 <!ENTITY enableAddonsUpdate.accesskey   "A">
 <!ENTITY whenUpdatesFound.label         "When updates to &brandShortName; are found,">
--- a/mail/test/mozmill/folder-display/test-close-window-on-delete.js
+++ b/mail/test/mozmill/folder-display/test-close-window-on-delete.js
@@ -64,17 +64,17 @@ function setupModule(module) {
  */
 function test_close_message_window_on_delete_from_message_window() {
   set_close_message_on_delete(true);
   be_in_folder(folder);
 
   // select the first message
   let firstMessage = select_click_row(0);
   // display it
-  msgc = open_selected_message_in_new_window();
+  let msgc = open_selected_message_in_new_window();
 
   let secondMessage = select_click_row(1);
   let msgc2 = open_selected_message_in_new_window();
 
   let preCount = folder.getTotalMessages(false);
   msgc.window.focus();
   plan_for_window_close(msgc);
   press_delete(msgc);
@@ -96,18 +96,18 @@ function test_close_message_window_on_de
  */
 function test_close_multiple_message_windows_on_delete_from_message_window() {
   set_close_message_on_delete(true);
   be_in_folder(folder);
 
   // select the first message
   let firstMessage = select_click_row(0);
   // display it
-  msgc = open_selected_message_in_new_window();
-  msgcA = open_selected_message_in_new_window();
+  let msgc = open_selected_message_in_new_window();
+  let msgcA = open_selected_message_in_new_window();
 
   let secondMessage = select_click_row(1);
   let msgc2 = open_selected_message_in_new_window();
 
   let preCount = folder.getTotalMessages(false);
   msgc.window.focus();
   plan_for_window_close(msgc);
   plan_for_window_close(msgcA);
@@ -132,18 +132,18 @@ function test_close_multiple_message_win
  */
 function test_close_multiple_message_windows_on_delete_from_3pane_window() {
   set_close_message_on_delete(true);
   be_in_folder(folder);
 
   // select the first message
   let firstMessage = select_click_row(0);
   // display it
-  msgc = open_selected_message_in_new_window();
-  msgcA = open_selected_message_in_new_window();
+  let msgc = open_selected_message_in_new_window();
+  let msgcA = open_selected_message_in_new_window();
 
   let secondMessage = select_click_row(1);
   let msgc2 = open_selected_message_in_new_window();
 
   let preCount = folder.getTotalMessages(false);
   mc.window.focus();
   plan_for_window_close(msgc);
   plan_for_window_close(msgcA);
@@ -151,14 +151,158 @@ function test_close_multiple_message_win
   press_delete(mc);
 
   if (folder.getTotalMessages(false) != preCount - 1)
     throw new Error("didn't delete a message before closing window");
   wait_for_window_close(msgc);
   wait_for_window_close(msgcA);
 
   if (msgc2.window.closed)
-    throw new Error("should only have closed the active window");
+    throw new Error("should only have closed the first window");
 
   close_window(msgc2);
 
   reset_close_message_on_delete();
 }
+
+/**
+ * Delete a message and check that the message tab is closed
+ * where appropriate.
+ */
+function test_close_message_tab_on_delete_from_message_tab() {
+  set_close_message_on_delete(true);
+  be_in_folder(folder);
+
+  // select the first message
+  let firstMessage = select_click_row(0);
+  // display it
+  let msgc = open_selected_message_in_new_tab(true);
+
+  let secondMessage = select_click_row(1);
+  let msgc2 = open_selected_message_in_new_tab(true);
+
+  let preCount = folder.getTotalMessages(false);
+  switch_tab(msgc);
+  press_delete();
+
+  if (folder.getTotalMessages(false) != preCount - 1)
+    throw new Error("didn't delete a message before closing tab");
+
+  assert_number_of_tabs_open(2);
+
+  if (msgc2 != mc.tabmail.tabInfo[1])
+    throw new Error("should only have closed the active tab");
+
+  close_tab(msgc2);
+
+  reset_close_message_on_delete();
+}
+
+/**
+ * Delete a message when multiple windows are open to the message, and the
+ * message is deleted from one of them.
+ */
+function test_close_multiple_message_tabs_on_delete_from_message_tab() {
+  set_close_message_on_delete(true);
+  be_in_folder(folder);
+
+  // select the first message
+  let firstMessage = select_click_row(0);
+  // display it
+  let msgc = open_selected_message_in_new_tab(true);
+  let msgcA = open_selected_message_in_new_tab(true);
+
+  let secondMessage = select_click_row(1);
+  let msgc2 = open_selected_message_in_new_tab(true);
+
+  let preCount = folder.getTotalMessages(false);
+  switch_tab(msgc);
+  press_delete();
+
+  if (folder.getTotalMessages(false) != preCount - 1)
+    throw new Error("didn't delete a message before closing tab");
+
+  assert_number_of_tabs_open(2);
+
+  if (msgc2 != mc.tabmail.tabInfo[1])
+    throw new Error("should only have closed the active tab");
+
+  close_tab(msgc2);
+
+  reset_close_message_on_delete();
+}
+
+/**
+ * Delete a message when multiple tabs are open to the message, and the
+ * message is deleted from the 3-pane window.
+ */
+function test_close_multiple_message_tabs_on_delete_from_3pane_window() {
+  set_close_message_on_delete(true);
+  be_in_folder(folder);
+
+  // select the first message
+  let firstMessage = select_click_row(0);
+  // display it
+  let msgc = open_selected_message_in_new_tab(true);
+  let msgcA = open_selected_message_in_new_tab(true);
+
+  let secondMessage = select_click_row(1);
+  let msgc2 = open_selected_message_in_new_tab(true);
+
+  let preCount = folder.getTotalMessages(false);
+  mc.window.focus();
+  select_click_row(0);
+  press_delete(mc);
+
+  if (folder.getTotalMessages(false) != preCount - 1)
+    throw new Error("didn't delete a message before closing window");
+
+  assert_number_of_tabs_open(2);
+
+  if (msgc2 != mc.tabmail.tabInfo[1])
+    throw new Error("should only have closed the active tab");
+
+  close_tab(msgc2);
+
+  reset_close_message_on_delete();
+}
+
+/**
+ * Delete a message when multiple windows and tabs are open to the message, and
+ * the message is deleted from the 3-pane window.
+ */
+function test_close_multiple_windows_tabs_on_delete_from_3pane_window() {
+  set_close_message_on_delete(true);
+  be_in_folder(folder);
+
+  // select the first message
+  let firstMessage = select_click_row(0);
+  // display it
+  let msgc = open_selected_message_in_new_tab(true);
+  let msgcA = open_selected_message_in_new_window();
+
+  let secondMessage = select_click_row(1);
+  let msgc2 = open_selected_message_in_new_tab(true);
+  let msgc2A = open_selected_message_in_new_window();
+
+  let preCount = folder.getTotalMessages(false);
+  mc.window.focus();
+  plan_for_window_close(msgcA);
+  select_click_row(0);
+  press_delete(mc);
+
+  if (folder.getTotalMessages(false) != preCount - 1)
+    throw new Error("didn't delete a message before closing window");
+  wait_for_window_close(msgcA);
+
+  assert_number_of_tabs_open(2);
+
+  if (msgc2 != mc.tabmail.tabInfo[1])
+    throw new Error("should only have closed the active tab");
+
+  if (msgc2A.window.closed)
+    throw new Error("should only have closed the first window");
+
+  close_tab(msgc2);
+  close_window(msgc2A);
+
+  reset_close_message_on_delete();
+}