summaryrefslogtreecommitdiffstats
path: root/mailnews/base/search/content/searchWidgets.xml
diff options
context:
space:
mode:
Diffstat (limited to 'mailnews/base/search/content/searchWidgets.xml')
-rw-r--r--mailnews/base/search/content/searchWidgets.xml738
1 files changed, 738 insertions, 0 deletions
diff --git a/mailnews/base/search/content/searchWidgets.xml b/mailnews/base/search/content/searchWidgets.xml
new file mode 100644
index 000000000..80ebe38c4
--- /dev/null
+++ b/mailnews/base/search/content/searchWidgets.xml
@@ -0,0 +1,738 @@
+<?xml version="1.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/. -->
+
+<!--
+ This file has the following external dependencies:
+ -gFilterActionStrings from FilterEditor.js
+ -gFilterList from FilterEditor.js
+ -gFilter from FilterEditor.js
+ -gCustomActions from FilterEditor.js
+ -gFilterType from FilterEditor.js
+ -checkActionsReorder from FilterEditor.js
+-->
+
+<!DOCTYPE dialog [
+ <!ENTITY % filterEditorDTD SYSTEM "chrome://messenger/locale/FilterEditor.dtd" >
+%filterEditorDTD;
+ <!ENTITY % messengerDTD SYSTEM "chrome://messenger/locale/messenger.dtd" >
+%messengerDTD;
+]>
+
+<bindings id="filterBindings"
+ xmlns="http://www.mozilla.org/xbl"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:nc="http://home.netscape.com/NC-rdf#"
+ xmlns:xbl="http://www.mozilla.org/xbl">
+
+ <binding id="ruleactiontype-menulist">
+ <content>
+ <xul:menulist class="ruleaction-type">
+ <xul:menupopup>
+ <xul:menuitem label="&moveMessage.label;" value="movemessage" enablefornews="false"/>
+ <xul:menuitem label="&copyMessage.label;" value="copymessage"/>
+ <xul:menuseparator enablefornews="false"/>
+ <xul:menuitem label="&forwardTo.label;" value="forwardmessage" enablefornews="false"/>
+ <xul:menuitem label="&replyWithTemplate.label;" value="replytomessage" enablefornews="false"/>
+ <xul:menuseparator/>
+ <xul:menuitem label="&markMessageRead.label;" value="markasread"/>
+ <xul:menuitem label="&markMessageUnread.label;" value="markasunread"/>
+ <xul:menuitem label="&markMessageStarred.label;" value="markasflagged"/>
+ <xul:menuitem label="&setPriority.label;" value="setpriorityto"/>
+ <xul:menuitem label="&addTag.label;" value="addtagtomessage"/>
+ <xul:menuitem label="&setJunkScore.label;" value="setjunkscore" enablefornews="false"/>
+ <xul:menuseparator enableforpop3="true"/>
+ <xul:menuitem label="&deleteMessage.label;" value="deletemessage"/>
+ <xul:menuitem label="&deleteFromPOP.label;" value="deletefrompopserver" enableforpop3="true"/>
+ <xul:menuitem label="&fetchFromPOP.label;" value="fetchfrompopserver" enableforpop3="true"/>
+ <xul:menuseparator/>
+ <xul:menuitem label="&ignoreThread.label;" value="ignorethread"/>
+ <xul:menuitem label="&ignoreSubthread.label;" value="ignoresubthread"/>
+ <xul:menuitem label="&watchThread.label;" value="watchthread"/>
+ <xul:menuseparator/>
+ <xul:menuitem label="&stopExecution.label;" value="stopexecution"/>
+ </xul:menupopup>
+ </xul:menulist>
+ </content>
+
+ <implementation>
+ <constructor>
+ <![CDATA[
+ this.addCustomActions();
+ this.hideInvalidActions();
+ // differentiate between creating a new, next available action,
+ // and creating a row which will be initialized with an action
+ if (!this.parentNode.hasAttribute('initialActionIndex'))
+ {
+ var unavailableActions = this.usedActionsList();
+ // select the first one that's not in the list
+ for (var index = 0; index < this.menuitems.length; index++)
+ {
+ var menu = this.menuitems[index];
+ if (!(menu.value in unavailableActions) && !menu.hidden)
+ {
+ this.menulist.value = menu.value;
+ this.parentNode.setAttribute('value', menu.value);
+ break;
+ }
+ }
+ }
+ else
+ {
+ this.parentNode.mActionTypeInitialized = true;
+ this.parentNode.clearInitialActionIndex();
+ }
+ ]]>
+ </constructor>
+
+ <field name="menulist">document.getAnonymousNodes(this)[0]</field>
+ <field name="menuitems">this.menulist.getElementsByTagNameNS(this.menulist.namespaceURI, 'menuitem')</field>
+
+ <method name="hideInvalidActions">
+ <body>
+ <![CDATA[
+ let menupopup = this.menulist.menupopup;
+ let scope = getScopeFromFilterList(gFilterList);
+
+ // walk through the list of filter actions and hide any actions which aren't valid
+ // for our given scope (news, imap, pop, etc) and context
+ let elements, i;
+
+ // disable / enable all elements in the "filteractionlist"
+ // based on the scope and the "enablefornews" attribute
+ elements = menupopup.getElementsByAttribute("enablefornews", "true");
+ for (i = 0; i < elements.length; i++)
+ elements[i].hidden = scope != Components.interfaces.nsMsgSearchScope.newsFilter;
+
+ elements = menupopup.getElementsByAttribute("enablefornews", "false");
+ for (i = 0; i < elements.length; i++)
+ elements[i].hidden = scope == Components.interfaces.nsMsgSearchScope.newsFilter;
+
+ elements = menupopup.getElementsByAttribute("enableforpop3", "true");
+ for (i = 0; i < elements.length; i++)
+ elements[i].hidden = !((gFilterList.folder.server.type == "pop3") ||
+ (gFilterList.folder.server.type == "none"));
+
+ elements = menupopup.getElementsByAttribute("isCustom", "true");
+ // Note there might be an additional element here as a placeholder
+ // for a missing action, so we iterate over the known actions
+ // instead of the elements.
+ for (i = 0; i < gCustomActions.length; i++)
+ elements[i].hidden = !gCustomActions[i]
+ .isValidForType(gFilterType, scope);
+
+ // Disable "Reply with Template" if there are no templates.
+ if (!this.getTemplates(false)) {
+ elements = menupopup.getElementsByAttribute("value", "replytomessage");
+ if (elements.length == 1)
+ elements[0].hidden = true;
+ }
+ ]]>
+ </body>
+ </method>
+
+ <method name="addCustomActions">
+ <body>
+ <![CDATA[
+ var menupopup = this.menulist.menupopup;
+ for (var i = 0; i < gCustomActions.length; i++)
+ {
+ var customAction = gCustomActions[i];
+ var menuitem = document.createElementNS(
+ "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
+ "xul:menuitem");
+ menuitem.setAttribute("label", customAction.name);
+ menuitem.setAttribute("value", customAction.id);
+ menuitem.setAttribute("isCustom", "true");
+ menupopup.appendChild(menuitem);
+ }
+ ]]>
+ </body>
+ </method>
+
+ <!-- returns a hash containing all of the filter actions which are currently being used by other filteractionrows -->
+ <method name="usedActionsList">
+ <body>
+ <![CDATA[
+ var usedActions = {};
+ var currentFilterActionRow = this.parentNode;
+ var listBox = currentFilterActionRow.mListBox; // need to account for the list item
+ // now iterate over each list item in the list box
+ for (var index = 0; index < listBox.getRowCount(); index++)
+ {
+ var filterActionRow = listBox.getItemAtIndex(index);
+ if (filterActionRow != currentFilterActionRow)
+ {
+ var actionValue = filterActionRow.getAttribute('value');
+
+ // let custom actions decide if dups are allowed
+ var isCustom = false;
+ for (var i = 0; i < gCustomActions.length; i++)
+ {
+ if (gCustomActions[i].id == actionValue)
+ {
+ isCustom = true;
+ if (!gCustomActions[i].allowDuplicates)
+ usedActions[actionValue] = true;
+ break;
+ }
+ }
+
+ if (!isCustom) {
+ // The following actions can appear more than once in a single filter
+ // so do not set them as already used.
+ if (actionValue != 'addtagtomessage' &&
+ actionValue != 'forwardmessage' &&
+ actionValue != 'copymessage')
+ usedActions[actionValue] = true;
+ // If either Delete message or Move message exists, disable the other one.
+ // It does not make sense to apply both to the same message.
+ if (actionValue == 'deletemessage')
+ usedActions['movemessage'] = true;
+ else if (actionValue == 'movemessage')
+ usedActions['deletemessage'] = true;
+ // The same with Mark as read/Mark as Unread.
+ else if (actionValue == 'markasread')
+ usedActions['markasunread'] = true;
+ else if (actionValue == 'markasunread')
+ usedActions['markasread'] = true;
+ }
+ }
+ }
+ return usedActions;
+ ]]>
+ </body>
+ </method>
+
+ <!--
+ - Check if there exist any templates in this account.
+ -
+ - @param populateTemplateList If true, create menuitems representing
+ - the found templates.
+ - @param templateMenuList The menulist element to create items in.
+ -
+ - @return True if at least one template was found, otherwise false.
+ -->
+ <method name="getTemplates">
+ <parameter name="populateTemplateList"/>
+ <parameter name="templateMenuList"/>
+ <body>
+ <![CDATA[
+ Components.utils.import("resource:///modules/iteratorUtils.jsm", this);
+ let identitiesRaw = MailServices.accounts
+ .getIdentitiesForServer(gFilterList.folder.server);
+ let identities = Array.from(this.fixIterator(identitiesRaw,
+ Components.interfaces.nsIMsgIdentity));
+
+ if (!identities.length) // typically if this is Local Folders
+ identities.push(MailServices.accounts.defaultAccount.defaultIdentity);
+
+ let templateFound = false;
+ let foldersScanned = [];
+
+ for (let identity of identities) {
+ let enumerator = null;
+ let msgFolder;
+ try {
+ msgFolder = Components.classes["@mozilla.org/rdf/rdf-service;1"]
+ .getService(Components.interfaces.nsIRDFService)
+ .GetResource(identity.stationeryFolder)
+ .QueryInterface(Components.interfaces.nsIMsgFolder);
+ // If we already processed this folder, do not set enumerator
+ // so that we skip this identity.
+ if (foldersScanned.indexOf(msgFolder) == -1) {
+ foldersScanned.push(msgFolder);
+ enumerator = msgFolder.msgDatabase.EnumerateMessages();
+ }
+ } catch (e) {
+ // The Templates folder may not exist, that is OK.
+ }
+
+ if (!enumerator)
+ continue;
+
+ while (enumerator.hasMoreElements()) {
+ let header = enumerator.getNext();
+ if (header instanceof Components.interfaces.nsIMsgDBHdr) {
+ templateFound = true;
+ if (!populateTemplateList)
+ return true;
+ let msgTemplateUri = msgFolder.URI + "?messageId=" +
+ header.messageId + '&subject=' + header.mime2DecodedSubject;
+ let newItem = templateMenuList.appendItem(header.mime2DecodedSubject,
+ msgTemplateUri);
+ }
+ }
+ }
+
+ return templateFound;
+ ]]>
+ </body>
+ </method>
+
+ </implementation>
+
+ <handlers>
+ <handler event="command">
+ <![CDATA[
+ this.parentNode.setAttribute('value', this.menulist.value);
+ checkActionsReorder();
+ ]]>
+ </handler>
+
+ <handler event="popupshowing">
+ <![CDATA[
+ var unavailableActions = this.usedActionsList();
+ for (var index = 0; index < this.menuitems.length; index++)
+ {
+ var menu = this.menuitems[index];
+ menu.setAttribute('disabled', menu.value in unavailableActions);
+ }
+ ]]>
+ </handler>
+ </handlers>
+ </binding>
+
+ <!-- This binding exists to disable the default binding of a listitem
+ in the search terms. -->
+ <binding id="listitem">
+ <implementation>
+ <method name="_fireEvent">
+ <parameter name="aName"/>
+ <body>
+ <![CDATA[
+ /* This provides a dummy _fireEvent function that
+ the listbox expects to be able to call.
+ See bug 202036. */
+ ]]>
+ </body>
+ </method>
+ </implementation>
+ </binding>
+
+ <binding id="ruleaction" extends="#listitem">
+ <content allowevents="true">
+ <xul:listcell class="ruleactiontype"
+ orient="vertical" align="stretch" pack="center"/>
+ <xul:listcell class="ruleactiontarget" xbl:inherits="type=value"
+ orient="vertical" align="stretch" pack="center"/>
+ <xul:listcell>
+ <xul:button class="small-button"
+ label="+"
+ tooltiptext="&addAction.tooltip;"
+ oncommand="this.parentNode.parentNode.addRow();"/>
+ <xul:button class="small-button"
+ label="&#x2212;"
+ tooltiptext="&removeAction.tooltip;"
+ oncommand="this.parentNode.parentNode.removeRow();"
+ anonid="removeButton"/>
+ </xul:listcell>
+ </content>
+
+ <implementation>
+ <field name="mListBox">this.parentNode</field>
+ <field name="mRemoveButton">document.getAnonymousElementByAttribute(this, "anonid", "removeButton")</field>
+ <field name="mActionTypeInitialized">false</field>
+ <field name="mRuleActionTargetInitialized">false</field>
+ <field name="mRuleActionType">document.getAnonymousNodes(this)[0]</field>
+
+ <method name="clearInitialActionIndex">
+ <body>
+ <![CDATA[
+ // we should only remove the initialActionIndex after we have been told that
+ // both the rule action type and the rule action target have both been built since they both need
+ // this piece of information. This complication arises because both of these child elements are getting
+ // bound asynchronously after the search row has been constructed
+
+ if (this.mActionTypeInitialized && this.mRuleActionTargetInitialized)
+ this.removeAttribute('initialActionIndex');
+ ]]>
+ </body>
+ </method>
+
+ <method name="initWithAction">
+ <parameter name="aFilterAction"/>
+ <body>
+ <![CDATA[
+ var filterActionStr;
+ var actionTarget = document.getAnonymousNodes(this)[1];
+ var actionItem = document.getAnonymousNodes(actionTarget);
+ var nsMsgFilterAction = Components.interfaces.nsMsgFilterAction;
+ switch (aFilterAction.type)
+ {
+ case nsMsgFilterAction.Custom:
+ filterActionStr = aFilterAction.customId;
+ if (actionItem)
+ 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)
+ {
+ needCustomLabel = false;
+ break;
+ }
+ }
+ if (needCustomLabel)
+ {
+ var menuitem = document.createElementNS(
+ "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
+ "xul:menuitem");
+ menuitem.setAttribute("label",
+ gFilterBundle.getString("filterMissingCustomAction"));
+ menuitem.setAttribute("value", filterActionStr);
+ menuitem.disabled = true;
+ this.mRuleActionType.menulist.menupopup.appendChild(menuitem);
+ var scriptError = Components.classes["@mozilla.org/scripterror;1"]
+ .createInstance(Components.interfaces.nsIScriptError);
+ scriptError.init("Missing custom action " + filterActionStr,
+ null, null, 0, 0,
+ Components.interfaces.nsIScriptError.errorFlag,
+ "component javascript");
+ Services.console.logMessage(scriptError);
+ }
+ break;
+ case nsMsgFilterAction.MoveToFolder:
+ case nsMsgFilterAction.CopyToFolder:
+ actionItem[0].value = aFilterAction.targetFolderUri;
+ break;
+ case nsMsgFilterAction.Reply:
+ case nsMsgFilterAction.Forward:
+ actionItem[0].value = aFilterAction.strValue;
+ break;
+ case nsMsgFilterAction.Label:
+ actionItem[0].value = aFilterAction.label;
+ break;
+ case nsMsgFilterAction.ChangePriority:
+ actionItem[0].value = aFilterAction.priority;
+ break;
+ case nsMsgFilterAction.JunkScore:
+ actionItem[0].value = aFilterAction.junkScore;
+ break;
+ case nsMsgFilterAction.AddTag:
+ actionItem[0].value = aFilterAction.strValue;
+ break;
+ default:
+ break;
+ }
+ if (aFilterAction.type != nsMsgFilterAction.Custom)
+ filterActionStr = gFilterActionStrings[aFilterAction.type];
+ document.getAnonymousNodes(this.mRuleActionType)[0]
+ .value = filterActionStr;
+ this.mRuleActionTargetInitialized = true;
+ this.clearInitialActionIndex();
+ checkActionsReorder();
+ ]]>
+ </body>
+ </method>
+
+ <method name="validateAction">
+ <body>
+ <![CDATA[
+ // returns true if this row represents a valid filter action and false otherwise.
+ // This routine also prompts the user.
+ Components.utils.import("resource:///modules/MailUtils.js", this);
+ var filterActionString = this.getAttribute('value');
+ var actionTarget = document.getAnonymousNodes(this)[1];
+ var errorString, customError;
+
+ switch (filterActionString)
+ {
+ case "movemessage":
+ case "copymessage":
+ let msgFolder = document.getAnonymousNodes(actionTarget)[0].value ?
+ this.MailUtils.getFolderForURI(document.getAnonymousNodes(actionTarget)[0].value) : null;
+ if (!msgFolder || !msgFolder.canFileMessages)
+ errorString = "mustSelectFolder";
+ break;
+ case "forwardmessage":
+ if (document.getAnonymousNodes(actionTarget)[0].value.length < 3 ||
+ document.getAnonymousNodes(actionTarget)[0].value.indexOf('@') < 1)
+ errorString = "enterValidEmailAddress";
+ break;
+ case "replytomessage":
+ 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(
+ document.getAnonymousNodes(actionTarget)[0].value,
+ gFilterList.folder, gFilterType);
+ break;
+ }
+ break;
+ }
+
+ errorString = errorString ?
+ gFilterBundle.getString(errorString) :
+ customError;
+ if (errorString)
+ Services.prompt.alert(window, null, errorString);
+
+ return !errorString;
+ ]]>
+ </body>
+ </method>
+
+ <method name="saveToFilter">
+ <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];
+ var actionItem = document.getAnonymousNodes(actionTarget);
+ var nsMsgFilterAction = Components.interfaces.nsMsgFilterAction;
+ switch (filterAction.type)
+ {
+ case nsMsgFilterAction.Label:
+ filterAction.label = actionItem[0].getAttribute("value");
+ break;
+ case nsMsgFilterAction.ChangePriority:
+ filterAction.priority = actionItem[0].getAttribute("value");
+ break;
+ case nsMsgFilterAction.MoveToFolder:
+ case nsMsgFilterAction.CopyToFolder:
+ filterAction.targetFolderUri = actionItem[0].value;
+ break;
+ case nsMsgFilterAction.JunkScore:
+ filterAction.junkScore = actionItem[0].value;
+ break;
+ case nsMsgFilterAction.Custom:
+ filterAction.customId = filterActionString;
+ // fall through to set the value
+ default:
+ 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 = document.getAnonymousNodes(actionTarget);
+
+ aActionStrings.push({
+ label: document.getAnonymousNodes(this.mRuleActionType)[0].label,
+ argument: actionItem ?
+ (actionItem[0].label ?
+ actionItem[0].label : actionItem[0].value) : ""
+ });
+ ]]>
+ </body>
+ </method>
+
+ <method name="updateRemoveButton">
+ <body>
+ <![CDATA[
+ // if we only have one row of actions, then disable the remove button for that row
+ this.mListBox.getItemAtIndex(0).mRemoveButton.disabled = this.mListBox.getRowCount() == 1;
+ ]]>
+ </body>
+ </method>
+
+ <method name="addRow">
+ <body>
+ <![CDATA[
+ let listItem = document.createElement('listitem');
+ listItem.className = 'ruleaction';
+ listItem.setAttribute('onfocus','this.storeFocus();');
+ this.mListBox.insertBefore(listItem, this.nextSibling);
+ this.mListBox.ensureElementIsVisible(listItem);
+
+ // make sure the first remove button is enabled
+ this.updateRemoveButton();
+ checkActionsReorder();
+ ]]>
+ </body>
+ </method>
+
+ <method name="removeRow">
+ <body>
+ <![CDATA[
+ // this.mListBox will fail after the row is removed, so save it
+ let listBox = this.mListBox;
+ if (listBox.getRowCount() > 1)
+ this.remove();
+ // can't use 'this' as it is destroyed now
+ listBox.getItemAtIndex(0).updateRemoveButton();
+ checkActionsReorder();
+ ]]>
+ </body>
+ </method>
+
+ <method name="storeFocus">
+ <body>
+ <![CDATA[
+ // When this action row is focused, store its index in the parent listbox.
+ 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[
+ Components.utils.import("resource:///modules/MailUtils.js", this);
+ let folder = this.menulist.value ?
+ this.MailUtils.getFolderForURI(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>