mirror of
https://github.com/mjl-/mox.git
synced 2025-06-28 10:18:15 +03:00
webmail: when composing, no longer remove the last remaining To address with the ctrl+backspace shortcut
On reply, with too many Cc/Bcc, I usually hit ctrl+backspace a few time. I just want to clear the addresses, but I practically always still want a To address.
This commit is contained in:
parent
297e83188c
commit
70aedddc90
@ -2781,10 +2781,10 @@ const compose = (opts, listMailboxes) => {
|
|||||||
const cmdSendArchive = async () => {
|
const cmdSendArchive = async () => {
|
||||||
await withStatus('Sending email and archive', submit(true), fieldset);
|
await withStatus('Sending email and archive', submit(true), fieldset);
|
||||||
};
|
};
|
||||||
const cmdAddTo = async () => { newAddrView('', true, toViews, toBtn, toCell, toRow); };
|
const cmdAddTo = async () => { newAddrView('', true, true, toViews, toBtn, toCell, toRow); };
|
||||||
const cmdAddCc = async () => { newAddrView('', true, ccViews, ccBtn, ccCell, ccRow); };
|
const cmdAddCc = async () => { newAddrView('', true, false, ccViews, ccBtn, ccCell, ccRow); };
|
||||||
const cmdAddBcc = async () => { newAddrView('', true, bccViews, bccBtn, bccCell, bccRow); };
|
const cmdAddBcc = async () => { newAddrView('', true, false, bccViews, bccBtn, bccCell, bccRow); };
|
||||||
const cmdReplyTo = async () => { newAddrView('', false, replytoViews, replyToBtn, replyToCell, replyToRow, true); };
|
const cmdReplyTo = async () => { newAddrView('', false, false, replytoViews, replyToBtn, replyToCell, replyToRow, true); };
|
||||||
const cmdCustomFrom = async () => {
|
const cmdCustomFrom = async () => {
|
||||||
if (customFrom) {
|
if (customFrom) {
|
||||||
return;
|
return;
|
||||||
@ -2805,7 +2805,7 @@ const compose = (opts, listMailboxes) => {
|
|||||||
'ctrl S': cmdClose,
|
'ctrl S': cmdClose,
|
||||||
// ctrl Backspace and ctrl = (+) not included, they are handled by keydown handlers on in the inputs they remove/add.
|
// ctrl Backspace and ctrl = (+) not included, they are handled by keydown handlers on in the inputs they remove/add.
|
||||||
};
|
};
|
||||||
const newAddrView = (addr, isRecipient, views, btn, cell, row, single) => {
|
const newAddrView = (addr, isRecipient, isTo, views, btn, cell, row, single) => {
|
||||||
if (single && views.length !== 0) {
|
if (single && views.length !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2901,11 +2901,12 @@ const compose = (opts, listMailboxes) => {
|
|||||||
};
|
};
|
||||||
const recipientSecurityTitle = 'Description of security mechanisms recipient domains may implement:\n1. STARTTLS: Opportunistic (unverified) TLS with STARTTLS, successfully negotiated during the most recent delivery attempt.\n2. MTA-STS: For PKIX/WebPKI-verified TLS.\n3. DNSSEC: MX DNS records are DNSSEC-signed.\n4. DANE: First delivery destination host implements DANE for verified TLS.\n5. RequireTLS: SMTP extension for verified TLS delivery into recipient mailbox, support detected during the most recent delivery attempt.\n\nChecks STARTTLS, DANE and RequireTLS cover the most recently used delivery path, not necessarily all possible delivery paths.\n\nThe bars below the input field indicate implementation status by the recipient domain:\n- Red, not implemented/unsupported\n- Green, implemented/supported\n- Gray, error while determining\n- Absent/white, unknown or skipped (e.g. no previous delivery attempt, or DANE check skipped due to DNSSEC-lookup error)';
|
const recipientSecurityTitle = 'Description of security mechanisms recipient domains may implement:\n1. STARTTLS: Opportunistic (unverified) TLS with STARTTLS, successfully negotiated during the most recent delivery attempt.\n2. MTA-STS: For PKIX/WebPKI-verified TLS.\n3. DNSSEC: MX DNS records are DNSSEC-signed.\n4. DANE: First delivery destination host implements DANE for verified TLS.\n5. RequireTLS: SMTP extension for verified TLS delivery into recipient mailbox, support detected during the most recent delivery attempt.\n\nChecks STARTTLS, DANE and RequireTLS cover the most recently used delivery path, not necessarily all possible delivery paths.\n\nThe bars below the input field indicate implementation status by the recipient domain:\n- Red, not implemented/unsupported\n- Green, implemented/supported\n- Gray, error while determining\n- Absent/white, unknown or skipped (e.g. no previous delivery attempt, or DANE check skipped due to DNSSEC-lookup error)';
|
||||||
const root = dom.span(autosizeElem = dom.span(dom._class('autosize'), inputElem = dom.input(focusPlaceholder('Jane <jane@example.org>'), style({ width: 'auto' }), attr.value(addr), newAddressComplete(), accountSettings?.ShowAddressSecurity ? attr.title(recipientSecurityTitle) : [], function keydown(e) {
|
const root = dom.span(autosizeElem = dom.span(dom._class('autosize'), inputElem = dom.input(focusPlaceholder('Jane <jane@example.org>'), style({ width: 'auto' }), attr.value(addr), newAddressComplete(), accountSettings?.ShowAddressSecurity ? attr.title(recipientSecurityTitle) : [], function keydown(e) {
|
||||||
if (e.key === 'Backspace' && e.ctrlKey && inputElem.value === '') {
|
// Backspace removes address except when it's the only To address left.
|
||||||
|
if (e.key === 'Backspace' && e.ctrlKey && inputElem.value === '' && !(isTo && views.length === 1)) {
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
else if (e.key === '=' && e.ctrlKey) {
|
else if (e.key === '=' && e.ctrlKey) {
|
||||||
newAddrView('', isRecipient, views, btn, cell, row, single);
|
newAddrView('', isRecipient, isTo, views, btn, cell, row, single);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
@ -2930,7 +2931,7 @@ const compose = (opts, listMailboxes) => {
|
|||||||
autosizeElem.dataset.value = inputElem.value = split[0];
|
autosizeElem.dataset.value = inputElem.value = split[0];
|
||||||
let last;
|
let last;
|
||||||
for (const rest of split.splice(1)) {
|
for (const rest of split.splice(1)) {
|
||||||
last = newAddrView(rest.trim(), isRecipient, views, btn, cell, row, single);
|
last = newAddrView(rest.trim(), isRecipient, isTo, views, btn, cell, row, single);
|
||||||
}
|
}
|
||||||
last.input.focus();
|
last.input.focus();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -3157,11 +3158,11 @@ const compose = (opts, listMailboxes) => {
|
|||||||
shortcutCmd(cmdSend, shortcuts);
|
shortcutCmd(cmdSend, shortcuts);
|
||||||
}));
|
}));
|
||||||
subjectAutosize.dataset.value = subject.value;
|
subjectAutosize.dataset.value = subject.value;
|
||||||
(opts.to && opts.to.length > 0 ? opts.to : ['']).forEach(s => newAddrView(s, true, toViews, toBtn, toCell, toRow));
|
(opts.to && opts.to.length > 0 ? opts.to : ['']).forEach(s => newAddrView(s, true, true, toViews, toBtn, toCell, toRow));
|
||||||
(opts.cc || []).forEach(s => newAddrView(s, true, ccViews, ccBtn, ccCell, ccRow));
|
(opts.cc || []).forEach(s => newAddrView(s, true, false, ccViews, ccBtn, ccCell, ccRow));
|
||||||
(opts.bcc || []).forEach(s => newAddrView(s, true, bccViews, bccBtn, bccCell, bccRow));
|
(opts.bcc || []).forEach(s => newAddrView(s, true, false, bccViews, bccBtn, bccCell, bccRow));
|
||||||
if (opts.replyto) {
|
if (opts.replyto) {
|
||||||
newAddrView(opts.replyto, false, replytoViews, replyToBtn, replyToCell, replyToRow, true);
|
newAddrView(opts.replyto, false, false, replytoViews, replyToBtn, replyToCell, replyToRow, true);
|
||||||
}
|
}
|
||||||
if (!opts.cc || !opts.cc.length) {
|
if (!opts.cc || !opts.cc.length) {
|
||||||
ccRow.style.display = 'none';
|
ccRow.style.display = 'none';
|
||||||
|
@ -1642,10 +1642,10 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||||||
await withStatus('Sending email and archive', submit(true), fieldset)
|
await withStatus('Sending email and archive', submit(true), fieldset)
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmdAddTo = async () => { newAddrView('', true, toViews, toBtn, toCell, toRow) }
|
const cmdAddTo = async () => { newAddrView('', true, true, toViews, toBtn, toCell, toRow) }
|
||||||
const cmdAddCc = async () => { newAddrView('', true, ccViews, ccBtn, ccCell, ccRow) }
|
const cmdAddCc = async () => { newAddrView('', true, false, ccViews, ccBtn, ccCell, ccRow) }
|
||||||
const cmdAddBcc = async () => { newAddrView('', true, bccViews, bccBtn, bccCell, bccRow) }
|
const cmdAddBcc = async () => { newAddrView('', true, false, bccViews, bccBtn, bccCell, bccRow) }
|
||||||
const cmdReplyTo = async () => { newAddrView('', false, replytoViews, replyToBtn, replyToCell, replyToRow, true) }
|
const cmdReplyTo = async () => { newAddrView('', false, false, replytoViews, replyToBtn, replyToCell, replyToRow, true) }
|
||||||
const cmdCustomFrom = async () => {
|
const cmdCustomFrom = async () => {
|
||||||
if (customFrom) {
|
if (customFrom) {
|
||||||
return
|
return
|
||||||
@ -1668,7 +1668,7 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||||||
// ctrl Backspace and ctrl = (+) not included, they are handled by keydown handlers on in the inputs they remove/add.
|
// ctrl Backspace and ctrl = (+) not included, they are handled by keydown handlers on in the inputs they remove/add.
|
||||||
}
|
}
|
||||||
|
|
||||||
const newAddrView = (addr: string, isRecipient: boolean, views: AddrView[], btn: HTMLButtonElement, cell: HTMLElement, row: HTMLElement, single?: boolean) => {
|
const newAddrView = (addr: string, isRecipient: boolean, isTo: boolean, views: AddrView[], btn: HTMLButtonElement, cell: HTMLElement, row: HTMLElement, single?: boolean) => {
|
||||||
if (single && views.length !== 0) {
|
if (single && views.length !== 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1780,10 +1780,11 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||||||
newAddressComplete(),
|
newAddressComplete(),
|
||||||
accountSettings?.ShowAddressSecurity ? attr.title(recipientSecurityTitle) : [],
|
accountSettings?.ShowAddressSecurity ? attr.title(recipientSecurityTitle) : [],
|
||||||
function keydown(e: KeyboardEvent) {
|
function keydown(e: KeyboardEvent) {
|
||||||
if (e.key === 'Backspace' && e.ctrlKey && inputElem.value === '') {
|
// Backspace removes address except when it's the only To address left.
|
||||||
|
if (e.key === 'Backspace' && e.ctrlKey && inputElem.value === '' && !(isTo && views.length === 1)) {
|
||||||
remove()
|
remove()
|
||||||
} else if (e.key === '=' && e.ctrlKey) {
|
} else if (e.key === '=' && e.ctrlKey) {
|
||||||
newAddrView('', isRecipient, views, btn, cell, row, single)
|
newAddrView('', isRecipient, isTo, views, btn, cell, row, single)
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1810,7 +1811,7 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||||||
autosizeElem.dataset.value = inputElem.value = split[0]
|
autosizeElem.dataset.value = inputElem.value = split[0]
|
||||||
let last
|
let last
|
||||||
for (const rest of split.splice(1)) {
|
for (const rest of split.splice(1)) {
|
||||||
last = newAddrView(rest.trim(), isRecipient, views, btn, cell, row, single)
|
last = newAddrView(rest.trim(), isRecipient, isTo, views, btn, cell, row, single)
|
||||||
}
|
}
|
||||||
last!!.input.focus()
|
last!!.input.focus()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@ -2186,11 +2187,11 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||||||
|
|
||||||
subjectAutosize.dataset.value = subject.value
|
subjectAutosize.dataset.value = subject.value
|
||||||
|
|
||||||
;(opts.to && opts.to.length > 0 ? opts.to : ['']).forEach(s => newAddrView(s, true, toViews, toBtn, toCell, toRow))
|
;(opts.to && opts.to.length > 0 ? opts.to : ['']).forEach(s => newAddrView(s, true, true, toViews, toBtn, toCell, toRow))
|
||||||
;(opts.cc || []).forEach(s => newAddrView(s,true, ccViews, ccBtn, ccCell, ccRow))
|
;(opts.cc || []).forEach(s => newAddrView(s, true, false, ccViews, ccBtn, ccCell, ccRow))
|
||||||
;(opts.bcc || []).forEach(s => newAddrView(s, true, bccViews, bccBtn, bccCell, bccRow))
|
;(opts.bcc || []).forEach(s => newAddrView(s, true, false, bccViews, bccBtn, bccCell, bccRow))
|
||||||
if (opts.replyto) {
|
if (opts.replyto) {
|
||||||
newAddrView(opts.replyto, false, replytoViews, replyToBtn, replyToCell, replyToRow, true)
|
newAddrView(opts.replyto, false, false, replytoViews, replyToBtn, replyToCell, replyToRow, true)
|
||||||
}
|
}
|
||||||
if (!opts.cc || !opts.cc.length) {
|
if (!opts.cc || !opts.cc.length) {
|
||||||
ccRow.style.display = 'none'
|
ccRow.style.display = 'none'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user