Bug 1489172 - Backed out changeset c7cda013b0b4 for making the filter editor unusable. a=jorgk
authorJorg K <jorgk@jorgk.com>
Sat, 24 Nov 2018 21:47:13 +0100
changeset 33775 57b3ea524f1df2ba4ed65b55a17413fbec194d07
parent 33774 dfe843fc864c5d24b51e071b8ecedb6f24b68c76
child 33776 e43bbffbc0c32c80a84432467c161fb83eeae244
push id388
push userclokep@gmail.com
push dateMon, 28 Jan 2019 20:54:56 +0000
reviewersjorgk
bugs1489172
Bug 1489172 - Backed out changeset c7cda013b0b4 for making the filter editor unusable. a=jorgk
mail/base/content/messenger.css
mailnews/base/search/content/FilterEditor.xul
mailnews/base/search/content/searchWidgets.js
mailnews/base/search/content/searchWidgets.xml
mailnews/jar.mn
--- a/mail/base/content/messenger.css
+++ b/mail/base/content/messenger.css
@@ -68,16 +68,44 @@ searchterm {
 .ruleaction {
   -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleaction");
 }
 
 .ruleactiontype {
   -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleactiontype-menulist");
 }
 
+.ruleactiontarget[type] {
+  -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleactiontarget-base");
+}
+
+.ruleactiontarget[type="movemessage"], .ruleactiontarget[type="copymessage"] {
+  -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleactiontarget-folder");
+}
+
+.ruleactiontarget[type="addtagtomessage"] {
+  -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleactiontarget-tag");
+}
+
+.ruleactiontarget[type="setpriorityto"] {
+  -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleactiontarget-priority");
+}
+
+.ruleactiontarget[type="setjunkscore"] {
+  -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleactiontarget-junkscore");
+}
+
+.ruleactiontarget[type="forwardmessage"] {
+  -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleactiontarget-forwardto");
+}
+
+.ruleactiontarget[type="replytomessage"] {
+  -moz-binding: url("chrome://messenger/content/searchWidgets.xml#ruleactiontarget-replyto");
+}
+
 dummy.usesMailWidgets {
   -moz-binding: url("chrome://messenger/content/mailWidgets.xml#dummy");
 }
 
 #searchInput {
   -moz-binding: url("chrome://messenger/content/search.xml#glodaSearch");
 }
 
--- a/mailnews/base/search/content/FilterEditor.xul
+++ b/mailnews/base/search/content/FilterEditor.xul
@@ -31,17 +31,16 @@
 
   <dummy class="usesMailWidgets"/>
   <stringbundleset id="stringbundleset">
     <stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
     <stringbundle id="bundle_filter" src="chrome://messenger/locale/filter.properties"/>
     <stringbundle id="bundle_search" src="chrome://messenger/locale/search.properties"/>
   </stringbundleset>
 
-  <script type="application/javascript" src="chrome://messenger/content/searchWidgets.js"/>
   <script type="application/javascript" src="chrome://messenger/content/mailWindowOverlay.js"/>
   <script type="application/javascript" src="chrome://messenger/content/mailCommands.js"/>
   <script type="application/javascript" src="chrome://messenger/content/FilterEditor.js"/>
 #ifndef MOZ_THUNDERBIRD
   <script type="application/javascript" src="chrome://messenger/content/searchTermOverlay.js"/>
 #else
   <script type="application/javascript" src="chrome://messenger/content/searchTerm.js"/>
 #endif
deleted file mode 100644
--- a/mailnews/base/search/content/searchWidgets.js
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* global MozXULElement, gFilter, gFilterList */
-
-ChromeUtils.import("resource:///modules/MailUtils.jsm");
-
-const updateParentNode = (parentNode) => {
-  if (parentNode.hasAttribute("initialActionIndex")) {
-    let actionIndex = parentNode.getAttribute("initialActionIndex");
-    let filterAction = gFilter.getActionAt(actionIndex);
-    parentNode.initWithAction(filterAction);
-  }
-  parentNode.updateRemoveButton();
-};
-
-class MozRuleactiontargetTag extends MozXULElement {
-  connectedCallback() {
-    const menulist = document.createElement("menulist");
-    const menuPopup = document.createElement("menupopup");
-
-    menulist.classList.add("ruleactionitem");
-    menulist.setAttribute("flex", "1");
-    menulist.appendChild(menuPopup);
-
-    for (let taginfo of MailServices.tags.getAllTags({})) {
-      const newMenuItem = document.createElement("menuitem");
-      newMenuItem.setAttribute("label", taginfo.tag);
-      newMenuItem.setAttribute("value", taginfo.key);
-      menuPopup.appendChild(newMenuItem);
-    }
-
-    // propagating a pre-existing hack to make the tag get displayed correctly in the menulist
-    // now that we"ve changed the tags for each menu list. We need to use the current selectedIndex
-    // (if its defined) to handle the case where we were initialized with a filter action already.
-    const currentItem = menulist.selectedItem;
-    menulist.selectedItem = null;
-    menulist.selectedItem = currentItem;
-
-    this.appendChild(menulist);
-
-    updateParentNode(this.closest(".ruleaction"));
-  }
-}
-
-class MozRuleactiontargetPriority extends MozXULElement {
-  connectedCallback() {
-    this.appendChild(MozXULElement.parseXULToFragment(`
-      <menulist class="ruleactionitem" flex="1">
-        <menupopup>
-          <menuitem value="6" label="&highestPriorityCmd.label;"></menuitem>
-          <menuitem value="5" label="&highPriorityCmd.label;"></menuitem>
-          <menuitem value="4" label="&normalPriorityCmd.label;"></menuitem>
-          <menuitem value="3" label="&lowPriorityCmd.label;"></menuitem>
-          <menuitem value="2" label="&lowestPriorityCmd.label;"></menuitem>
-        </menupopup>
-      </menulist>
-      `, [
-        "chrome://messenger/locale/FilterEditor.dtd",
-      ]));
-
-    updateParentNode(this.closest(".ruleaction"));
-  }
-}
-
-class MozRuleactiontargetJunkscore extends MozXULElement {
-  connectedCallback() {
-    this.appendChild(MozXULElement.parseXULToFragment(`
-      <menulist class="ruleactionitem" flex="1">
-        <menupopup>
-          <menuitem value="100" label="&junk.label;"/>
-          <menuitem value="0" label="&notJunk.label;"/>
-        </menupopup>
-      </menulist>
-      `, [
-        "chrome://messenger/locale/FilterEditor.dtd",
-      ]));
-
-    updateParentNode(this.closest(".ruleaction"));
-  }
-}
-
-class MozRuleactiontargetReplyto extends MozXULElement {
-  connectedCallback() {
-    const menulist = document.createElement("menulist");
-    const menuPopup = document.createElement("menupopup");
-
-    menulist.classList.add("ruleactionitem");
-    menulist.setAttribute("flex", "1");
-    menulist.appendChild(menuPopup);
-
-    this.appendChild(menulist);
-
-    document.getAnonymousElementByAttribute(this.closest(".ruleaction"), "class", "ruleactiontype")
-            .getTemplates(true, menulist);
-
-    updateParentNode(this.closest(".ruleaction"));
-  }
-}
-
-
-class MozRuleactiontargetForwardto extends MozXULElement {
-  connectedCallback() {
-    const textbox = document.createElement("textbox");
-
-    textbox.classList.add("ruleactionitem");
-    textbox.setAttribute("flex", "1");
-
-    this.appendChild(textbox);
-
-    updateParentNode(this.closest(".ruleaction"));
-  }
-}
-
-class MozRuleactiontargetFolder extends MozXULElement {
-  connectedCallback() {
-    this.appendChild(MozXULElement.parseXULToFragment(`
-      <menulist class="ruleactionitem folderMenuItem" flex="1" displayformat="verbose">
-        <menupopup type="folder" mode="filing" class="menulist-menupopup" showRecent="true" recentLabel="&recentFolders.label;" showFileHereLabel="true"></menupopup>
-      </menulist>
-      `, [
-        "chrome://messenger/locale/messenger.dtd",
-      ]));
-
-    this.menulist = this.querySelector("menulist");
-
-    this.menulist.addEventListener("command", (event) => {
-      this.setPicker(event);
-    });
-
-    let folder = this.menulist.value ?
-      MailUtils.getOrCreateFolder(this.menulist.value) :
-      gFilterList.folder;
-
-    // An account folder is not a move/copy target; show "Choose Folder".
-    folder = folder.isServer ? null : folder;
-
-    // The menupopup constructor needs to finish first.
-    this.menulist.menupopup.selectFolder(folder);
-
-    updateParentNode(this.closest(".ruleaction"));
-  }
-
-  setPicker(event) {
-    this.menulist.menupopup.selectFolder(event.target._folder);
-  }
-}
-
-class MozRuleactiontargetWrapper extends MozXULElement {
-  static get observedAttributes() {
-    return ["type"];
-  }
-
-  get ruleactiontargetElement() {
-    return this.node;
-  }
-
-  connectedCallback() {
-    this._updateAttributes();
-  }
-
-  attributeChangedCallback() {
-    this._updateAttributes();
-  }
-
-  _getChildNode(type) {
-    const elementMapping = {
-      "movemessage": "ruleactiontarget-folder",
-      "copymessage": "ruleactiontarget-folder",
-      "setpriorityto": "ruleactiontarget-priority",
-      "setjunkscore": "ruleactiontarget-junkscore",
-      "forwardmessage": "ruleactiontarget-forwardto",
-      "replytomessage": "ruleactiontarget-replyto",
-      "addtagtomessage": "ruleactiontarget-tag",
-    };
-    const elementName = elementMapping[type];
-
-    return elementName ? document.createElement(elementName) : null;
-  }
-
-  _updateAttributes() {
-    const type = this.getAttribute("type");
-
-    while (this.firstChild) {
-      this.firstChild.remove();
-    }
-
-    if (type == null) {
-      return;
-    }
-
-    this.node = this._getChildNode(type);
-
-    if (this.node) {
-      this.node.setAttribute("flex", "1");
-      this.appendChild(this.node);
-    }
-  }
-}
-
-customElements.define("ruleactiontarget-tag", MozRuleactiontargetTag);
-customElements.define("ruleactiontarget-priority", MozRuleactiontargetPriority);
-customElements.define("ruleactiontarget-junkscore", MozRuleactiontargetJunkscore);
-customElements.define("ruleactiontarget-replyto", MozRuleactiontargetReplyto);
-customElements.define("ruleactiontarget-forwardto", MozRuleactiontargetForwardto);
-customElements.define("ruleactiontarget-folder", MozRuleactiontargetFolder);
-customElements.define("ruleactiontarget-wrapper", MozRuleactiontargetWrapper);
--- a/mailnews/base/search/content/searchWidgets.xml
+++ b/mailnews/base/search/content/searchWidgets.xml
@@ -315,19 +315,18 @@
       </method>
     </implementation>
   </binding>
 
   <binding id="ruleaction" extends="#filterlistitem">
     <content allowevents="true">
       <xul:hbox class="ruleactiontype"
                     flex="&filterActionTypeFlexValue;"/>
-      <xul:ruleactiontarget-wrapper xbl:inherits="type=value"
-                                    class="ruleactiontarget"
-                                    flex="&filterActionTargetFlexValue;"/>
+      <xul:hbox class="ruleactiontarget" xbl:inherits="type=value"
+                    flex="&filterActionTargetFlexValue;"/>
       <xul:hbox>
         <xul:button class="small-button"
                     label="+"
                     tooltiptext="&addAction.tooltip;"
                     oncommand="this.parentNode.parentNode.addRow();"/>
         <xul:button class="small-button"
                     label="&#x2212;"
                     tooltiptext="&removeAction.tooltip;"
@@ -358,24 +357,24 @@
       </method>
 
       <method name="initWithAction">
         <parameter name="aFilterAction"/>
         <body>
           <![CDATA[
             var filterActionStr;
             var actionTarget = document.getAnonymousNodes(this)[1];
-            let actionItem = actionTarget.ruleactiontargetElement;
+            var actionItem = document.getAnonymousNodes(actionTarget);
             var nsMsgFilterAction = Ci.nsMsgFilterAction;
             switch (aFilterAction.type)
             {
               case nsMsgFilterAction.Custom:
                 filterActionStr = aFilterAction.customId;
                 if (actionItem)
-                  actionItem.childNodes[0].value = aFilterAction.strValue;
+                  actionItem[0].value = aFilterAction.strValue;
 
                 // Make sure the custom action has been added. If not, it
                 // probably was from an extension that has been removed. We'll
                 // show a dummy menuitem to warn the user.
                 var needCustomLabel = true;
                 for (var i = 0; i < gCustomActions.length; i++)
                 {
                   if (gCustomActions[i].id == filterActionStr)
@@ -400,33 +399,33 @@
                       null, null, 0, 0,
                       Ci.nsIScriptError.errorFlag,
                       "component javascript");
                   Services.console.logMessage(scriptError);
                 }
                 break;
               case nsMsgFilterAction.MoveToFolder:
               case nsMsgFilterAction.CopyToFolder:
-                actionItem.childNodes[0].value = aFilterAction.targetFolderUri;
+                actionItem[0].value = aFilterAction.targetFolderUri;
                 break;
               case nsMsgFilterAction.Reply:
               case nsMsgFilterAction.Forward:
-                actionItem.childNodes[0].value = aFilterAction.strValue;
+                actionItem[0].value = aFilterAction.strValue;
                 break;
               case nsMsgFilterAction.Label:
-                actionItem.childNodes[0].value = aFilterAction.label;
+                actionItem[0].value = aFilterAction.label;
                 break;
               case nsMsgFilterAction.ChangePriority:
-                actionItem.childNodes[0].value = aFilterAction.priority;
+                actionItem[0].value = aFilterAction.priority;
                 break;
               case nsMsgFilterAction.JunkScore:
-                actionItem.childNodes[0].value = aFilterAction.junkScore;
+                actionItem[0].value = aFilterAction.junkScore;
                 break;
               case nsMsgFilterAction.AddTag:
-                actionItem.childNodes[0].value = aFilterAction.strValue;
+                actionItem[0].value = aFilterAction.strValue;
                 break;
               default:
                 break;
             }
             if (aFilterAction.type != nsMsgFilterAction.Custom)
               filterActionStr = gFilterActionStrings[aFilterAction.type];
             document.getAnonymousNodes(this.mRuleActionType)[0]
                     .value = filterActionStr;
@@ -440,49 +439,47 @@
       <method name="validateAction">
         <body>
           <![CDATA[
             // returns true if this row represents a valid filter action and false otherwise.
             // This routine also prompts the user.
             ChromeUtils.import("resource:///modules/MailUtils.jsm", this);
             var filterActionString = this.getAttribute('value');
             var actionTarget = document.getAnonymousNodes(this)[1];
-            let actionTargetLabel = actionTarget.ruleactiontargetElement &&
-                                    actionTarget.ruleactiontargetElement.childNodes[0].value;
             var errorString, customError;
 
             switch (filterActionString)
             {
               case "movemessage":
               case "copymessage":
-                let msgFolder = actionTargetLabel ?
-                  this.MailUtils.getOrCreateFolder(actionTargetLabel) : null;
+                let msgFolder = document.getAnonymousNodes(actionTarget)[0].value ?
+                  this.MailUtils.getOrCreateFolder(document.getAnonymousNodes(actionTarget)[0].value) : null;
                 if (!msgFolder || !msgFolder.canFileMessages)
                   errorString = "mustSelectFolder";
                 break;
               case "forwardmessage":
-                if (actionTargetLabel.length < 3 ||
-                    actionTargetLabel.indexOf('@') < 1)
+                if (document.getAnonymousNodes(actionTarget)[0].value.length < 3 ||
+                    document.getAnonymousNodes(actionTarget)[0].value.indexOf('@') < 1)
                   errorString = "enterValidEmailAddress";
                 break;
               case "replytomessage":
-                if (!actionTarget.ruleactiontargetElement.childNodes[0].selectedItem)
+                if (!document.getAnonymousNodes(actionTarget)[0].selectedItem)
                    errorString = "pickTemplateToReplyWith";
                 break;
               default:
                 // some custom actions have no action value node
                 if (!document.getAnonymousNodes(actionTarget))
                   return true;
                 // locate the correct custom action, and check validity
                 for (var i = 0; i < gCustomActions.length; i++)
                   if (gCustomActions[i].id == filterActionString)
                   {
                     customError =
                         gCustomActions[i].validateActionValue(
-                          actionTargetLabel,
+                          document.getAnonymousNodes(actionTarget)[0].value,
                           gFilterList.folder, gFilterType);
                     break;
                   }
                 break;
             }
 
             errorString = errorString ?
                           gFilterBundle.getString(errorString) :
@@ -499,60 +496,59 @@
         <parameter name="aFilter"/>
         <body>
           <![CDATA[
             // create a new filter action, fill it in, and then append it to the filter
             var filterAction = aFilter.createAction();
             var filterActionString = this.getAttribute('value');
             filterAction.type = gFilterActionStrings.indexOf(filterActionString);
             var actionTarget = document.getAnonymousNodes(this)[1];
-            let actionItem = actionTarget.ruleactiontargetElement;
+            var actionItem = document.getAnonymousNodes(actionTarget);
             var nsMsgFilterAction = Ci.nsMsgFilterAction;
             switch (filterAction.type)
             {
               case nsMsgFilterAction.Label:
-                filterAction.label = actionItem.childNodes[0].getAttribute("value");
+                filterAction.label = actionItem[0].getAttribute("value");
                 break;
               case nsMsgFilterAction.ChangePriority:
-                filterAction.priority = actionItem.childNodes[0].getAttribute("value");
+                filterAction.priority = actionItem[0].getAttribute("value");
                 break;
               case nsMsgFilterAction.MoveToFolder:
               case nsMsgFilterAction.CopyToFolder:
-                filterAction.targetFolderUri = actionItem.childNodes[0].value;
+                filterAction.targetFolderUri = actionItem[0].value;
                 break;
               case nsMsgFilterAction.JunkScore:
-                filterAction.junkScore = actionItem.childNodes[0].value;
+                filterAction.junkScore = actionItem[0].value;
                 break;
               case nsMsgFilterAction.Custom:
                 filterAction.customId = filterActionString;
                 // fall through to set the value
               default:
-                if (actionItem && actionItem.childNodes.length > 0)
-                  filterAction.strValue = actionItem.childNodes[0].value;
+                if (actionItem)
+                  filterAction.strValue = actionItem[0].value;
                 break;
               }
             aFilter.appendAction(filterAction);
           ]]>
         </body>
       </method>
 
       <method name="getActionStrings">
         <parameter name="aActionStrings"/>
         <body>
           <![CDATA[
             // Collect the action names and arguments in a plain string form.
             let actionTarget = document.getAnonymousNodes(this)[1];
-            let actionItem = actionTarget.ruleactiontargetElement;
-            let actionItemLabel = actionItem.childNodes[0].label;
+            let actionItem = document.getAnonymousNodes(actionTarget);
 
             aActionStrings.push({
               label: document.getAnonymousNodes(this.mRuleActionType)[0].label,
               argument: actionItem ?
-                        (actionItemLabel ?
-                         actionItemLabel : actionItem.childNodes[0].value) : ""
+                        (actionItem[0].label ?
+                         actionItem[0].label : actionItem[0].value) : ""
             });
           ]]>
         </body>
       </method>
 
       <method name="updateRemoveButton">
         <body>
           <![CDATA[
@@ -599,9 +595,148 @@
             this.mListBox.setAttribute("focusedAction", this.mListBox.getIndexOfItem(this));
           ]]>
         </body>
       </method>
 
     </implementation>
   </binding>
 
+  <binding id="ruleactiontarget-base">
+    <implementation>
+      <constructor>
+        <![CDATA[
+          if (this.parentNode.hasAttribute('initialActionIndex'))
+          {
+            let actionIndex = this.parentNode.getAttribute('initialActionIndex');
+            let filterAction = gFilter.getActionAt(actionIndex);
+            this.parentNode.initWithAction(filterAction);
+          }
+          this.parentNode.updateRemoveButton();
+        ]]>
+      </constructor>
+    </implementation>
+  </binding>
+
+  <binding id="ruleactiontarget-tag" extends="chrome://messenger/content/searchWidgets.xml#ruleactiontarget-base">
+    <content>
+      <xul:menulist class="ruleactionitem">
+        <xul:menupopup>
+        </xul:menupopup>
+      </xul:menulist>
+    </content>
+
+    <implementation>
+      <constructor>
+        <![CDATA[
+            let menuPopup = document.getAnonymousNodes(this)[0].menupopup;
+            let tagArray = MailServices.tags.getAllTags({});
+            for (let i = 0; i < tagArray.length; ++i)
+            {
+              var taginfo = tagArray[i];
+              var newMenuItem = document.createElement('menuitem');
+              newMenuItem.setAttribute('label', taginfo.tag);
+              newMenuItem.setAttribute('value', taginfo.key);
+              menuPopup.appendChild(newMenuItem);
+            }
+          // propagating a pre-existing hack to make the tag get displayed correctly in the menulist
+          // now that we've changed the tags for each menu list. We need to use the current selectedIndex
+          // (if its defined) to handle the case where we were initialized with a filter action already.
+          var currentItem = document.getAnonymousNodes(this)[0].selectedItem;
+          document.getAnonymousNodes(this)[0].selectedItem = null;
+          document.getAnonymousNodes(this)[0].selectedItem = currentItem;
+        ]]>
+      </constructor>
+    </implementation>
+  </binding>
+
+  <binding id="ruleactiontarget-priority" extends="chrome://messenger/content/searchWidgets.xml#ruleactiontarget-base">
+    <content>
+      <xul:menulist class="ruleactionitem">
+        <xul:menupopup>
+          <xul:menuitem value="6" label="&highestPriorityCmd.label;"/>
+          <xul:menuitem value="5" label="&highPriorityCmd.label;"/>
+          <xul:menuitem value="4" label="&normalPriorityCmd.label;"/>
+          <xul:menuitem value="3" label="&lowPriorityCmd.label;"/>
+          <xul:menuitem value="2" label="&lowestPriorityCmd.label;"/>
+        </xul:menupopup>
+      </xul:menulist>
+    </content>
+  </binding>
+
+  <binding id="ruleactiontarget-junkscore" extends="chrome://messenger/content/searchWidgets.xml#ruleactiontarget-base">
+    <content>
+      <xul:menulist class="ruleactionitem">
+        <xul:menupopup>
+          <xul:menuitem value="100" label="&junk.label;"/>
+          <xul:menuitem value="0"   label="&notJunk.label;"/>
+        </xul:menupopup>
+      </xul:menulist>
+    </content>
+  </binding>
+
+  <binding id="ruleactiontarget-replyto" extends="chrome://messenger/content/searchWidgets.xml#ruleactiontarget-base">
+    <content>
+      <xul:menulist class="ruleactionitem">
+        <xul:menupopup>
+        </xul:menupopup>
+      </xul:menulist>
+    </content>
+
+    <implementation>
+      <constructor>
+        <![CDATA[
+          document.getAnonymousElementByAttribute(
+            this.parentNode, "class", "ruleactiontype")
+            .getTemplates(true, document.getAnonymousNodes(this)[0]);
+        ]]>
+      </constructor>
+    </implementation>
+  </binding>
+
+  <binding id="ruleactiontarget-forwardto" extends="chrome://messenger/content/searchWidgets.xml#ruleactiontarget-base">
+    <content>
+      <xul:textbox class="ruleactionitem" flex="1"/>
+    </content>
+  </binding>
+
+  <binding id="ruleactiontarget-folder" extends="chrome://messenger/content/searchWidgets.xml#ruleactiontarget-base">
+    <content>
+      <xul:menulist class="ruleactionitem folderMenuItem"
+                    displayformat="verbose"
+                    oncommand="this.parentNode.setPicker(event);">
+        <xul:menupopup type="folder"
+                       mode="filing"
+                       class="menulist-menupopup"
+                       showRecent="true"
+                       recentLabel="&recentFolders.label;"
+                       showFileHereLabel="true"/>
+      </xul:menulist>
+    </content>
+
+    <implementation>
+      <constructor>
+        <![CDATA[
+          ChromeUtils.import("resource:///modules/MailUtils.jsm", this);
+          let folder = this.menulist.value ?
+                         this.MailUtils.getOrCreateFolder(this.menulist.value) :
+                         gFilterList.folder;
+          // An account folder is not a move/copy target; show "Choose Folder".
+          folder = folder.isServer ? null : folder;
+          let menupopup = this.menulist.menupopup;
+          // The menupopup constructor needs to finish first.
+          setTimeout(function() { menupopup.selectFolder(folder); }, 0);
+        ]]>
+      </constructor>
+
+      <field name="menulist">document.getAnonymousNodes(this)[0]</field>
+      <method name="setPicker">
+        <parameter name="aEvent"/>
+        <body>
+          <![CDATA[
+            this.menulist.menupopup.selectFolder(aEvent.target._folder);
+          ]]>
+        </body>
+      </method>
+    </implementation>
+  </binding>
+
 </bindings>
--- a/mailnews/jar.mn
+++ b/mailnews/jar.mn
@@ -101,17 +101,16 @@ messenger.jar:
 #else
     content/messenger/searchTerm.js                                            (base/search/content/searchTermOverlay.js)
 #endif
 *   content/messenger/CustomHeaders.xul                                        (base/search/content/CustomHeaders.xul)
     content/messenger/CustomHeaders.js                                         (base/search/content/CustomHeaders.js)
 *   content/messenger/FilterEditor.xul                                         (base/search/content/FilterEditor.xul)
     content/messenger/FilterEditor.js                                          (base/search/content/FilterEditor.js)
     content/messenger/searchWidgets.xml                                        (base/search/content/searchWidgets.xml)
-    content/messenger/searchWidgets.js                                         (base/search/content/searchWidgets.js)
     content/messenger/viewLog.xul                                              (base/search/content/viewLog.xul)
     content/messenger/viewLog.js                                               (base/search/content/viewLog.js)
     content/messenger/messengercompose/askSendFormat.js                        (compose/content/askSendFormat.js)
     content/messenger/messengercompose/askSendFormat.xul                       (compose/content/askSendFormat.xul)
     content/messenger/messengercompose/sendProgress.xul                        (compose/content/sendProgress.xul)
     content/messenger/messengercompose/sendProgress.js                         (compose/content/sendProgress.js)
 #ifndef MOZ_THUNDERBIRD
     content/messenger/messengercompose/menulistCompactBindings.xml             (compose/content/menulistCompactBindings.xml)