fix(editor): a programmatic click is not a click-outside
Import with an open, dirty editor showed "Discard unsaved changes?" stacked
on top of the native file dialog. doImport appends its hidden file input to
<body> and calls .click(); that synthetic click bubbles to the document
handler, which sees a target outside .slideover and fires
requestCloseSlideOver.
Same latent bug on the attachment download web-fallback (an <a download>
appended to <body>, then .click()ed).
Gate the handler on e.isTrusted: only a real user click can mean "clicked
away". Fixes both and any future programmatic click, at the shared choke
point. File inputs living inside the slideover (icon upload, attachment
picker) were already safe via closest('.slideover').
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7197,6 +7197,12 @@ async function init() {
|
|||||||
}, true);
|
}, true);
|
||||||
document.addEventListener('click', e => {
|
document.addEventListener('click', e => {
|
||||||
if (!$('#slideover').classList.contains('is-open')) return;
|
if (!$('#slideover').classList.contains('is-open')) return;
|
||||||
|
// Only a real click can mean "the user clicked away". A programmatic
|
||||||
|
// .click() — the hidden file input behind Import, the <a download>
|
||||||
|
// behind an attachment save — is appended to <body>, so it bubbles up
|
||||||
|
// here looking exactly like an outside click and popped the discard
|
||||||
|
// prompt on top of the native file dialog. isTrusted tells them apart.
|
||||||
|
if (!e.isTrusted) return;
|
||||||
if (_slideoverMouseDownInside) { _slideoverMouseDownInside = false; return; }
|
if (_slideoverMouseDownInside) { _slideoverMouseDownInside = false; return; }
|
||||||
if (e.target.closest('.slideover')) return;
|
if (e.target.closest('.slideover')) return;
|
||||||
if (e.target.closest('.entry-card')) return;
|
if (e.target.closest('.entry-card')) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user