ulysses/static
Mocchibird 4c82e4a172
fix(ui): route transient dropdown menus through escMenuStack to stop listener leaks (#4684)
The app's ad-hoc dropdown/context menus each wire their own document-level
outside-click listener, but that listener only removes itself on an *outside*
click. Every other dismissal path -- clicking a menu item (which calls
el.remove() directly), a Cancel button, Escape, or the "close the
previously-open menu" reopen sweep -- tears the node down without
unregistering the listener, orphaning it on `document`. The stranded listener
then lingers and can break the next menu interaction: the recurring "the
button stops working until I refresh the page" class of bug (e.g. delete an
email, then the kebab/more button is dead on the other rows).

Route all 16 of these menus through the existing escMenuStack helper
(bindMenuDismiss / dismissOrRemove), exactly as documentLibrary.js
_showLibDropdown, cookbookRunning.js, and research/panel.js already do: a
single idempotent close() owns the teardown and is released on every dismissal
path, reopen sweeps use dismissOrRemove() instead of a bare .remove(), and
Escape flows through the central LIFO esc-stack arbiter. Net -49 lines.

Menus migrated: cookbook _showDepMenu; document export menu and
_openDocAiReplyChoice; emailInbox _showEmailMenu; emailLibrary
_showReaderMoreMenu / _showCardMenu / _showBulkActionsMenu; gallery
_showGalleryBulkMenu; notes _pickCustomDate / _openNoteCornerMenu; settings
(3 unified-integrations dropdowns); skills _openSkillMenu; tasks
_showTaskDropdown; compare _toggleExportMenu.

Per-menu semantics preserved (anchor-as-inside tests, the tasks 250ms
ghost-click guard, emailLibrary's reader-more-active anchor class and the
bulk-Cancel select-mode reset, settings' reused-vs-recreated lifecycles).

Six menus with custom lifecycles (notes _openReminderMenu, sessions
long-press, document markdown-toolbar, emojiPicker, compare model selector)
are intentionally left for a follow-up -- each needs individual review.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 20:40:56 +02:00
..
fonts feat(a11y): add a Text size control and an OpenDyslexic font option (#4210) 2026-06-22 13:53:46 +02:00
icons Cookbook model workflow fixes 2026-06-21 11:02:35 +00:00
js fix(ui): route transient dropdown menus through escMenuStack to stop listener leaks (#4684) 2026-06-22 20:40:56 +02:00
lib Odysseus v1.0 2026-05-31 23:58:26 +09:00
app.js Merge remote-tracking branch 'origin/dev' into test-main-dev-merge-20260615 2026-06-15 21:20:15 +09:00
icon.ico feat(launcher): add portable windows launcher (#976) 2026-06-16 04:58:16 +01:00
index.html feat(a11y): add a Text size control and an OpenDyslexic font option (#4210) 2026-06-22 13:53:46 +02:00
login.html fix(auth): centralize password and username validation constants (#4120) 2026-06-16 09:52:15 +02:00
manifest.json pwa missing icons added (#428) 2026-06-15 16:00:13 +09:00
style.css feat(a11y): add a Text size control and an OpenDyslexic font option (#4210) 2026-06-22 13:53:46 +02:00
sw.js fix(ui): modal drag + removed startDrag func (#2430) 2026-06-04 20:34:18 +02:00