From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mail/components/addrbook/content/abCommon.js | 145 + .../components/addrbook/content/abContactsPanel.js | 374 ++ .../addrbook/content/abContactsPanel.xhtml | 234 ++ .../addrbook/content/abEditListDialog.xhtml | 99 + .../addrbook/content/abMailListDialog.xhtml | 116 + .../components/addrbook/content/abSearchDialog.js | 408 ++ .../addrbook/content/abSearchDialog.xhtml | 200 + .../mail/components/addrbook/content/abView-new.js | 577 +++ .../addrbook/content/aboutAddressBook.js | 4445 ++++++++++++++++++++ .../addrbook/content/aboutAddressBook.xhtml | 460 ++ .../components/addrbook/content/addressBookTab.js | 172 + .../addrbook/content/menulist-addrbooks.js | 271 ++ .../components/addrbook/content/vcard-edit/adr.mjs | 149 + .../addrbook/content/vcard-edit/custom.mjs | 60 + .../addrbook/content/vcard-edit/edit.mjs | 1094 +++++ .../addrbook/content/vcard-edit/email.mjs | 135 + .../components/addrbook/content/vcard-edit/fn.mjs | 71 + .../addrbook/content/vcard-edit/id-gen.mjs | 12 + .../addrbook/content/vcard-edit/impp.mjs | 97 + .../components/addrbook/content/vcard-edit/n.mjs | 186 + .../addrbook/content/vcard-edit/nickname.mjs | 59 + .../addrbook/content/vcard-edit/note.mjs | 82 + .../components/addrbook/content/vcard-edit/org.mjs | 197 + .../addrbook/content/vcard-edit/special-date.mjs | 269 ++ .../components/addrbook/content/vcard-edit/tel.mjs | 83 + .../components/addrbook/content/vcard-edit/tz.mjs | 86 + .../components/addrbook/content/vcard-edit/url.mjs | 89 + .../content/vcard-edit/vCardTemplates.inc.xhtml | 398 ++ 28 files changed, 10568 insertions(+) create mode 100644 comm/mail/components/addrbook/content/abCommon.js create mode 100644 comm/mail/components/addrbook/content/abContactsPanel.js create mode 100644 comm/mail/components/addrbook/content/abContactsPanel.xhtml create mode 100644 comm/mail/components/addrbook/content/abEditListDialog.xhtml create mode 100644 comm/mail/components/addrbook/content/abMailListDialog.xhtml create mode 100644 comm/mail/components/addrbook/content/abSearchDialog.js create mode 100644 comm/mail/components/addrbook/content/abSearchDialog.xhtml create mode 100644 comm/mail/components/addrbook/content/abView-new.js create mode 100644 comm/mail/components/addrbook/content/aboutAddressBook.js create mode 100644 comm/mail/components/addrbook/content/aboutAddressBook.xhtml create mode 100644 comm/mail/components/addrbook/content/addressBookTab.js create mode 100644 comm/mail/components/addrbook/content/menulist-addrbooks.js create mode 100644 comm/mail/components/addrbook/content/vcard-edit/adr.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/custom.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/edit.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/email.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/fn.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/id-gen.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/impp.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/n.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/nickname.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/note.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/org.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/special-date.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/tel.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/tz.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/url.mjs create mode 100644 comm/mail/components/addrbook/content/vcard-edit/vCardTemplates.inc.xhtml (limited to 'comm/mail/components/addrbook/content') diff --git a/comm/mail/components/addrbook/content/abCommon.js b/comm/mail/components/addrbook/content/abCommon.js new file mode 100644 index 0000000000..36f251206e --- /dev/null +++ b/comm/mail/components/addrbook/content/abCommon.js @@ -0,0 +1,145 @@ +/* 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/. */ + +/* import-globals-from ../../../../mailnews/addrbook/content/abResultsPane.js */ + +var { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); + +var gAbView = null; + +var kDefaultAscending = "ascending"; +var kDefaultDescending = "descending"; +var kAllDirectoryRoot = "moz-abdirectory://"; +var kPersonalAddressbookURI = "jsaddrbook://abook.sqlite"; + +async function AbDelete() { + let types = GetSelectedCardTypes(); + if (types == kNothingSelected) { + return; + } + + let cards = GetSelectedAbCards(); + + // Determine strings for smart and context-sensitive user prompts + // for confirming deletion. + let action, name, list; + let selectedDir = gAbView.directory; + + switch (types) { + case kListsAndCards: + action = "delete-mixed"; + break; + case kSingleListOnly: + case kMultipleListsOnly: + action = "delete-lists"; + name = cards[0].displayName; + break; + default: { + let nameFormatFromPref = Services.prefs.getIntPref( + "mail.addr_book.lastnamefirst" + ); + name = cards[0].generateName(nameFormatFromPref); + if (selectedDir && selectedDir.isMailList) { + action = "remove-contacts"; + list = selectedDir.dirName; + } else { + action = "delete-contacts"; + } + break; + } + } + + // Adjust strings to match translations. + let actionString; + switch (action) { + case "delete-contacts": + actionString = !cards.length + ? "delete-contacts-single" + : "delete-contacts-multi"; + break; + case "remove-contacts": + actionString = !cards.length + ? "remove-contacts-single" + : "remove-contacts-multi"; + break; + default: + actionString = action; + break; + } + + let [title, message] = await document.l10n.formatValues([ + { + id: `about-addressbook-confirm-${action}-title`, + args: { count: cards.length }, + }, + { + id: `about-addressbook-confirm-${actionString}`, + args: { + count: cards.length, + name, + list, + }, + }, + ]); + + // Finally, show our smart confirmation message, and act upon it! + if (!Services.prompt.confirm(window, title, message)) { + // Deletion cancelled by user. + return; + } + + // Delete cards from address books or mailing lists. + gAbView.deleteSelectedCards(); +} + +function AbNewMessage(address) { + let params = Cc[ + "@mozilla.org/messengercompose/composeparams;1" + ].createInstance(Ci.nsIMsgComposeParams); + params.type = Ci.nsIMsgCompType.New; + params.format = Ci.nsIMsgCompFormat.Default; + params.composeFields = Cc[ + "@mozilla.org/messengercompose/composefields;1" + ].createInstance(Ci.nsIMsgCompFields); + + if (address) { + params.composeFields.to = address; + } else { + params.composeFields.to = GetSelectedAddresses(); + } + MailServices.compose.OpenComposeWindowWithParams(null, params); +} + +/** + * Make a mailbox string from the card, for use in the UI. + * + * @param {nsIAbCard} - The card to use. + * @returns {string} A mailbox representation of the card. + */ +function makeMailboxObjectFromCard(card) { + if (!card) { + return ""; + } + + let email; + if (card.isMailList) { + let directory = GetDirectoryFromURI(card.mailListURI); + email = directory.description || card.displayName; + } else { + email = card.primaryEmail; + } + + return MailServices.headerParser + .makeMailboxObject(card.displayName, email) + .toString(); +} + +function GetDirectoryFromURI(uri) { + if (uri.startsWith("moz-abdirectory://")) { + return null; + } + return MailServices.ab.getDirectory(uri); +} diff --git a/comm/mail/components/addrbook/content/abContactsPanel.js b/comm/mail/components/addrbook/content/abContactsPanel.js new file mode 100644 index 0000000000..c1e3481318 --- /dev/null +++ b/comm/mail/components/addrbook/content/abContactsPanel.js @@ -0,0 +1,374 @@ +/* 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/. */ + +/* import-globals-from ../../../../../toolkit/content/editMenuOverlay.js */ +/* import-globals-from ../../../../mailnews/addrbook/content/abResultsPane.js */ +/* import-globals-from ../../../base/content/globalOverlay.js */ +/* import-globals-from abCommon.js */ + +var { UIDensity } = ChromeUtils.import("resource:///modules/UIDensity.jsm"); +var { getSearchTokens, getModelQuery, generateQueryURI } = ChromeUtils.import( + "resource:///modules/ABQueryUtils.jsm" +); + +// A boolean variable determining whether AB column should be shown +// in Contacts Sidebar in compose window. +var gShowAbColumnInComposeSidebar = false; +var gQueryURIFormat = null; + +UIDensity.registerWindow(window); + +function GetAbViewListener() { + // the ab panel doesn't care if the total changes, or if the selection changes + return null; +} + +/** + * Handle the command event on abContextMenuButton (click, Enter, spacebar). + */ +function abContextMenuButtonOnCommand(event) { + showContextMenu("sidebarAbContextMenu", event, [ + event.target, + "after_end", + 0, + 0, + true, + ]); +} + +/** + * Handle the context menu event of results tree (right-click, context menu key + * press, etc.). Show the respective context menu for selected contact(s) or + * results tree blank space (work around for XUL tree bug 1331377). + * + * @param aEvent a context menu event (right-click, context menu key press, etc.) + */ +function contactsListOnContextMenu(aEvent) { + let target = aEvent.target; + let contextMenuID; + let positionArray; + + // For right-click on column header or column picker, don't show context menu. + if (target.localName == "treecol" || target.localName == "treecolpicker") { + return; + } + + // On treechildren, if there's no selection, show "sidebarAbContextMenu". + if (gAbView.selection.count == 0) { + contextMenuID = gAbResultsTree.getAttribute("contextNoSelection"); + // If "sidebarAbContextMenu" menu was activated by keyboard, + // position it in the topleft corner of gAbResultsTree. + if (!aEvent.button) { + positionArray = [gAbResultsTree, "overlap", 0, 0, true]; + } + // If there's a selection, show "cardProperties" context menu. + } else { + contextMenuID = gAbResultsTree.getAttribute("contextSelection"); + updateCardPropertiesMenu(); + } + showContextMenu(contextMenuID, aEvent, positionArray); +} + +/** + * Update the single row card properties context menu to show or hide the "Edit" + * menu item only depending on the selection type. + */ +function updateCardPropertiesMenu() { + let cards = GetSelectedAbCards(); + + let separator = document.getElementById("abContextBeforeEditContact"); + let menuitem = document.getElementById("abContextEditContact"); + + // Only show the Edit item if one item is selected, is not a mailing list, and + // the contact is not part of a readOnly address book. + if ( + cards.length != 1 || + cards.some(c => c.isMailList) || + MailServices.ab.getDirectoryFromUID(cards[0].directoryUID)?.readOnly + ) { + separator.hidden = true; + menuitem.hidden = true; + return; + } + + separator.hidden = false; + menuitem.hidden = false; +} + +/** + * Handle the click event of the results tree (workaround for XUL tree + * bug 1331377). + * + * @param aEvent a click event + */ +function contactsListOnClick(aEvent) { + CommandUpdate_AddressBook(); + + let target = aEvent.target; + + // Left click on column header: Change sort direction. + if (target.localName == "treecol" && aEvent.button == 0) { + let sortDirection = + target.getAttribute("sortDirection") == kDefaultDescending + ? kDefaultAscending + : kDefaultDescending; + SortAndUpdateIndicators(target.id, sortDirection); + return; + } + // Any click on gAbResultsTree view (rows or blank space). + if (target.localName == "treechildren") { + let row = gAbResultsTree.getRowAt(aEvent.clientX, aEvent.clientY); + if (row < 0 || row >= gAbResultsTree.view.rowCount) { + // Any click on results tree whitespace. + if ((aEvent.detail == 1 && aEvent.button == 0) || aEvent.button == 2) { + // Single left click or any right click on results tree blank space: + // Clear selection. This also triggers on the first click of any + // double-click, but that's ok. MAC OS X doesn't return event.detail==1 + // for single right click, so we also let this trigger for the second + // click of right double-click. + gAbView.selection.clearSelection(); + } + } else if (aEvent.button == 0 && aEvent.detail == 2) { + // Any click on results tree rows. + // Double-click on a row: Go ahead and add the entry. + addSelectedAddresses("addr_to"); + } + } +} + +/** + * Appends the currently selected cards as new recipients in the composed message. + * + * @param recipientType Type of recipient, e.g. "addr_to". + */ +function addSelectedAddresses(recipientType) { + var cards = GetSelectedAbCards(); + + // Turn each card into a properly formatted address. + let addresses = cards.map(makeMailboxObjectFromCard).filter(addr => addr); + parent.addressRowAddRecipientsArray( + parent.document.querySelector( + `.address-row[data-recipienttype="${recipientType}"]` + ), + addresses + ); +} + +/** + * Open the address book tab and trigger the edit of the selected contact. + */ +function editSelectedAddress() { + let cards = GetSelectedAbCards(); + window.top.toAddressBook({ action: "edit", card: cards[0] }); +} + +function AddressBookMenuListChange(aValue) { + let searchInput = document.getElementById("peopleSearchInput"); + if (searchInput.value && !searchInput.showingSearchCriteria) { + onEnterInSearchBar(); + } else { + ChangeDirectoryByURI(aValue); + } + + // Hide the addressbook column if the selected addressbook isn't + // "All address books". Since the column is redundant in all other cases. + let abList = document.getElementById("addressbookList"); + let addrbookColumn = document.getElementById("addrbook"); + if (abList.value.startsWith(kAllDirectoryRoot + "?")) { + addrbookColumn.hidden = !gShowAbColumnInComposeSidebar; + addrbookColumn.removeAttribute("ignoreincolumnpicker"); + } else { + addrbookColumn.hidden = true; + addrbookColumn.setAttribute("ignoreincolumnpicker", "true"); + } + + CommandUpdate_AddressBook(); +} + +var mutationObs = null; + +function AbPanelLoad() { + if (location.search == "?focus") { + document.getElementById("peopleSearchInput").focus(); + } + + document.title = parent.document.getElementById("contactsTitle").value; + + // Get the URI of the directory to display. + let startupURI = Services.prefs.getCharPref("mail.addr_book.view.startupURI"); + // If the URI is a mailing list, use the parent directory instead, since + // mailing lists are not displayed here. + startupURI = startupURI.replace(/^(jsaddrbook:\/\/[\w\.-]*)\/.*$/, "$1"); + + let abPopup = document.getElementById("addressbookList"); + abPopup.value = startupURI; + + // If provided directory is not on abPopup, fall back to All Address Books. + if (!abPopup.selectedItem) { + abPopup.selectedIndex = 0; + } + + // Postpone the slow contacts load so that the sidebar document + // gets a chance to display quickly. + setTimeout(ChangeDirectoryByURI, 0, abPopup.value); + + mutationObs = new MutationObserver(function (aMutations) { + aMutations.forEach(function (mutation) { + if ( + getSelectedDirectoryURI() == kAllDirectoryRoot + "?" && + mutation.type == "attributes" && + mutation.attributeName == "hidden" + ) { + let curState = document.getElementById("addrbook").hidden; + gShowAbColumnInComposeSidebar = !curState; + } + }); + }); + + document.getElementById("addrbook").hidden = !gShowAbColumnInComposeSidebar; + + mutationObs.observe(document.getElementById("addrbook"), { + attributes: true, + childList: true, + }); +} + +function AbPanelUnload() { + mutationObs.disconnect(); + + // If there's no default startupURI, save the last used URI as new startupURI. + if (!Services.prefs.getBoolPref("mail.addr_book.view.startupURIisDefault")) { + Services.prefs.setCharPref( + "mail.addr_book.view.startupURI", + getSelectedDirectoryURI() + ); + } + + CloseAbView(); +} + +function AbResultsPaneDoubleClick(card) { + // double click for ab panel means "send mail to this person / list" + AbNewMessage(); +} + +function CommandUpdate_AddressBook() { + // Toggle disable state of to,cc,bcc buttons. + let disabled = GetNumSelectedCards() == 0 ? "true" : "false"; + document.getElementById("cmd_addrTo").setAttribute("disabled", disabled); + document.getElementById("cmd_addrCc").setAttribute("disabled", disabled); + document.getElementById("cmd_addrBcc").setAttribute("disabled", disabled); + + goUpdateCommand("cmd_delete"); +} + +/** + * Handle the onpopupshowing event of #sidebarAbContextMenu. + * Update the checkmark of #sidebarAbContext-startupDir menuitem when context + * menu opens, so as to always be in sync with changes from the main AB window. + */ +function onAbContextShowing() { + let startupItem = document.getElementById("sidebarAbContext-startupDir"); + if (Services.prefs.getBoolPref("mail.addr_book.view.startupURIisDefault")) { + let startupURI = Services.prefs.getCharPref( + "mail.addr_book.view.startupURI" + ); + startupItem.setAttribute( + "checked", + startupURI == getSelectedDirectoryURI() + ); + } else { + startupItem.setAttribute("checked", "false"); + } +} + +function onEnterInSearchBar() { + if (!gQueryURIFormat) { + // Get model query from pref. We don't want the query starting with "?" + // as we have to prefix "?and" to this format. + /* eslint-disable no-global-assign */ + gQueryURIFormat = getModelQuery("mail.addr_book.quicksearchquery.format"); + /* eslint-enable no-global-assign */ + } + + let searchURI = getSelectedDirectoryURI(); + let searchQuery; + let searchInput = document.getElementById("peopleSearchInput"); + + // Use helper method to split up search query to multi-word search + // query against multiple fields. + if (searchInput) { + let searchWords = getSearchTokens(searchInput.value); + searchQuery = generateQueryURI(gQueryURIFormat, searchWords); + } + + SetAbView(searchURI, searchQuery, searchInput ? searchInput.value : ""); +} + +/** + * Open a menupopup as a context menu + * + * @param aContextMenuID The ID of a menupopup to be shown as context menu + * @param aEvent The event which triggered this. + * @param positionArray An optional array containing the parameters for openPopup() method; + * if omitted, mouse pointer position will be used. + */ +function showContextMenu(aContextMenuID, aEvent, aPositionArray) { + let theContextMenu = document.getElementById(aContextMenuID); + if (!aPositionArray) { + aPositionArray = [null, "", aEvent.clientX, aEvent.clientY, true]; + } + theContextMenu.openPopup(...aPositionArray); +} + +/** + * Get the URI of the selected directory. + * + * @returns The URI of the currently selected directory + */ +function getSelectedDirectoryURI() { + return document.getElementById("addressbookList").value; +} + +function abToggleSelectedDirStartup() { + let selectedDirURI = getSelectedDirectoryURI(); + if (!selectedDirURI) { + return; + } + + let isDefault = Services.prefs.getBoolPref( + "mail.addr_book.view.startupURIisDefault" + ); + let startupURI = Services.prefs.getCharPref("mail.addr_book.view.startupURI"); + + if (isDefault && startupURI == selectedDirURI) { + // The current directory has been the default startup view directory; + // toggle that off now. So there's no default startup view directory any more. + Services.prefs.setBoolPref( + "mail.addr_book.view.startupURIisDefault", + false + ); + } else { + // The current directory will now be the default view + // when starting up the main AB window. + Services.prefs.setCharPref( + "mail.addr_book.view.startupURI", + selectedDirURI + ); + Services.prefs.setBoolPref("mail.addr_book.view.startupURIisDefault", true); + } + + // Update the checkbox in the menuitem. + goUpdateCommand("cmd_abToggleStartupDir"); +} + +function ChangeDirectoryByURI(uri = kPersonalAddressbookURI) { + SetAbView(uri); + + // Actively de-selecting if there are any pre-existing selections + // in the results list. + if (gAbView && gAbView.selection && gAbView.getCardFromRow(0)) { + gAbView.selection.clearSelection(); + } +} diff --git a/comm/mail/components/addrbook/content/abContactsPanel.xhtml b/comm/mail/components/addrbook/content/abContactsPanel.xhtml new file mode 100644 index 0000000000..18163eafda --- /dev/null +++ b/comm/mail/components/addrbook/content/abContactsPanel.xhtml @@ -0,0 +1,234 @@ + + + + + + + + + + + +%abResultsPaneDTD; + +%abContactsPanelDTD; + +%abMainWindowDTD; ]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
    +
  • +
    +
    +
    + +
    +
    +
  • +
+
+ + +
+
+
+
+ + +
+ + + + + + + + + + +
+ +
+ +
+ + +
+ + + + + + + + + + + +
+ + + + + + +
+ + +