diff options
Diffstat (limited to '')
-rw-r--r-- | comm/mail/modules/DisplayNameUtils.jsm | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/comm/mail/modules/DisplayNameUtils.jsm b/comm/mail/modules/DisplayNameUtils.jsm new file mode 100644 index 0000000000..bee32796fd --- /dev/null +++ b/comm/mail/modules/DisplayNameUtils.jsm @@ -0,0 +1,130 @@ +/* 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/. */ + +const EXPORTED_SYMBOLS = ["DisplayNameUtils"]; + +const { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); + +var DisplayNameUtils = { + formatDisplayName, + formatDisplayNameList, +}; + +// XXX: Maybe the strings for this file should go in a separate bundle? +var gMessengerBundle = Services.strings.createBundle( + "chrome://messenger/locale/messenger.properties" +); + +function _getIdentityForAddress(aEmailAddress) { + let emailAddress = aEmailAddress.toLowerCase(); + for (let identity of MailServices.accounts.allIdentities) { + if (!identity.email) { + continue; + } + if (emailAddress == identity.email.toLowerCase()) { + return identity; + } + } + return null; +} + +/** + * Take an email address and compose a sensible display name based on the + * header display name and/or the display name from the address book. If no + * appropriate name can be made (e.g. there is no card for this address), + * returns |null|. + * + * @param {string} emailAddress - The email address to format. + * @param {string} headerDisplayName - The display name from the header, if any. + * @param {string} context - The field being formatted (e.g. "to", "from"). + * @returns The formatted display name, or null. + */ +function formatDisplayName(emailAddress, headerDisplayName, context) { + let displayName = null; + let identity = _getIdentityForAddress(emailAddress); + let card = MailServices.ab.cardForEmailAddress(emailAddress); + + // If this address is one of the user's identities... + if (identity) { + if ( + MailServices.accounts.allIdentities.length == 1 && + (!headerDisplayName || identity.fullName == headerDisplayName) + ) { + // ...pick a localized version of the word "Me" appropriate to this + // specific header; fall back to the version used by the "to" header + // if nothing else is available. + try { + displayName = gMessengerBundle.GetStringFromName( + `header${context}FieldMe` + ); + } catch (e) { + displayName = gMessengerBundle.GetStringFromName("headertoFieldMe"); + } + } else { + // Use the full address. It's not the expected name, maybe a customized + // one the user sent, or one the sender got wrong, or we have multiple + // identities making the "Me" short string ambiguous. + displayName = MailServices.headerParser + .makeMailboxObject(headerDisplayName, emailAddress) + .toString(); + } + } + + // If we don't have a card, refuse to generate a display name. Places calling + // this are then responsible for falling back to something else (e.g. the + // value from the message header). + if (card) { + // getProperty may return a "1" or "0" string, we want a boolean + if (card.getProperty("PreferDisplayName", "1") == "1") { + displayName = card.displayName || null; + } + + // Note: headerDisplayName is not used as a fallback as confusion could be + // caused by a collected address using an e-mail address as display name. + } + + return displayName; +} + +/** + * Format the display name from a list of addresses. First, try using + * formatDisplayName, then fall back to the header's display name or the + * address. + * + * @param aHeaderValue The decoded header value (e.g. mime2DecodedAuthor). + * @param aContext The context of the header field (e.g. "to", "from"). + * @returns The formatted display name. + */ +function formatDisplayNameList(aHeaderValue, aContext) { + let addresses = MailServices.headerParser.parseDecodedHeader(aHeaderValue); + if (addresses.length > 0) { + let displayName = formatDisplayName( + addresses[0].email, + addresses[0].name, + aContext + ); + let andOthersStr = ""; + if (addresses.length > 1) { + andOthersStr = " " + gMessengerBundle.GetStringFromName("andOthers"); + } + + if (displayName) { + return displayName + andOthersStr; + } + + // Construct default display. + if (addresses[0].email) { + return ( + MailServices.headerParser + .makeMailboxObject(addresses[0].name, addresses[0].email) + .toString() + andOthersStr + ); + } + } + + // Something strange happened, just return the raw header value. + return aHeaderValue; +} |