Bug 1609647 - Add 'Move to To/Cc/Bcc' to recipient pill context menu. r=mkmelin
This commit is contained in:
Родитель
0f670b6839
Коммит
0679539d04
|
@ -2199,6 +2199,7 @@
|
|||
* @param {HTMLElement} element - The original autocomplete input that
|
||||
* generated the pill.
|
||||
* @param {Array} address - The array containing the recipient's info.
|
||||
* @return {Element} The newly created pill.
|
||||
*/
|
||||
createRecipientPill(element, address) {
|
||||
let pill = document.createXULElement("mail-address-pill");
|
||||
|
@ -2243,6 +2244,14 @@
|
|||
this.handleKeyPress(pill, event);
|
||||
});
|
||||
|
||||
pill.addEventListener("contextmenu", event => {
|
||||
// Update the context menu options only if opened via the context menu
|
||||
// keyboard button.
|
||||
if (event.buttons == 0) {
|
||||
emailAddressPillOnPopupShown();
|
||||
}
|
||||
});
|
||||
|
||||
element.closest(".address-container").insertBefore(pill, element);
|
||||
|
||||
// The emailInput attribute is accessible only after the pill has been
|
||||
|
@ -2267,6 +2276,8 @@
|
|||
"autocompletesearchparam",
|
||||
JSON.stringify(params)
|
||||
);
|
||||
|
||||
return pill;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2386,10 +2397,12 @@
|
|||
* @param {Event} event - The DOM Event.
|
||||
*/
|
||||
checkSelected(pill, event) {
|
||||
if (
|
||||
pill.isEditing ||
|
||||
(pill.hasAttribute("selected") && event.which == 3)
|
||||
) {
|
||||
if (pill.isEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pill.hasAttribute("selected") && event.button == 2) {
|
||||
emailAddressPillOnPopupShown();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2403,6 +2416,12 @@
|
|||
} else {
|
||||
pill.focus();
|
||||
}
|
||||
|
||||
// Update the options in the context menu only after the pills were
|
||||
// selected and if the event was a right click.
|
||||
if (event.button == 2) {
|
||||
emailAddressPillOnPopupShown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2450,6 +2469,33 @@
|
|||
pill.startEditing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the selected pills email address to another addressing row.
|
||||
*
|
||||
* @param {Element} element - The element from which the context menu was
|
||||
* opened.
|
||||
* @param {string} targetFieldType - The target recipient type,
|
||||
* e.g. "addr_to".
|
||||
*/
|
||||
moveSelectedPills(element, targetFieldType) {
|
||||
// Store all the selected addresses inside an array.
|
||||
let selectedAddresses = [...this.getAllSelectedPills()].map(
|
||||
pill => pill.fullAddress
|
||||
);
|
||||
|
||||
// Remove all the selected pills.
|
||||
let pill = element.closest("mail-address-pill");
|
||||
this.removeSelectedPills(pill);
|
||||
|
||||
// Create new addressing pills inside the target recipient row and maintain
|
||||
// the current selection.
|
||||
awAddRecipientsArray(targetFieldType, selectedAddresses, true);
|
||||
|
||||
// Move focus to the last selected pill.
|
||||
let selectedPills = this.getAllSelectedPills();
|
||||
selectedPills[selectedPills.length - 1].focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all selected pills and handle focus and selection smartly as needed.
|
||||
*
|
||||
|
|
|
@ -378,8 +378,9 @@ function awAddRecipients(msgCompFields, recipientType, recipientsList) {
|
|||
*
|
||||
* @param aRecipientType Type of recipient, e.g. "addr_to".
|
||||
* @param aAddressArray An array of recipient addresses (strings) to add.
|
||||
* @param {boolean} select - If the newly generated pills should be selected.
|
||||
*/
|
||||
function awAddRecipientsArray(aRecipientType, aAddressArray) {
|
||||
function awAddRecipientsArray(aRecipientType, aAddressArray, select = false) {
|
||||
let label = document.getElementById(aRecipientType);
|
||||
let addresses = MailServices.headerParser.makeFromDisplayAddress(
|
||||
aAddressArray
|
||||
|
@ -392,7 +393,10 @@ function awAddRecipientsArray(aRecipientType, aAddressArray) {
|
|||
|
||||
let recipientArea = document.getElementById("recipientsContainer");
|
||||
for (let address of addresses) {
|
||||
recipientArea.createRecipientPill(element, address);
|
||||
let pill = recipientArea.createRecipientPill(element, address);
|
||||
if (select) {
|
||||
pill.setAttribute("selected", "selected");
|
||||
}
|
||||
}
|
||||
|
||||
if (element.id != "replyAddrInput") {
|
||||
|
@ -701,17 +705,14 @@ function editAddressPill(element, event) {
|
|||
* opened.
|
||||
*/
|
||||
function copyEmailNewsAddress(element) {
|
||||
let allAddresses = [];
|
||||
for (let pill of document
|
||||
.getElementById("recipientsContainer")
|
||||
.getAllSelectedPills()) {
|
||||
allAddresses.push(pill.fullAddress);
|
||||
}
|
||||
let selectedAddresses = [
|
||||
...document.getElementById("recipientsContainer").getAllSelectedPills(),
|
||||
].map(pill => pill.fullAddress);
|
||||
|
||||
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
|
||||
Ci.nsIClipboardHelper
|
||||
);
|
||||
clipboard.copyString(allAddresses.join(", "));
|
||||
clipboard.copyString(selectedAddresses.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -722,21 +723,103 @@ function copyEmailNewsAddress(element) {
|
|||
*/
|
||||
function cutEmailNewsAddress(element) {
|
||||
copyEmailNewsAddress(element);
|
||||
deleteAddressPill(element);
|
||||
deleteSelectedPills(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the selected pill(s).
|
||||
*
|
||||
* @param {XULElement} element - The element from which the context menu was
|
||||
* @param {Element} element - The label element from which the context menu was
|
||||
* opened.
|
||||
*/
|
||||
function deleteAddressPill(element) {
|
||||
// element is the pill's <label>, get the pill.
|
||||
function deleteSelectedPills(element) {
|
||||
// element is the <label> of the focused pill, get the pill itself.
|
||||
let pill = element.closest("mail-address-pill");
|
||||
document.getElementById("recipientsContainer").removeSelectedPills(pill);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle disabling of "Move to..." context menu items according to the types
|
||||
* of selected pills.
|
||||
*/
|
||||
function emailAddressPillOnPopupShown() {
|
||||
let menu = document.getElementById("emailAddressPillPopup");
|
||||
|
||||
// Reset previously disabled menuitems.
|
||||
for (let menuitem of menu.querySelectorAll(
|
||||
".pill-action-move, .pill-action-edit"
|
||||
)) {
|
||||
menuitem.disabled = false;
|
||||
}
|
||||
|
||||
// If more than one pill is selected, disable the editing item.
|
||||
if (
|
||||
document.getElementById("recipientsContainer").getAllSelectedPills()
|
||||
.length > 1
|
||||
) {
|
||||
menu.querySelector("#editAddressPill").disabled = true;
|
||||
}
|
||||
|
||||
// If Newsgroups or Followups are part of the selection, disable everything.
|
||||
if (
|
||||
document.querySelectorAll(
|
||||
`mail-address-pill[recipienttype="addr_newsgroups"][selected]`
|
||||
).length ||
|
||||
document.querySelectorAll(
|
||||
`mail-address-pill[recipienttype="addr_followup"][selected]`
|
||||
).length
|
||||
) {
|
||||
for (let menuitem of menu.querySelectorAll(".pill-action-move")) {
|
||||
menuitem.disabled = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let selectedTypes = [];
|
||||
// Add all the recipient types of the selected pills.
|
||||
for (let row of document.querySelectorAll(".address-row:not(.hidden)")) {
|
||||
if (row.querySelectorAll("mail-address-pill[selected]").length) {
|
||||
selectedTypes.push(
|
||||
row
|
||||
.querySelector(`input[is="autocomplete-input"][recipienttype]`)
|
||||
.getAttribute("recipienttype")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt if more than one type is selected.
|
||||
if (selectedTypes.length > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (selectedTypes[0]) {
|
||||
case "addr_to":
|
||||
menu.querySelector("#moveAddressPillTo").disabled = true;
|
||||
break;
|
||||
|
||||
case "addr_cc":
|
||||
menu.querySelector("#moveAddressPillCc").disabled = true;
|
||||
break;
|
||||
|
||||
case "addr_bcc":
|
||||
menu.querySelector("#moveAddressPillBcc").disabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the selected pills email address to another addressing row.
|
||||
*
|
||||
* @param {Element} element - The element from which the context menu was
|
||||
* opened.
|
||||
* @param {string} targetFieldType - The target recipient type, e.g. "addr_to".
|
||||
*/
|
||||
function moveSelectedPills(element, targetFieldType) {
|
||||
document
|
||||
.getElementById("recipientsContainer")
|
||||
.moveSelectedPills(element, targetFieldType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the keypress event on the recipient labels for keyboard navigation and
|
||||
* to show the container row of a hidden recipient (Cc, Bcc, etc.).
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
<stringbundle id="charsetBundle" src="chrome://communicator/content/labelsencodings.properties"/>
|
||||
|
||||
<linkset>
|
||||
<html:link rel="localization" href="messenger/messengercompose/messengercompose.ftl"/>
|
||||
<html:link rel="localization" href="toolkit/main-window/findbar.ftl"/>
|
||||
<html:link rel="localization" href="toolkit/global/textActions.ftl"/>
|
||||
<html:link rel="localization" href="messenger/menubar.ftl"/>
|
||||
|
@ -770,18 +771,33 @@
|
|||
|
||||
|
||||
<menupopup id="emailAddressPillPopup" class="emailAddressPopup">
|
||||
<menuitem id="editAddressPill" label="&editMenu.label;"
|
||||
accesskey="&editMenu.accesskey;"
|
||||
<menuitem id="editAddressPill"
|
||||
class="pill-action-edit"
|
||||
data-l10n-id="pill-action-edit"
|
||||
oncommand="editAddressPill(document.popupNode, event)"/>
|
||||
<menuitem id="menu_delete"
|
||||
data-l10n-id="text-action-delete"
|
||||
oncommand="deleteSelectedPills(document.popupNode)"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_cut"
|
||||
data-l10n-id="text-action-cut"
|
||||
oncommand="cutEmailNewsAddress(document.popupNode)"/>
|
||||
<menuitem id="menu_copy"
|
||||
data-l10n-id="text-action-copy"
|
||||
oncommand="copyEmailNewsAddress(document.popupNode)"/>
|
||||
<menuitem id="menu_delete"
|
||||
data-l10n-id="text-action-delete"
|
||||
oncommand="deleteAddressPill(document.popupNode)"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="moveAddressPillTo"
|
||||
class="pill-action-move"
|
||||
data-l10n-id="pill-action-move-to"
|
||||
oncommand="moveSelectedPills(document.popupNode, 'addr_to')"/>
|
||||
<menuitem id="moveAddressPillCc"
|
||||
class="pill-action-move"
|
||||
data-l10n-id="pill-action-move-cc"
|
||||
oncommand="moveSelectedPills(document.popupNode, 'addr_cc')"/>
|
||||
<menuitem id="moveAddressPillBcc"
|
||||
class="pill-action-move"
|
||||
data-l10n-id="pill-action-move-bcc"
|
||||
oncommand="moveSelectedPills(document.popupNode, 'addr_bcc')"/>
|
||||
</menupopup>
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
|
|
@ -14,3 +14,19 @@ address-input-type = { $count ->
|
|||
[one] { $type } input field with one address
|
||||
*[other] { $type } input field with { $count } addresses
|
||||
}
|
||||
|
||||
pill-action-edit =
|
||||
.label = Edit Address
|
||||
.accesskey = e
|
||||
|
||||
pill-action-move-to =
|
||||
.label = Move to To
|
||||
.accesskey = t
|
||||
|
||||
pill-action-move-cc =
|
||||
.label = Move to Cc
|
||||
.accesskey = c
|
||||
|
||||
pill-action-move-bcc =
|
||||
.label = Move to Bcc
|
||||
.accesskey = b
|
||||
|
|
|
@ -524,6 +524,9 @@
|
|||
|
||||
.address-input {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.address-container > .address-input {
|
||||
padding-block: 4px;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче