releases-comm-central/suite/mailnews/mailContextMenus.js

718 строки
26 KiB
JavaScript

/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
//NOTE: gMessengerBundle must be defined and set or this Overlay won't work
/**
* Function to change the highlighted row back to the row that is currently
* outline/dotted without loading the contents of either rows. This is
* triggered when the context menu for a given row is hidden/closed
* (onpopuphiding).
* @param tree the tree element to restore selection for
*/
function RestoreSelectionWithoutContentLoad(tree)
{
// If a delete or move command had been issued, then we should
// reset gRightMouseButtonDown and gThreadPaneDeleteOrMoveOccurred
// and return (see bug 142065).
if(gThreadPaneDeleteOrMoveOccurred)
{
gRightMouseButtonDown = false;
gThreadPaneDeleteOrMoveOccurred = false;
return;
}
var treeSelection = tree.view.selection;
// make sure that currentIndex is valid so that we don't try to restore
// a selection of an invalid row.
if((!treeSelection.isSelected(treeSelection.currentIndex)) &&
(treeSelection.currentIndex >= 0))
{
treeSelection.selectEventsSuppressed = true;
treeSelection.select(treeSelection.currentIndex);
treeSelection.selectEventsSuppressed = false;
// Keep track of which row in the thread pane is currently selected.
// This is currently only needed when deleting messages. See
// declaration of var in msgMail3PaneWindow.js.
if(tree.id == "threadTree")
gThreadPaneCurrentSelectedIndex = treeSelection.currentIndex;
}
else if(treeSelection.currentIndex < 0)
// Clear the selection in the case of when a folder has just been
// loaded where the message pane does not have a message loaded yet.
// When right-clicking a message in this case and dismissing the
// popup menu (by either executing a menu command or clicking
// somewhere else), the selection needs to be cleared.
// However, if the 'Delete Message' or 'Move To' menu item has been
// selected, DO NOT clear the selection, else it will prevent the
// tree view from refreshing.
treeSelection.clearSelection();
// Need to reset gRightMouseButtonDown to false here because
// TreeOnMouseDown() is only called on a mousedown, not on a key down.
// So resetting it here allows the loading of messages in the messagepane
// when navigating via the keyboard or the toolbar buttons *after*
// the context menu has been dismissed.
gRightMouseButtonDown = false;
}
/**
* Function to clear out the global nsContextMenu, and in the case when we
* are a threadpane context menu, restore the selection so that a right-click
* on a non-selected row doesn't move the selection.
* @param aTarget the target of the popup event
*/
function MailContextOnPopupHiding(aTarget)
{
gContextMenu.hiding();
gContextMenu = null;
if (InThreadPane(aTarget))
RestoreSelectionWithoutContentLoad(GetThreadTree());
}
/**
* Determines whether the context menu was triggered by a node that's a child
* of the threadpane by looking for an ancestor node with id="threadTree".
* @param aTarget the target of the popup event
* @return true if the popupNode is a child of the threadpane, otherwise false
*/
function InThreadPane(aTarget)
{
var node = aTarget.triggerNode;
while (node)
{
if (node.id == "threadTree")
return true;
node = node.parentNode;
}
return false;
}
/**
* Function to set up the global nsContextMenu, and the mailnews overlay.
* @param aTarget the target of the popup event
* @return true always
*/
function FillMailContextMenu(aTarget)
{
var inThreadPane = InThreadPane(aTarget);
gContextMenu = new nsContextMenu(aTarget, getBrowser());
// Need to call nsContextMenu's initItems to hide what is not used.
gContextMenu.initItems();
var numSelected = GetNumSelectedMessages();
var oneOrMore = (numSelected > 0);
var single = (numSelected == 1);
var isNewsgroup = gFolderDisplay.selectedMessageIsNews;
// Clear the global var used to keep track if a 'Delete Message' or 'Move
// To' command has been triggered via the thread pane context menu.
gThreadPaneDeleteOrMoveOccurred = false;
// Don't show mail items for links/images, just show related items.
var showMailItems = inThreadPane ||
(!gContextMenu.onImage && !gContextMenu.onLink);
// Select-all and copy are only available in the message-pane
ShowMenuItem("context-selectall", single && !inThreadPane);
ShowMenuItem("context-copy", !inThreadPane);
ShowMenuItem("mailContext-openNewWindow", inThreadPane && single);
ShowMenuItem("mailContext-openNewTab", inThreadPane && single);
ShowMenuItem("mailContext-downloadflagged",
inThreadPane || (numSelected > 1));
ShowMenuItem("mailContext-downloadselected",
inThreadPane || (numSelected > 1));
ShowMenuItem("mailContext-editAsNew", showMailItems && oneOrMore);
ShowMenuItem("mailContext-replySender", showMailItems && single);
ShowMenuItem("mailContext-replyList",
showMailItems && single && !isNewsgroup && IsListPost());
ShowMenuItem("mailContext-replyNewsgroup",
showMailItems && single && isNewsgroup);
ShowMenuItem("mailContext-replySenderAndNewsgroup",
showMailItems && single && isNewsgroup);
ShowMenuItem("mailContext-replyAll", showMailItems && single);
ShowMenuItem("mailContext-forward", showMailItems && single);
ShowMenuItem("mailContext-forwardAsAttachment",
showMailItems && (numSelected > 1));
ShowMenuItem("mailContext-copyMessageUrl",
showMailItems && single && isNewsgroup);
ShowMenuItem("mailContext-archive", showMailItems && oneOrMore &&
gFolderDisplay.canArchiveSelectedMessages);
// Set up the move menu. We can't move from newsgroups.
// Disable move if we can't delete message(s) from this folder.
var msgFolder = GetLoadedMsgFolder();
ShowMenuItem("mailContext-moveMenu",
showMailItems && oneOrMore && !isNewsgroup);
EnableMenuItem("mailContext-moveMenu",
oneOrMore && msgFolder && msgFolder.canDeleteMessages);
// Copy is available as long as something is selected.
var canCopy = showMailItems && oneOrMore && (!gMessageDisplay.isDummy ||
window.arguments[0].scheme == "file");
ShowMenuItem("mailContext-copyMenu", canCopy);
ShowMenuItem("mailContext-tags", showMailItems && oneOrMore);
ShowMenuItem("mailContext-mark", showMailItems && oneOrMore);
ShowMenuItem("mailContext-saveAs", showMailItems && oneOrMore);
ShowMenuItem("mailContext-printpreview", showMailItems && single);
ShowMenuItem("mailContext-print", showMailItems);
EnableMenuItem("mailContext-print", oneOrMore);
ShowMenuItem("mailContext-delete", showMailItems);
EnableMenuItem("mailContext-delete", oneOrMore);
// This function is needed for the case where a folder is just loaded
// (while there isn't a message loaded in the message pane), a right-click
// is done in the thread pane. This function will disable enable the
// 'Delete Message' menu item.
goUpdateCommand('cmd_delete');
ShowMenuItem("context-addemail", gContextMenu.onMailtoLink);
ShowMenuItem("context-composeemailto", gContextMenu.onMailtoLink);
ShowMenuItem("context-createfilterfrom", gContextMenu.onMailtoLink);
// Figure out separators.
ShowSeparator("mailContext-sep-open");
ShowSeparator("mailContext-sep-edit");
ShowSeparator("mailContext-sep-link");
ShowSeparator("mailContext-sep-image");
ShowSeparator("mailContext-sep-copy");
ShowSeparator("mailContext-sep-print");
ShowSeparator("mailContext-sep-tags");
ShowSeparator("mailContext-sep-mark");
ShowSeparator("mailContext-sep-move");
// If we are on a link, go ahead and hide this separator.
if (gContextMenu.onLink)
ShowMenuItem("mailContext-sep-copy", false);
return true;
}
function FolderPaneOnPopupHiding()
{
RestoreSelectionWithoutContentLoad(GetFolderTree());
}
function FillFolderPaneContextMenu()
{
let folders = GetSelectedMsgFolders();
let numSelected = folders.length;
if (numSelected != 1)
return false;
let folder = folders[0];
let isServer = folder.isServer;
let serverType = folder.server.type;
let specialFolder = getSpecialFolderString(folder);
var canSubscribeToFolder = (serverType == "nntp") ||
(serverType == "imap") ||
(serverType == "rss");
var isNewsgroup = !isServer && serverType == 'nntp';
var isMailFolder = !isServer && serverType != 'nntp';
var isVirtualFolder = (specialFolder == "Virtual");
const kTrashFlag = Components.interfaces.nsMsgFolderFlags.Trash;
let isChildOfTrash = folder.isSpecialFolder(kTrashFlag, true);
var canGetMessages =
(isServer && serverType != "none") ||
isNewsgroup ||
((serverType == "rss") && !isChildOfTrash && !isVirtualFolder);
if (!isServer)
{
ShowMenuItem("folderPaneContext-settings", false);
ShowMenuItem("folderPaneContext-properties", true);
EnableMenuItem("folderPaneContext-properties", true);
}
else
{
ShowMenuItem("folderPaneContext-properties", false);
ShowMenuItem("folderPaneContext-settings", true);
EnableMenuItem("folderPaneContext-settings", true);
}
if ((numSelected <= 1) && canGetMessages)
if (isServer)
SetMenuItemLabel("folderPaneContext-getMessages",
gMessengerBundle.getString("getMessagesFor"));
else
SetMenuItemLabel("folderPaneContext-getMessages",
gMessengerBundle.getString("getMessages"));
ShowMenuItem("folderPaneContext-getMessages", (numSelected <= 1) && canGetMessages);
EnableMenuItem("folderPaneContext-getMessages", true);
ShowMenuItem("folderPaneContext-openNewWindow", (numSelected <= 1));
EnableMenuItem("folderPaneContext-openNewWindow", true);
ShowMenuItem("folderPaneContext-openNewTab", (numSelected <= 1));
EnableMenuItem("folderPaneContext-openNewTab", true);
SetupRenameMenuItem(folder, numSelected, isServer, serverType, specialFolder);
SetupRemoveMenuItem(folder, numSelected, isServer, serverType, specialFolder);
SetupCompactMenuItem(folder, numSelected);
ShowMenuItem("folderPaneContext-emptyTrash", (numSelected <= 1) && (specialFolder == 'Trash'));
EnableMenuItem("folderPaneContext-emptyTrash", true);
ShowMenuItem("folderPaneContext-emptyJunk", (numSelected <= 1) && (specialFolder == 'Junk'));
EnableMenuItem("folderPaneContext-emptyJunk", true);
var showSendUnsentMessages = (numSelected <= 1) && (specialFolder == 'Outbox');
ShowMenuItem("folderPaneContext-sendUnsentMessages", showSendUnsentMessages);
if (showSendUnsentMessages)
EnableMenuItem("folderPaneContext-sendUnsentMessages", IsSendUnsentMsgsEnabled(folder));
ShowMenuItem("folderPaneContext-sep-edit", (numSelected <= 1));
SetupNewMenuItem(folder, numSelected, isServer, serverType, specialFolder);
ShowMenuItem("folderPaneContext-subscribe", (numSelected <= 1) && canSubscribeToFolder && !isVirtualFolder);
EnableMenuItem("folderPaneContext-subscribe", true);
ShowMenuItem("folderPaneContext-sep1", (numSelected <= 1) && !isServer);
// News folder context menu =============================================
ShowMenuItem("folderPaneContext-newsUnsubscribe", (numSelected <= 1) && canSubscribeToFolder && isNewsgroup);
EnableMenuItem("folderPaneContext-newsUnsubscribe", true);
ShowMenuItem("folderPaneContext-markNewsgroupAllRead", (numSelected <= 1) && isNewsgroup);
EnableMenuItem("folderPaneContext-markNewsgroupAllRead", true);
// End of News folder context menu =======================================
ShowMenuItem("folderPaneContext-markMailFolderAllRead", (numSelected <= 1) && isMailFolder && !isVirtualFolder);
EnableMenuItem("folderPaneContext-markMailFolderAllRead", true);
ShowMenuItem("folderPaneContext-searchMessages", (numSelected <= 1) && !isVirtualFolder);
goUpdateCommand('cmd_search');
return(true);
}
function SetupRenameMenuItem(msgFolder, numSelected, isServer, serverType, specialFolder)
{
var canRename = (specialFolder == "Junk") ?
CanRenameDeleteJunkMail(msgFolder.URI) : msgFolder.canRename;
ShowMenuItem("folderPaneContext-rename", (numSelected <= 1) && canRename);
EnableMenuItem("folderPaneContext-rename", !isServer && msgFolder.isCommandEnabled("cmd_renameFolder"));
if (canRename)
SetMenuItemLabel("folderPaneContext-rename", gMessengerBundle.getString("renameFolder"));
}
function SetupRemoveMenuItem(msgFolder, numSelected, isServer, serverType, specialFolder)
{
var isMail = serverType != 'nntp';
var canDelete = (specialFolder == "Junk") ?
CanRenameDeleteJunkMail(msgFolder.URI) : msgFolder.deletable;
var showRemove = (numSelected <=1) && isMail && canDelete;
ShowMenuItem("folderPaneContext-remove", showRemove);
if (showRemove)
EnableMenuItem("folderPaneContext-remove", msgFolder.isCommandEnabled("cmd_delete"));
if (canDelete)
SetMenuItemLabel("folderPaneContext-remove", gMessengerBundle.getString("removeFolder"));
}
function SetupCompactMenuItem(folder, numSelected)
{
let canCompact = folder.canCompact;
ShowMenuItem("folderPaneContext-compact", numSelected <= 1 && canCompact);
EnableMenuItem("folderPaneContext-compact", folder.isCommandEnabled("cmd_compactFolder"));
if (canCompact)
SetMenuItemLabel("folderPaneContext-compact", gMessengerBundle.getString("compactFolder"));
}
function SetupNewMenuItem(folder, numSelected, isServer, serverType, specialFolder)
{
var isInbox = specialFolder == "Inbox";
let showNew = (numSelected <= 1 && serverType != "nntp" &&
folder.canCreateSubfolders) || isInbox;
ShowMenuItem("folderPaneContext-new", showNew);
EnableMenuItem("folderPaneContext-new",
folder.server.type != "imap" || !Services.io.offline);
if (showNew)
{
if (isServer || isInbox)
SetMenuItemLabel("folderPaneContext-new", gMessengerBundle.getString("newFolder"));
else
SetMenuItemLabel("folderPaneContext-new", gMessengerBundle.getString("newSubfolder"));
}
}
function ShowMenuItem(id, showItem)
{
var item = document.getElementById(id);
if(item && item.hidden != "true")
item.hidden = !showItem;
}
function EnableMenuItem(id, enableItem)
{
var item = document.getElementById(id);
if(item)
{
var enabled = (item.getAttribute('disabled') !='true');
if(enableItem != enabled)
{
item.setAttribute('disabled', enableItem ? '' : 'true');
}
}
}
function SetMenuItemLabel(id, label)
{
var item = document.getElementById(id);
if(item)
item.setAttribute('label', label);
}
function SetMenuItemAccessKey(id, accessKey)
{
var item = document.getElementById(id);
if(item)
item.setAttribute('accesskey', accessKey);
}
function SiblingHidden(aSibling, aNext)
{
var siblingID;
while (aSibling)
{
siblingID = aSibling.id;
// For some reason, context-blockimage and context-unblockimage are not
// hidden on the very first time the context menu is invoked. They are only
// hidden on subsequent triggers of the context menu. Since we're not
// using these two menuitems in mailnews, we can ignore them if encountered.
if (!aSibling.hidden && (siblingID != "context-blockimage") &&
(siblingID != "context-unblockimage"))
return aSibling.localName == "menuseparator";
aSibling = aNext ? aSibling.nextSibling : aSibling.previousSibling;
}
return true;
}
function ShowSeparator(aSeparatorID)
{
var separator = document.getElementById(aSeparatorID);
// Check to see if there are visible siblings before the next and
// previous separators.
var hidden = SiblingHidden(separator.nextSibling, true) ||
SiblingHidden(separator.previousSibling, false);
ShowMenuItem(aSeparatorID, !hidden);
}
// message pane context menu helper methods
function AddContact(aEmailAddressNode)
{
if (aEmailAddressNode)
AddEmailToAddressBook(aEmailAddressNode.getAttribute("emailAddress"),
aEmailAddressNode.getAttribute("displayName"));
}
function AddEmailToAddressBook(primaryEmail, displayName)
{
window.openDialog("chrome://messenger/content/addressbook/abNewCardDialog.xul",
"", "chrome,resizable=no,titlebar,modal,centerscreen",
{primaryEmail:primaryEmail, displayName:displayName});
}
function EditContact(aEmailAddressNode)
{
if (aEmailAddressNode.cardDetails.card)
{
window.openDialog("chrome://messenger/content/addressbook/abEditCardDialog.xul",
"", "chrome,resizable=no,modal,titlebar,centerscreen",
{ abURI: aEmailAddressNode.cardDetails.book.URI,
card: aEmailAddressNode.cardDetails.card });
}
}
/**
* SendMailToNode takes the email address title button, extracts the email address
* we stored in there and opens a compose window with that address.
*
* @param addressNode a node which has a "fullAddress" attribute
* @param aEvent the event object when user triggers the menuitem
*/
function SendMailToNode(emailAddressNode, aEvent)
{
if (emailAddressNode)
SendMailTo(emailAddressNode.getAttribute("fullAddress"), aEvent);
}
function SendMailTo(fullAddress, aEvent)
{
var fields = Components.classes["@mozilla.org/messengercompose/composefields;1"].createInstance(Components.interfaces.nsIMsgCompFields);
var params = Components.classes["@mozilla.org/messengercompose/composeparams;1"].createInstance(Components.interfaces.nsIMsgComposeParams);
if (fields && params)
{
fields.to = fullAddress;
params.type = Components.interfaces.nsIMsgCompType.New;
// If aEvent is passed, check if Shift key was pressed for composition in
// non-default format (HTML vs. plaintext).
params.format = (aEvent && aEvent.shiftKey) ?
Components.interfaces.nsIMsgCompFormat.OppositeOfDefault :
Components.interfaces.nsIMsgCompFormat.Default;
params.identity = accountManager.getFirstIdentityForServer(GetLoadedMsgFolder().server);
params.composeFields = fields;
msgComposeService.OpenComposeWindowWithParams(null, params);
}
}
// CopyEmailAddress takes the email address title button, extracts
// the email address we stored in there and copies it to the clipboard
function CopyEmailAddress(emailAddressNode)
{
if (emailAddressNode)
CopyString(emailAddressNode.getAttribute("emailAddress"));
}
// show the message id in the context menu
function FillMessageIdContextMenu(messageIdNode)
{
var msgId = messageIdNode.getAttribute("messageid");
document.getElementById("messageIdContext-messageIdTarget")
.setAttribute("label", msgId);
// We don't want to show "Open Message For ID" for the same message
// we're viewing.
var currentMsgId = "<" + gFolderDisplay.selectedMessage.messageId + ">";
document.getElementById("messageIdContext-openMessageForMsgId")
.hidden = (currentMsgId == msgId);
// We don't want to show "Open Browser With Message-ID" for non-nntp messages.
document.getElementById("messageIdContext-openBrowserWithMsgId")
.hidden = !gFolderDisplay.selectedMessageIsNews;
}
function GetMessageIdFromNode(messageIdNode, cleanMessageId)
{
var messageId = messageIdNode.getAttribute("messageid");
// remove < and >
if (cleanMessageId)
messageId = messageId.substring(1, messageId.length - 1);
return messageId;
}
// take the message id from the messageIdNode and use the
// url defined in the hidden pref "mailnews.messageid_browser.url"
// to open it in a browser window (%mid is replaced by the message id)
function OpenBrowserWithMessageId(messageId)
{
var browserURL = GetLocalizedStringPref("mailnews.messageid_browser.url");
if (browserURL)
openAsExternal(browserURL.replace(/%mid/, messageId));
}
// take the message id from the messageIdNode, search for the
// corresponding message in all folders starting with the current
// selected folder, then the current account followed by the other
// accounts and open corresponding message if found
function OpenMessageForMessageId(messageId)
{
var startServer = msgWindow.openFolder.server;
var messageHeader;
window.setCursor("wait");
// first search in current folder for message id
var messageHeader = CheckForMessageIdInFolder(msgWindow.openFolder, messageId);
// if message id not found in current folder search in all folders
if (!messageHeader)
{
var accountManager = Components.classes["@mozilla.org/messenger/account-manager;1"]
.getService(Components.interfaces.nsIMsgAccountManager);
var allServers = accountManager.allServers;
messageHeader = SearchForMessageIdInSubFolder(startServer.rootFolder, messageId);
for (var i = 0; i < allServers.length && !messageHeader; i++)
{
var currentServer =
allServers.queryElementAt(i, Components.interfaces.nsIMsgIncomingServer);
if (currentServer && startServer != currentServer &&
currentServer.canSearchMessages && !currentServer.isDeferredTo)
{
messageHeader = SearchForMessageIdInSubFolder(currentServer.rootFolder, messageId);
}
}
}
window.setCursor("auto");
// if message id was found open corresponding message
// else show error message
if (messageHeader)
OpenMessageByHeader(messageHeader, Services.prefs.getBoolPref("mailnews.messageid.openInNewWindow"));
else
{
var messageIdStr = "<" + messageId + ">";
var errorTitle = gMessengerBundle.getString("errorOpenMessageForMessageIdTitle");
var errorMessage = gMessengerBundle.getFormattedString("errorOpenMessageForMessageIdMessage",
[messageIdStr]);
Services.prompt.alert(window, errorTitle, errorMessage);
}
}
function OpenMessageByHeader(messageHeader, openInNewWindow)
{
var folder = messageHeader.folder;
var folderURI = folder.URI;
if (openInNewWindow)
{
var messageURI = folder.getUriForMsg(messageHeader);
window.openDialog("chrome://messenger/content/messageWindow.xul",
"_blank", "all,chrome,dialog=no,status,toolbar",
messageURI, folderURI, null);
}
else
{
if (msgWindow.openFolder != folderURI)
SelectFolder(folderURI);
var tree = null;
var wintype = document.documentElement.getAttribute('windowtype');
if (wintype != "mail:messageWindow")
{
tree = GetThreadTree();
tree.view.selection.clearSelection();
}
try
{
gDBView.selectMsgByKey(messageHeader.messageKey);
}
catch(e)
{ // message not in the thread pane
try
{
goDoCommand("cmd_viewAllMsgs");
gDBView.selectMsgByKey(messageHeader.messageKey);
}
catch(e)
{
dump("select messagekey " + messageHeader.messageKey +
" failed in folder " + folder.URI);
}
}
if (tree && tree.currentIndex != -1)
tree.treeBoxObject.ensureRowIsVisible(tree.currentIndex);
}
}
// search for message by message id in given folder and its subfolders
// return message header if message was found
function SearchForMessageIdInSubFolder(folder, messageId)
{
var messageHeader;
var subFolders = folder.subFolders;
// search in folder
if (!folder.isServer)
messageHeader = CheckForMessageIdInFolder(folder, messageId);
// search subfolders recursively
while (subFolders.hasMoreElements() && !messageHeader)
{
// search in current folder
var currentFolder =
subFolders.getNext().QueryInterface(Components.interfaces.nsIMsgFolder);
messageHeader = CheckForMessageIdInFolder(currentFolder, messageId);
// search in its subfolder
if (!messageHeader && currentFolder.hasSubFolders)
messageHeader = SearchForMessageIdInSubFolder(currentFolder, messageId);
}
return messageHeader;
}
// check folder for corresponding message to given message id
// return message header if message was found
function CheckForMessageIdInFolder(folder, messageId)
{
var messageDatabase = folder.msgDatabase;
var messageHeader;
try
{
messageHeader = messageDatabase.getMsgHdrForMessageID(messageId);
}
catch (ex)
{
dump("Failed to find message-id in folder!");
}
if (!gMailSession)
{
gMailSession = Components.classes["@mozilla.org/messenger/services/session;1"]
.getService(Components.interfaces.nsIMsgMailSession);
}
const nsMsgFolderFlags = Components.interfaces.nsMsgFolderFlags;
if (!gMailSession.IsFolderOpenInWindow(folder) &&
!(folder.flags & (nsMsgFolderFlags.Trash | nsMsgFolderFlags.Inbox)))
{
folder.msgDatabase = null;
}
return messageHeader;
}
// CreateFilter opens the Message Filters and Filter Rules dialogs.
//The Filter Rules dialog has focus. The window is prefilled with filtername <email address>
//Sender condition is selected and the value is prefilled <email address>
function CreateFilter(emailAddressNode)
{
if (emailAddressNode)
CreateFilterFromMail(emailAddressNode.getAttribute("emailAddress"));
}
function CreateFilterFromMail(emailAddress)
{
if (emailAddress)
top.MsgFilters(emailAddress, GetFirstSelectedMsgFolder());
}
function CopyMessageUrl()
{
try
{
var hdr = gDBView.hdrForFirstSelectedMessage;
var server = hdr.folder.server;
// TODO let backend construct URL and return as attribute
var url = (server.socketType == Components.interfaces.nsMsgSocketType.SSL) ?
"snews://" : "news://";
url += server.hostName + ":" + server.port + "/" + hdr.messageId;
CopyString(url);
}
catch (ex)
{
dump("ex="+ex+"\n");
}
}
function CopyString(aString)
{
Components.classes["@mozilla.org/widget/clipboardhelper;1"]
.getService(Components.interfaces.nsIClipboardHelper)
.copyString(aString, document);
}