Bug 45715 - ""Reply to List" [button/(context) menu item]" [r=mkmelin,sr=bienvenu,ui-review=clarkbw]
authorBlake Winton <bwinton@latte.ca>
Fri, 29 May 2009 10:35:37 +0100
changeset 2727 98a7de404c08fb375c20bcee33c9dea633a05a50
parent 2726 1b3663fa364ef57f897cee49cf2d5a675a1158bd
child 2728 178d054e316394f7c009003b51f649c3e566179e
push id2212
push userbugzilla@standard8.plus.com
push dateFri, 29 May 2009 09:36:47 +0000
treeherdercomm-central@98a7de404c08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, bienvenu
bugs45715
Bug 45715 - ""Reply to List" [button/(context) menu item]" [r=mkmelin,sr=bienvenu,ui-review=clarkbw]
mail/base/content/hiddenWindow.js
mail/base/content/mail3PaneWindowCommands.js
mail/base/content/mailContextMenus.js
mail/base/content/mailWidgets.xml
mail/base/content/mailWindowOverlay.js
mail/base/content/mailWindowOverlay.xul
mail/base/content/messageWindow.js
mail/base/content/msgHdrViewOverlay.js
mail/locales/en-US/chrome/messenger/messenger.dtd
mail/locales/en-US/chrome/messenger/msgHdrViewOverlay.dtd
mail/themes/gnomestripe/mail/primaryToolbar.css
mail/themes/pinstripe/mail/primaryToolbar.css
mail/themes/qute/mail/primaryToolbar.css
mailnews/mime/emitters/src/nsMimeHtmlEmitter.cpp
--- a/mail/base/content/hiddenWindow.js
+++ b/mail/base/content/hiddenWindow.js
@@ -48,17 +48,17 @@ function hiddenWindowStartup()
              'menu_Toolbars', 'menu_MessagePaneLayout', 'menu_showMessage', 'menu_FolderViews',
              'viewSortMenu', 'groupBySort', 'viewMessageViewMenu', 'mailviewCharsetMenu',
              'viewMessagesMenu', 'menu_expandAllThreads', 'collapseAllThreads',
              'viewheadersmenu', 'viewBodyMenu', 'viewAttachmentsInlineMenuitem',
              'viewFullZoomMenu',
              'goNextMenu', 'menu_nextMsg', 'menu_nextUnreadMsg', 'menu_nextUnreadThread',
              'goPreviousMenu', 'menu_prevMsg', 'menu_prevUnreadMsg', 'menu_goForward', 'menu_goBack',
              'goStartPage', 'newMsgCmd', 'replyMainMenu', 'replySenderMainMenu', 'replyNewsgroupMainMenu',
-             'menu_replyToAll', 'menu_forwardMsg', 'forwardAsMenu', 'menu_editMsgAsNew', 'openMessageWindowMenuitem',
+             'menu_replyToAll', 'menu_replyToList', 'menu_forwardMsg', 'forwardAsMenu', 'menu_editMsgAsNew', 'openMessageWindowMenuitem',
              'moveMenu', 'copyMenu', 'moveToFolderAgain', 'tagMenu', 'markMenu',
              'markReadMenuItem', 'menu_markThreadAsRead', 'menu_markReadByDate', 'menu_markAllRead',
              'markFlaggedMenuItem', 'menu_markAsJunk', 'menu_markAsNotJunk', 'createFilter',
              'killThread', 'killSubthread', 'watchThread', 'applyFilters', 'runJunkControls', 'deleteJunk', 'menu_import',
              'searchMailCmd', 'searchAddressesCmd', 'filtersCmd',
              'cmd_close', 'minimizeWindow', 'zoomWindow'];
   var id;
   var element;
--- a/mail/base/content/mail3PaneWindowCommands.js
+++ b/mail/base/content/mail3PaneWindowCommands.js
@@ -143,16 +143,18 @@ var DefaultController =
       case "cmd_archive":
       case "button_archive":
       case "cmd_reply":
       case "button_reply":
       case "cmd_replySender":
       case "cmd_replyGroup":
       case "cmd_replyall":
       case "button_replyall":
+      case "cmd_replylist":
+      case "button_replylist":
       case "cmd_forward":
       case "button_forward":
       case "cmd_forwardInline":
       case "cmd_forwardAttachment":
       case "cmd_editAsNew":
       case "cmd_createFilterFromMenu":
       case "cmd_delete":
       case "cmd_deleteFolder":
@@ -295,16 +297,18 @@ var DefaultController =
         if (GetNumSelectedMessages() > 1)
           return false;   // else fall thru
       case "cmd_reply":
       case "button_reply":
       case "cmd_replySender":
       case "cmd_replyGroup":
       case "cmd_replyall":
       case "button_replyall":
+      case "cmd_replylist":
+      case "button_replylist":
       case "cmd_forward":
       case "button_forward":
       case "cmd_forwardInline":
       case "cmd_forwardAttachment":
       case "cmd_editAsNew":
       case "cmd_openMessage":
       case "button_print":
       case "cmd_print":
@@ -526,16 +530,19 @@ var DefaultController =
         MsgReplySender(null);
         break;
       case "cmd_replyGroup":
         MsgReplyGroup(null);
         break;
       case "cmd_replyall":
         MsgReplyToAllMessage(null);
         break;
+      case "cmd_replylist":
+        MsgReplyToListMessage(null);
+        break;
       case "cmd_forward":
         MsgForwardMessage(null);
         break;
       case "cmd_forwardInline":
         MsgForwardAsInline(null);
         break;
       case "cmd_forwardAttachment":
         MsgForwardAsAttachment(null);
--- a/mail/base/content/mailContextMenus.js
+++ b/mail/base/content/mailContextMenus.js
@@ -190,16 +190,17 @@ function fillMailContextMenu(event)
     ShowMenuItem(aID, single && !hideMailItems && hide);
     EnableMenuItem(aID, single);
   }
 
   setSingleSelection("mailContext-replySender");
   setSingleSelection("mailContext-editAsNew");
   setSingleSelection("mailContext-replyNewsgroup", isNewsgroup);
   setSingleSelection("mailContext-replyAll");
+  setSingleSelection("mailContext-replyList");
   setSingleSelection("mailContext-forward");
   ShowMenuItem("mailContext-forwardAsAttachment",
                numSelected > 1 && inThreadPane && !hideMailItems);
 
   setSingleSelection("mailContext-copyMessageUrl", isNewsgroup);
 
   ShowMenuItem("mailContext-sep-open", single);
 
--- a/mail/base/content/mailWidgets.xml
+++ b/mail/base/content/mailWidgets.xml
@@ -2115,24 +2115,75 @@
              these buttons are doing the right thing -->
 
        <xul:button anonid="hdrReplyButton" label="&hdrReplyButton.label;"
                    oncommand="MsgReplyMessage(event);RestoreFocusAfterHdrButton();"
                    observes="button_reply"
                    class="msgHeaderView-button hdrReplyButton"
                    type="menu-button">
          <xul:menupopup anonid="hdrReplyDropdown">
-           <xul:menuitem anonid="hdrReplyAllButton"
+           <xul:menuitem anonid="hdrReplySubButton"
+                         label="&hdrReplyButton.label;"
+                         tooltiptext="&replyButton.tooltip;"
+                         observes="button_reply"/>
+           <xul:menuseparator anonid="hdrReplyAllSubButtonSep"/>
+           <xul:menuitem anonid="hdrReplyAllSubButton"
                          label="&hdrReplyAllButton.label;"
                          tooltiptext="&replyAllButton.tooltip;"
                          observes="button_replyall"
                          oncommand="MsgReplyToAllMessage(event); event.stopPropagation();
                          RestoreFocusAfterHdrButton();"/>
          </xul:menupopup>
        </xul:button>
+       <xul:button anonid="hdrReplyAllButton" label="&hdrReplyAllButton.label;"
+                   oncommand="MsgReplyToAllMessage(event);RestoreFocusAfterHdrButton();"
+                   observes="button_replyall"
+                   class="msgHeaderView-button hdrReplyButton"
+                   type="menu-button"
+                   hidden="true">
+         <xul:menupopup anonid="hdrReplyAllDropdown">
+           <xul:menuitem anonid="hdrReplyAllSubButton"
+                         label="&hdrReplyAllButton.label;"
+                         tooltiptext="&replyAllButton.tooltip;"
+                         observes="button_replyall"/>
+           <xul:menuseparator/>
+           <xul:menuitem anonid="hdrReplySubButton"
+                         label="&hdrReplyButton.label;"
+                         tooltiptext="&replyButton.tooltip;"
+                         observes="button_reply"
+                         oncommand="MsgReplyMessage(event); event.stopPropagation();
+                         RestoreFocusAfterHdrButton();"/>
+         </xul:menupopup>
+       </xul:button>
+       <xul:button anonid="hdrReplyListButton" label="&hdrReplyListButton.label;"
+                   oncommand="MsgReplyToListMessage(event);RestoreFocusAfterHdrButton();"
+                   observes="button_replylist"
+                   class="msgHeaderView-button hdrReplyButton"
+                   type="menu-button"
+                   hidden="true">
+         <xul:menupopup anonid="hdrReplyListDropdown">
+           <xul:menuitem anonid="hdrReplyListSubButton"
+                         label="&hdrReplyListButton.label;"
+                         tooltiptext="&replyListButton.tooltip;"
+                         observes="button_replylist"/>
+           <xul:menuseparator/>
+           <xul:menuitem anonid="hdrReplyAllSubButton"
+                         label="&hdrReplyAllButton.label;"
+                         tooltiptext="&replyAllButton.tooltip;"
+                         observes="button_replyall"
+                         oncommand="MsgReplyToAllMessage(event); event.stopPropagation();
+                         RestoreFocusAfterHdrButton();"/>
+           <xul:menuitem anonid="hdrReplySubButton"
+                         label="&hdrReplyButton.label;"
+                         tooltiptext="&replyButton.tooltip;"
+                         observes="button_reply"
+                         oncommand="MsgReplyMessage(event); event.stopPropagation();
+                         RestoreFocusAfterHdrButton();"/>
+         </xul:menupopup>
+       </xul:button>
        <xul:button anonid="hdrForwardButton" label="&hdrForwardButton.label;"
                    oncommand="MsgForwardMessage(event);RestoreFocusAfterHdrButton();"
                    observes="button_forward" class="msgHeaderView-button hdrForwardButton"/>
        <xul:button anonid="archiveButton" label="&archiveButton.label;"
                    oncommand="MsgArchiveSelectedMessages(event);RestoreFocusAfterHdrButton();"
                    observes="button_archive"
                    class="msgHeaderView-button hdrArchiveButton"/>
        <xul:button anonid="hdrJunkButton" label="&hdrJunkButton.label;"
--- a/mail/base/content/mailWindowOverlay.js
+++ b/mail/base/content/mailWindowOverlay.js
@@ -802,16 +802,109 @@ function InitMessageMark()
 
 function UpdateJunkToolbarButton()
 {
   var junkButtonDeck = document.getElementById("junk-deck");
   if (junkButtonDeck)
     junkButtonDeck.selectedIndex = SelectedMessagesAreJunk() ? 1 : 0;
 }
 
+function UpdateReplyButtons()
+{
+  let msgHdr = messenger.msgHdrFromURI(GetLoadedMessage());
+
+  let myEmail = getIdentityForHeader(msgHdr).email;
+  let recipients = msgHdr.recipients + "," + msgHdr.ccList;
+
+  // If my email address isn't in the to or cc list, then I've been bcc-ed.
+  let imBcced = recipients.indexOf(myEmail) == -1;
+
+  // Now, let's get the number of unique recipients
+  let hdrParser = Components.classes["@mozilla.org/messenger/headerparser;1"]
+                            .getService(Components.interfaces.nsIMsgHeaderParser);
+  let uniqueRecipients = hdrParser.removeDuplicateAddresses(recipients, {});
+  let numAddresses = hdrParser.parseHeadersWithArray(uniqueRecipients, {}, {}, {});
+
+  // If I've been bcc-ed, then add 1 to the number of addresses to compensate.
+  if (imBcced)
+    numAddresses++
+
+  // By default, ReplyAll if there is more than 1 person to reply to.
+  let showReplyAll = numAddresses > 1;
+
+  // And ReplyToList if there is a List-Post header.
+  let showReplyList = currentHeaderData["list-post"];
+
+  // Get the server type.
+  let serverType = null;
+  try
+  {
+    serverType = msgHdr.folder.server.type;
+  }
+  catch (ex)
+  {
+    // This empty catch block needs to be here because msgHdr.folder will
+    // throw an exception when you try to access it on a .eml file.
+  }
+
+  // But, if we're in a news item, we should default to Reply.
+  if (serverType == "nntp")
+  {
+    showReplyAll = false;
+    showReplyList = false;
+  }
+
+  let buttonToShow = "reply";
+  if (showReplyList)
+    buttonToShow = "replyList";
+  else if (showReplyAll)
+    buttonToShow = "replyAll";
+
+  let buttonBox = document.getElementById(gCollapsedHeaderViewMode ?
+    "collapsedButtonBox" : "expandedButtonBox");
+
+  let replyButton = buttonBox.getButton("hdrReplyButton");
+  let replyAllButton = buttonBox.getButton("hdrReplyAllButton");
+  let replyAllSubButton = buttonBox.getButton("hdrReplyAllSubButton");
+  let replyAllSubButtonSep = buttonBox.getButton("hdrReplyAllSubButtonSep");
+  let replyListButton = buttonBox.getButton("hdrReplyListButton");
+
+  replyButton.hidden = (buttonToShow != "reply");
+  replyAllButton.hidden = (buttonToShow != "replyAll");
+  replyListButton.hidden = (buttonToShow != "replyList");
+
+  let replyListMenu = document.getElementById("menu_replyToList");
+  replyListMenu.hidden = !showReplyList;
+
+  let replyListCommand = document.getElementById("cmd_replylist");
+  replyListCommand.disabled = !showReplyList;
+
+  if (serverType == "nntp")
+  {
+    // If it's a news item, show the ReplyAll sub-button and separator.
+    replyAllSubButton.hidden = false;
+    replyAllSubButtonSep.hidden = false;
+  }
+  else if (serverType == "rss")
+  {
+    // otherwise, if it's an rss item, hide all the Reply buttons.
+    replyButton.hidden = true;
+    replyAllButton.hidden = true;
+    replyListButton.hidden = true;
+    replyAllSubButton.hidden = true;
+    replyAllSubButtonSep.hidden = true;
+  }
+  else
+  {
+    // otherwise, hide the ReplyAll sub-buttons.
+    replyAllSubButton.hidden = true;
+    replyAllSubButtonSep.hidden = true;
+  }
+}
+
 function UpdateDeleteToolbarButton()
 {
   var deleteButtonDeck = document.getElementById("delete-deck");
   if (!deleteButtonDeck)
     return;
 
   // Never show "Undelete" in the 3-pane for folders, when delete would
   // apply to the selected folder.
@@ -1092,16 +1185,20 @@ function MsgReplyGroup(event)
   composeMsgByType(Components.interfaces.nsIMsgCompType.ReplyToGroup, event);
 }
 
 function MsgReplyToAllMessage(event)
 {
   composeMsgByType(Components.interfaces.nsIMsgCompType.ReplyAll, event);
 }
 
+function MsgReplyToListMessage(event)
+{
+  composeMsgByType(Components.interfaces.nsIMsgCompType.ReplyToList, event);
+}
 
 // Message Archive function
 
 function BatchMessageMover()
 {
   this._batches = {};
   this._currentKey = null;
 }
--- a/mail/base/content/mailWindowOverlay.xul
+++ b/mail/base/content/mailWindowOverlay.xul
@@ -227,16 +227,17 @@
             commandupdater="true"
             events="create-menu-message"
             oncommandupdate="goUpdateMailMenuItems(this)">
   <command id="cmd_archive" oncommand="goDoCommand('cmd_archive')"/>
   <command id="cmd_reply" oncommand="goDoCommand('cmd_reply')"/>
   <command id="cmd_replySender" oncommand="goDoCommand('cmd_replySender')"/>
   <command id="cmd_replyGroup" oncommand="goDoCommand('cmd_replyGroup')"/>
   <command id="cmd_replyall" oncommand="goDoCommand('cmd_replyall')"/>
+  <command id="cmd_replylist" oncommand="goDoCommand('cmd_replylist')"/>
   <command id="cmd_forward" oncommand="goDoCommand('cmd_forward')"/>
   <command id="cmd_forwardInline" oncommand="goDoCommand('cmd_forwardInline')"/>
   <command id="cmd_forwardAttachment" oncommand="goDoCommand('cmd_forwardAttachment')"/>
   <command id="cmd_editAsNew" oncommand="goDoCommand('cmd_editAsNew')"/>
   <command id="cmd_openMessage" oncommand="goDoCommand('cmd_openMessage')"/>
   <command id="cmd_moveToFolderAgain" oncommand="goDoCommand('cmd_moveToFolderAgain')"/>
   <command id="cmd_createFilterFromMenu" oncommand="goDoCommand('cmd_createFilterFromMenu')"/>
   <command id="cmd_killThread" oncommand="goDoCommand('cmd_killThread')"/>
@@ -246,16 +247,17 @@
 
 <commandset id="mailToolbarItems"
             commandupdater="true"
             events="mail-toolbar"
             oncommandupdate="goUpdateMailMenuItems(this)">
 
   <command id="button_reply"/>
   <command id="button_replyall"/>
+  <command id="button_replylist"/>
   <command id="button_archive"/>
   <command id="button_forward"/>
   <command id="button_delete"/>
   <command id="button_mark"/>
   <command id="cmd_tag"/>
   <command id="button_getNewMessages"/>
   <command id="button_print"/>
   <command id="button_previous"/>
@@ -371,16 +373,17 @@
   <key id="key_previousMsg" key="&prevMsgCmd.key;"                   oncommand="goDoCommand('cmd_previousMsg')"/>
   <key id="key_previousUnreadMsg" key="&prevUnreadMsgCmd.key;"       oncommand="goDoCommand('cmd_previousUnreadMsg')"/>
   <key id="key_archive" key="&archiveMsgCmd.key;"                    oncommand="goDoCommand('cmd_archive')"/>
   <key id="key_goForward" key="&goForwardCmd.commandKey;"            oncommand="goDoCommand('cmd_goForward')"/>
   <key id="key_goBack" key="&goBackCmd.commandKey;"                  oncommand="goDoCommand('cmd_goBack')"/>
   <key id="key_goStartPage" keycode="VK_HOME"                        oncommand="goDoCommand('cmd_goStartPage')" modifiers="alt"/>
   <key id="key_reply" key="&replyMsgCmd.key;"                        oncommand="goDoCommand('cmd_reply')" modifiers="accel"/>
   <key id="key_replyall" key="&replyToAllMsgCmd.key;"                oncommand="goDoCommand('cmd_replyall')" modifiers="accel, shift"/>
+  <key id="key_replylist" key="&replyToListMsgCmd.key;"              oncommand="goDoCommand('cmd_replylist')" modifiers="accel, shift"/>
   <key id="key_forward" key="&forwardMsgCmd.key;"                    oncommand="goDoCommand('cmd_forward')" modifiers="accel"/>
   <key id="key_editAsNew" key="&editMsgAsNewCmd.key;"                oncommand="goDoCommand('cmd_editAsNew')" modifiers="accel"/>
   <key id="key_watchThread" key="&watchThreadMenu.key;"              oncommand="goDoCommand('cmd_watchThread')" />
   <key id="key_killThread" key="&killThreadMenu.key;"                oncommand="goDoCommand('cmd_killThread')" />
   <key id="key_killSubthread" key="&killSubthreadMenu.key;"          oncommand="goDoCommand('cmd_killSubthread')" modifiers="shift" />
   <key id="key_openMessage" key="&openMessageWindowCmd.key;"         oncommand="goDoCommand('cmd_openMessage')" modifiers="accel"/>
 #ifdef XP_MACOSX
   <key id="key_moveToFolderAgain" key="&moveToFolderAgainCmd.key;"   oncommand="goDoCommand('cmd_moveToFolderAgain')" modifiers="alt, accel"/>
@@ -531,16 +534,20 @@
     <menuitem id="mailContext-replyNewsgroup"
               label="&contextReplyNewsgroup.label;"
               accesskey="&contextReplyNewsgroup.accesskey;"
               oncommand="MsgReplyGroup(event);"/>
     <menuitem id="mailContext-replyAll"
               label="&contextReplyAll.label;"
               accesskey="&contextReplyAll.accesskey;"
               oncommand="MsgReplyToAllMessage(event);"/>
+    <menuitem id="mailContext-replyList"
+              label="&contextReplyList.label;"
+              accesskey="&contextReplyList.accesskey;"
+              oncommand="MsgReplyToListMessage(event);"/>
     <menuitem id="mailContext-forward"
               label="&contextForward.label;"
               accesskey="&contextForward.accesskey;"
               oncommand="MsgForwardMessage(event);"/>
     <menuitem id="mailContext-forwardAsAttachment"
               label="&contextForwardAsAttachment.label;"
               accesskey="&contextForwardAsAttachment.accesskey;"
               oncommand="MsgForwardAsAttachment(event);"/>
@@ -1225,62 +1232,66 @@
                     key="key_goStartPage"/>
         </menupopup>
         </menu>
 
         <!-- Message -->
         <menu id="messageMenu" label="&msgMenu.label;" accesskey="&msgMenu.accesskey;">
           <menupopup id="messageMenuPopup" onpopupshowing="InitMessageMenu();">
             <menuitem id="newMsgCmd" label="&newMsgCmd.label;"
-              accesskey="&newMsgCmd.accesskey;"
-              key="key_newMessage2"
-              oncommand="MsgNewMessage(null);"/>
+                      accesskey="&newMsgCmd.accesskey;"
+                      key="key_newMessage2"
+                      oncommand="MsgNewMessage(null);"/>
             <menuitem id="archiveMainMenu" label="&archiveMsgCmd.label;"
-              accesskey="&archiveMsgCmd.accesskey;"
-              key="key_archive"
-              command="cmd_archive"/>
+                      accesskey="&archiveMsgCmd.accesskey;"
+                      key="key_archive"
+                      command="cmd_archive"/>
             <menuitem id="replyMainMenu" label="&replyMsgCmd.label;"
-              accesskey="&replyMsgCmd.accesskey;"
-              key="key_reply"
-              command="cmd_reply"/>
+                      accesskey="&replyMsgCmd.accesskey;"
+                      key="key_reply"
+                      command="cmd_reply"/>
             <menuitem id="replySenderMainMenu" label="&replySenderCmd.label;"
-              accesskey="&replySenderCmd.accesskey;"
-              command="cmd_replySender"/>
+                      accesskey="&replySenderCmd.accesskey;"
+                      command="cmd_replySender"/>
             <menuitem id="replyNewsgroupMainMenu" label="&replyNewsgroupCmd.label;"
-              accesskey="&replyNewsgroupCmd.accesskey;"
-              key="key_reply"
-              command="cmd_replyGroup"/>
+                      accesskey="&replyNewsgroupCmd.accesskey;"
+                      key="key_reply"
+                      command="cmd_replyGroup"/>
             <menuitem id="menu_replyToAll" label="&replyToAllMsgCmd.label;"
-              accesskey="&replyToAllMsgCmd.accesskey;"
-              key="key_replyall"
-              command="cmd_replyall"/>
+                      accesskey="&replyToAllMsgCmd.accesskey;"
+                      key="key_replyall"
+                      command="cmd_replyall"/>
+            <menuitem id="menu_replyToList" label="&replyToListMsgCmd.label;"
+                      accesskey="&replyToListMsgCmd.accesskey;"
+                      key="key_replylist"
+                      command="cmd_replylist"/>
             <menuitem id="menu_forwardMsg" label="&forwardMsgCmd.label;"
-              accesskey="&forwardMsgCmd.accesskey;"
-              key="key_forward"
-              command="cmd_forward"/>
+                      accesskey="&forwardMsgCmd.accesskey;"
+                      key="key_forward"
+                      command="cmd_forward"/>
             <menu id="forwardAsMenu" label="&forwardAsMenu.label;" accesskey="&forwardAsMenu.accesskey;">
               <menupopup id="menu_forwardAsPopup">
                 <menuitem id="menu_forwardAsInline"
                           label="&forwardAsInline.label;"
                           accesskey="&forwardAsInline.accesskey;"
                           command="cmd_forwardInline"/>
                 <menuitem id="menu_forwardAsAttachment"
                           label="&forwardAsAttachmentCmd.label;"
                           accesskey="&forwardAsAttachmentCmd.accesskey;"
                           command="cmd_forwardAttachment"/>
               </menupopup>
             </menu>
             <menuitem id="menu_editMsgAsNew" label="&editMsgAsNewCmd.label;"
-                accesskey="&editMsgAsNewCmd.accesskey;"
-                key="key_editAsNew"
-                command="cmd_editAsNew"/>
+                      accesskey="&editMsgAsNewCmd.accesskey;"
+                      key="key_editAsNew"
+                      command="cmd_editAsNew"/>
             <menuitem id="openMessageWindowMenuitem" label="&openMessageWindowCmd.label;"
-              command="cmd_openMessage"
-              accesskey="&openMessageWindowCmd.accesskey;"
-              key="key_openMessage"/>
+                      command="cmd_openMessage"
+                      accesskey="&openMessageWindowCmd.accesskey;"
+                      key="key_openMessage"/>
             <menu id="openFeedMessage" 
                   label="&openFeedMessage.label;" 
                   accesskey="&openFeedMessage.accesskey;">
               <menupopup id="menu_openFeedMessage">
                 <menuitem id="menu_openFeedWebPageInWindow" 
                           type="radio"
                           name="openFeedGroup" 
                           label="&openFeedWebPageInWindow.label;"
@@ -1492,16 +1503,22 @@
                    observes="button_reply"
                    oncommand="MsgReplyMessage(event)"/>
     <toolbarbutton id="button-replyall"
                    class="toolbarbutton-1"
                    label="&replyAllButton.label;"
                    tooltiptext="&replyAllButton.tooltip;"
                    observes="button_replyall"
                    oncommand="MsgReplyToAllMessage(event)"/>
+    <toolbarbutton id="button-replylist"
+                   class="toolbarbutton-1"
+                   label="&replyListButton.label;"
+                   tooltiptext="&replyListButton.tooltip;"
+                   observes="button_replylist"
+                   oncommand="MsgReplyToListMessage(event)"/>
     <toolbarbutton id="button-forward"
                    class="toolbarbutton-1"
                    label="&forwardButton.label;"
                    tooltiptext="&forwardButton.tooltip;"
                    observes="button_forward"
                    oncommand="MsgForwardMessage(event)"/>
     <toolbarbutton id="button-file"
                    type="menu"
@@ -1698,19 +1715,19 @@
   -->
   <toolbar id="mail-bar2" class="toolbar-primary chromeclass-toolbar"
            toolbarname="&showMessengerToolbarCmd.label;"
            accesskey="&showMessengerToolbarCmd.accesskey;"
            fullscreentoolbar="true" mode="full"
            customizable="true"
            context="toolbar-context-menu"
 #ifdef XP_MACOSX
-           defaultset="button-getmsg,button-newmsg,button-address,spacer,button-reply,button-replyall,button-forward,spacer,button-tag,button-delete,button-junk,button-print,spacer,button-goback,button-goforward,spring,search-container,throbber-box">
+           defaultset="button-getmsg,button-newmsg,button-address,spacer,button-reply,button-replyall,button-replylist,button-forward,spacer,button-tag,button-delete,button-junk,button-print,spacer,button-goback,button-goforward,spring,search-container,throbber-box">
 #else
-           defaultset="button-getmsg,button-newmsg,button-address,separator,button-reply,button-replyall,button-forward,separator,button-tag,button-delete,button-junk,button-print,separator,button-goback,button-goforward,spring,search-container">
+           defaultset="button-getmsg,button-newmsg,button-address,separator,button-reply,button-replyall,button-replylist,button-forward,separator,button-tag,button-delete,button-junk,button-print,separator,button-goback,button-goforward,spring,search-container">
 #endif
   </toolbar>
   <toolbarset id="customToolbars" context="toolbar-context-menu"/>
 </toolbox>
 
 <!-- The msgNotificationBar appears on top of the message and displays
      information like: junk, contains remote images, or is a suspected phishing
      URL.
--- a/mail/base/content/messageWindow.js
+++ b/mail/base/content/messageWindow.js
@@ -173,16 +173,19 @@ nsMsgDBViewCommandUpdater.prototype =
     setTitleFromFolder(aFolder, aSubject);
     ClearPendingReadTimer(); // we are loading / selecting a new message so kill the mark as read timer for the currently viewed message
     gCurrentMessageUri = gDBView.URIForFirstSelectedMessage;
     UpdateStandAloneMessageCounts();
     goUpdateCommand("button_delete");
     goUpdateCommand("button_junk");
     goUpdateCommand("button_goBack");
     goUpdateCommand("button_goForward");
+    goUpdateCommand("button_reply");
+    goUpdateCommand("button_replyall");
+    goUpdateCommand("button_replylist");
   },
 
   updateNextMessageAfterDelete : function()
   {
     SetNextMessageAfterDelete();
   },
 
   summarizeSelection : function() {},
@@ -773,16 +776,18 @@ var MessageWindowController =
         return !(gDBView.keyForFirstSelectedMessage == nsMsgKey_None);
 
       case "cmd_reply":
       case "button_reply":
       case "cmd_replySender":
       case "cmd_replyGroup":
       case "cmd_replyall":
       case "button_replyall":
+      case "cmd_replylist":
+      case "button_replylist":
       case "cmd_archive":
       case "button_archive":
       case "cmd_forward":
       case "button_forward":
       case "cmd_forwardInline":
       case "cmd_forwardAttachment":
       case "cmd_editAsNew":
       case "cmd_getNextNMessages":
@@ -844,16 +849,18 @@ var MessageWindowController =
                             true));
       case "cmd_archive":
       case "cmd_reply":
       case "button_reply":
       case "cmd_replySender":
       case "cmd_replyGroup":
       case "cmd_replyall":
       case "button_replyall":
+      case "cmd_replylist":
+      case "button_replylist":
       case "cmd_forward":
       case "button_forward":
       case "cmd_forwardInline":
       case "cmd_forwardAttachment":
       case "cmd_editAsNew":
       case "cmd_print":
       case "cmd_printpreview":
       case "button_print":
@@ -969,16 +976,19 @@ var MessageWindowController =
         MsgReplySender(null);
         break;
       case "cmd_replyGroup":
         MsgReplyGroup(null);
         break;
       case "cmd_replyall":
         MsgReplyToAllMessage(null);
         break;
+      case "cmd_replylist":
+        MsgReplyToListMessage(null);
+        break;
       case "cmd_forward":
         MsgForwardMessage(null);
         break;
       case "cmd_forwardInline":
         MsgForwardAsInline(null);
         break;
       case "cmd_forwardAttachment":
         MsgForwardAsAttachment(null);
--- a/mail/base/content/msgHdrViewOverlay.js
+++ b/mail/base/content/msgHdrViewOverlay.js
@@ -410,16 +410,17 @@ var messageHeaderSink = {
       ClearHeaderView(gCollapsedHeaderView);
       ClearHeaderView(gExpandedHeaderView);
 
       EnsureSubjectValue(); // make sure there is a subject even if it's empty so we'll show the subject and the twisty
 
       UpdateMessageHeaders();
       ShowEditMessageBox();
       UpdateJunkButton();
+      UpdateReplyButtons();
 
       for (index in gMessageListeners)
         gMessageListeners[index].onEndHeaders();
     },
 
     processHeaders: function(headerNameEnumerator, headerValueEnumerator, dontCollectAddress)
     {
       this.onStartHeaders();
@@ -450,16 +451,18 @@ var messageHeaderSink = {
           else if (lowerCaseHeaderName == "cc")
             this.mDummyMsgHeader.ccList = header.headerValue;
           else if (lowerCaseHeaderName == "subject")
             this.mDummyMsgHeader.subject = header.headerValue;
           else if (lowerCaseHeaderName == "reply-to")
             this.mDummyMsgHeader.replyTo = header.headerValue;
           else if (lowerCaseHeaderName == "message-id")
             this.mDummyMsgHeader.messageId = header.headerValue;
+          else if (lowerCaseHeaderName == "list-post")
+            this.mDummyMsgHeader.listPost = header.headerValue;
 
         }
         // according to RFC 2822, certain headers
         // can occur "unlimited" times
         if (lowerCaseHeaderName in currentHeaderData)
         {
           // sometimes, you can have multiple To or Cc lines....
           // in this case, we want to append these headers into one.
@@ -781,16 +784,17 @@ function updateHeaderViews()
     showHeaderView(gCollapsedHeaderView);
   else
   {
     if (gMinNumberOfHeaders)
       EnsureMinimumNumberOfHeaders(gExpandedHeaderView);
     showHeaderView(gExpandedHeaderView);
   }
   UpdateJunkButton();
+  UpdateReplyButtons();
   displayAttachmentsForExpandedView();
 }
 
 function ToggleHeaderView ()
 {
   gCollapsedHeaderViewMode = !gCollapsedHeaderViewMode;
   // Work around a xul deck bug where the height of the deck is determined by the tallest panel in the deck
   // even if that panel is not selected...
@@ -1991,13 +1995,14 @@ nsDummyMsgHeader.prototype =
   getStringProperty : function(property) {return this.mProperties[property];},
   setStringProperty : function(property, val) {this.mProperties[property] = val;},
   markHasAttachments : function(hasAttachments) {},
   messageSize : 0,
   recipients : null,
   from : null,
   subject : null,
   ccList : null,
+  listPost : null,
   messageId : null,
   accountKey : "",
   folder : null
 };
 
--- a/mail/locales/en-US/chrome/messenger/messenger.dtd
+++ b/mail/locales/en-US/chrome/messenger/messenger.dtd
@@ -327,16 +327,19 @@ you can use these alternative items. Oth
 <!ENTITY replyMsgCmd.key  "r">
 <!ENTITY replySenderCmd.label "Reply to Sender Only">
 <!ENTITY replySenderCmd.accesskey "R">
 <!ENTITY replyNewsgroupCmd.label "Reply to Newsgroup">
 <!ENTITY replyNewsgroupCmd.accesskey  "y">
 <!ENTITY replyToAllMsgCmd.label "Reply to All">
 <!ENTITY replyToAllMsgCmd.accesskey  "p">
 <!ENTITY replyToAllMsgCmd.key  "r">
+<!ENTITY replyToListMsgCmd.label "Reply to List">
+<!ENTITY replyToListMsgCmd.accesskey  "L">
+<!ENTITY replyToListMsgCmd.key  "l">
 <!ENTITY forwardMsgCmd.label "Forward">
 <!ENTITY forwardMsgCmd.accesskey "F">
 <!ENTITY forwardMsgCmd.key  "l">
 <!ENTITY forwardAsMenu.label "Forward As">
 <!ENTITY forwardAsMenu.accesskey "w">
 <!ENTITY forwardAsInline.label "Inline">
 <!ENTITY forwardAsInline.accesskey "I">
 <!ENTITY forwardAsAttachmentCmd.label "Attachment">
@@ -456,16 +459,17 @@ you can use these alternative items. Oth
         which is placed under the Edit menu on Unix systems -->
 <!ENTITY accountManagerCmdUnix.accesskey "A">
 
 <!-- Mail Toolbar -->
 <!ENTITY getMsgButton.label "Get Mail">
 <!ENTITY newMsgButton.label "Write">
 <!ENTITY replyButton.label "Reply">
 <!ENTITY replyAllButton.label "Reply All">
+<!ENTITY replyListButton.label "Reply to List">
 <!ENTITY forwardButton.label "Forward">
 <!ENTITY fileButton.label "File">
 <!ENTITY nextButton.label "Next">
 <!ENTITY previousButton.label "Previous">
 <!ENTITY backButton1.label "Back">
 <!ENTITY goForwardButton1.label "Forward">
 <!ENTITY deleteButton.label "Delete">
 <!ENTITY undeleteButton.label "Undelete">
@@ -487,16 +491,17 @@ you can use these alternative items. Oth
 <!ENTITY advancedButton.tooltip "Advanced message search">
 <!ENTITY getMsgButton.tooltip "Get new messages">
 <!ENTITY getAllNewMsgCmd.label "Get All New Messages">
 <!ENTITY getAllNewMsgCmd.accesskey "G">
 <!ENTITY getAllNewMsgCmd.key "t">
 <!ENTITY newMsgButton.tooltip "Create a new message">
 <!ENTITY replyButton.tooltip "Reply to the message">
 <!ENTITY replyAllButton.tooltip "Reply to sender and all recipients">
+<!ENTITY replyListButton.tooltip "Reply to mailing list">
 <!ENTITY forwardButton.tooltip "Forward selected message">
 <!ENTITY fileButton.tooltip "File selected message">
 <!ENTITY nextButton.tooltip "Move to the next unread message">
 <!ENTITY previousButton.tooltip "Move to the previous unread message">
 <!ENTITY goForwardButton.tooltip "Go forward one message">
 <!ENTITY goBackButton.tooltip "Go back one message">
 <!ENTITY deleteButton.tooltip "Delete selected message or folder">
 <!ENTITY undeleteButton.tooltip "Undelete selected message">
@@ -649,16 +654,18 @@ you can use these alternative items. Oth
 <!ENTITY contextEditAsNew.label "Edit As New…">
 <!ENTITY contextEditAsNew.accesskey "E">
 <!ENTITY contextReplySender.label "Reply to Sender Only">
 <!ENTITY contextReplySender.accesskey "R">
 <!ENTITY contextReplyNewsgroup.label "Reply to Newsgroup">
 <!ENTITY contextReplyNewsgroup.accesskey "y">
 <!ENTITY contextReplyAll.label "Reply to All">
 <!ENTITY contextReplyAll.accesskey "A">
+<!ENTITY contextReplyList.label "Reply to List">
+<!ENTITY contextReplyList.accesskey "L">
 <!ENTITY contextForward.label "Forward">
 <!ENTITY contextForward.accesskey "F">
 <!ENTITY contextForwardAsAttachment.label "Forward as Attachments">
 <!ENTITY contextForwardAsAttachment.accesskey "o">
 <!ENTITY contextMoveMsgMenu.label "Move To">
 <!ENTITY contextMoveMsgMenu.accesskey "M">
 <!ENTITY contextMoveCopyMsgRecentMenu.label "Recent">
 <!ENTITY contextMoveCopyMsgRecentMenu.accesskey "R">
--- a/mail/locales/en-US/chrome/messenger/msgHdrViewOverlay.dtd
+++ b/mail/locales/en-US/chrome/messenger/msgHdrViewOverlay.dtd
@@ -55,16 +55,17 @@
 <!ENTITY inReplyToField2.label "in-reply-to ">
 <!ENTITY originalWebsite2.label "website ">
 
 <!ENTITY editMessageDescription.label "This is a draft message">
 <!ENTITY editMessageButton.label "Edit…">
 <!ENTITY archiveButton.label "archive">
 <!ENTITY hdrReplyButton.label "reply">
 <!ENTITY hdrReplyAllButton.label "reply all">
+<!ENTITY hdrReplyListButton.label "reply list">
 <!ENTITY hdrForwardButton.label "forward">
 <!ENTITY hdrJunkButton.label "junk">
 <!ENTITY trashButton.tooltiptext "delete">
 
 <!ENTITY otherActionsButton.label "other actions">
 <!ENTITY saveAsMenuItem.label "save as…">
 <!ENTITY saveAsMenuItem.accesskey "S">
 <!ENTITY viewSourceMenuItem.label "view source…">
--- a/mail/themes/gnomestripe/mail/primaryToolbar.css
+++ b/mail/themes/gnomestripe/mail/primaryToolbar.css
@@ -101,17 +101,29 @@
 }
 
 #button-replyall:hover {
   -moz-image-region: rect(24px 120px 48px 96px);
 } 
 
 #button-replyall[disabled] {
   -moz-image-region: rect(48px 120px 72px 96px) !important;
-} 
+}
+
+#button-replylist {
+  -moz-image-region: rect(0px 120px 24px 96px);
+}
+
+#button-replylist:hover {
+  -moz-image-region: rect(24px 120px 48px 96px);
+}
+
+#button-replylist[disabled] {
+  -moz-image-region: rect(48px 120px 72px 96px) !important;
+}
 
 #button-forward {
   -moz-image-region: rect(0px 144px 24px 120px);
 }
 
 #button-forward:hover {
   -moz-image-region: rect(24px 144px 48px 120px);
 } 
@@ -322,16 +334,28 @@ toolbar[iconsize="small"] #button-replya
 toolbar[iconsize="small"] #button-replyall:hover {
   -moz-image-region: rect(16px 80px 32px 64px);
 } 
 
 toolbar[iconsize="small"] #button-replyall[disabled] {
   -moz-image-region: rect(32px 80px 48px 64px) !important;
 } 
 
+toolbar[iconsize="small"] #button-replylist {
+  -moz-image-region: rect(0px 80px 16px 64px);
+}
+
+toolbar[iconsize="small"] #button-replylist:hover {
+  -moz-image-region: rect(16px 80px 32px 64px);
+}
+
+toolbar[iconsize="small"] #button-replylist[disabled] {
+  -moz-image-region: rect(32px 80px 48px 64px) !important;
+}
+
 toolbar[iconsize="small"] #button-forward {
   -moz-image-region: rect(0px 96px 16px 80px);
 }
 
 toolbar[iconsize="small"] #button-forward:hover {
   -moz-image-region: rect(16px 96px 32px 80px);
 } 
 
--- a/mail/themes/pinstripe/mail/primaryToolbar.css
+++ b/mail/themes/pinstripe/mail/primaryToolbar.css
@@ -134,16 +134,28 @@ toolbar[mode="text"] .toolbarbutton-menu
 #button-replyall:hover:active {
   -moz-image-region: rect(32px 160px 64px 128px);
 } 
 
 #button-replyall[disabled] {
   -moz-image-region: rect(64px 160px 96px 128px) !important;
 } 
 
+#button-replylist {
+  -moz-image-region: rect(0px 160px 32px 128px);
+}
+
+#button-replylist:hover:active {
+  -moz-image-region: rect(32px 160px 64px 128px);
+}
+
+#button-replylist[disabled] {
+  -moz-image-region: rect(64px 160px 96px 128px) !important;
+}
+
 #button-forward {
   -moz-image-region: rect(0px 192px 32px 160px);
 }
 
 #button-forward:hover:active {
   -moz-image-region: rect(32px 192px 64px 160px);
 } 
 
@@ -358,19 +370,31 @@ toolbar[iconsize="small"] #button-reply[
 } 
 
 toolbar[iconsize="small"] #button-replyall {
   -moz-image-region: rect(0px 120px 24px 96px);
 }
 
 toolbar[iconsize="small"] #button-replyall:hover:active {
   -moz-image-region: rect(24px 120px 48px 96px);
+}
+
+toolbar[iconsize="small"] #button-replyall[disabled] {
+  -moz-image-region: rect(48px 120px 72px 96px) !important;
+}
+
+toolbar[iconsize="small"] #button-replylist {
+  -moz-image-region: rect(0px 120px 24px 96px);
+}
+
+toolbar[iconsize="small"] #button-replylist:hover:active {
+  -moz-image-region: rect(24px 120px 48px 96px);
 } 
 
-toolbar[iconsize="small"] #button-replyall[disabled] {
+toolbar[iconsize="small"] #button-replylist[disabled] {
   -moz-image-region: rect(48px 120px 72px 96px) !important;
 } 
 
 toolbar[iconsize="small"] #button-forward {
   -moz-image-region: rect(0px 144px 24px 120px);
 }
 
 toolbar[iconsize="small"] #button-forward:hover:active {
--- a/mail/themes/qute/mail/primaryToolbar.css
+++ b/mail/themes/qute/mail/primaryToolbar.css
@@ -107,16 +107,28 @@
 #button-replyall:hover {
   -moz-image-region: rect(24px 120px 48px 96px);
 } 
 
 #button-replyall[disabled] {
   -moz-image-region: rect(48px 120px 72px 96px) !important;
 } 
 
+#button-replylist {
+  -moz-image-region: rect(0px 120px 24px 96px);
+}
+
+#button-replylist:hover {
+  -moz-image-region: rect(24px 120px 48px 96px);
+}
+
+#button-replylist[disabled] {
+  -moz-image-region: rect(48px 120px 72px 96px) !important;
+}
+
 #button-forward {
   -moz-image-region: rect(0px 144px 24px 120px);
 }
 
 #button-forward:hover {
   -moz-image-region: rect(24px 144px 48px 120px);
 } 
 
@@ -330,16 +342,28 @@ toolbar[iconsize="small"] #button-replya
 toolbar[iconsize="small"] #button-replyall:hover {
   -moz-image-region: rect(16px 80px 32px 64px);
 } 
 
 toolbar[iconsize="small"] #button-replyall[disabled] {
   -moz-image-region: rect(32px 80px 48px 64px) !important;
 } 
 
+toolbar[iconsize="small"] #button-replylist {
+  -moz-image-region: rect(0px 80px 16px 64px);
+}
+
+toolbar[iconsize="small"] #button-replylist:hover {
+  -moz-image-region: rect(16px 80px 32px 64px);
+}
+
+toolbar[iconsize="small"] #button-replylist[disabled] {
+  -moz-image-region: rect(32px 80px 48px 64px) !important;
+}
+
 toolbar[iconsize="small"] #button-forward {
   -moz-image-region: rect(0px 96px 16px 80px);
 }
 
 toolbar[iconsize="small"] #button-forward:hover {
   -moz-image-region: rect(16px 96px 32px 80px);
 } 
 
--- a/mailnews/mime/emitters/src/nsMimeHtmlEmitter.cpp
+++ b/mailnews/mime/emitters/src/nsMimeHtmlEmitter.cpp
@@ -236,16 +236,17 @@ nsresult nsMimeHtmlDisplayEmitter::Broad
           PL_strcasecmp("bcc", headerInfo->name) && PL_strcasecmp("followup-to", headerInfo->name) &&
           PL_strcasecmp("reply-to", headerInfo->name) && PL_strcasecmp("subject", headerInfo->name) &&
           PL_strcasecmp("organization", headerInfo->name) && PL_strcasecmp("user-agent", headerInfo->name) &&
           PL_strcasecmp("content-base", headerInfo->name) && PL_strcasecmp("sender", headerInfo->name) &&
           PL_strcasecmp("date", headerInfo->name) && PL_strcasecmp("x-mailer", headerInfo->name) &&
           PL_strcasecmp("content-type", headerInfo->name) && PL_strcasecmp("message-id", headerInfo->name) &&
           PL_strcasecmp("x-newsreader", headerInfo->name) && PL_strcasecmp("x-mimeole", headerInfo->name) &&
           PL_strcasecmp("references", headerInfo->name) && PL_strcasecmp("in-reply-to", headerInfo->name) &&
+          PL_strcasecmp("list-post", headerInfo->name) &&
           // make headerStr lower case because IndexOf is case-sensitive
          (!extraExpandedHeadersArray.Length() || (ToLowerCase(headerStr),
             extraExpandedHeadersArray.IndexOf(headerStr) ==
             extraExpandedHeadersArray.NoIndex)))
             continue;
     }
 
     if (!PL_strcasecmp("Date", headerInfo->name))