Commit Graph

8 Commits

Author SHA1 Message Date
Collin Osborne
471ee494f0 fix: make transient dropdown/popup menus close on Escape
The global Escape arbiter in ui.js only sees `.modal` elements, so the many
ad-hoc dropdowns and context popups that are built on the fly and appended to
<body> ignored Escape entirely: document-library card/chat menus, chat
context/stats/overflow popups, cookbook serve & running menus, calendar event
menus, and compare pane menus.

Add a small DOM-free dismissal registry (static/js/escMenuStack.js). Menus
register a dismiss callback while open, and the arbiter closes the
most-recently-opened one first, so a menu opened over a modal closes before the
modal. bindMenuDismiss() wires the ubiquitous "append-to-body, close on outside
click" idiom to both the outside-click listener and the Escape stack in one
call, and dismissOrRemove() lets the pre-existing bulk removers (scroll/swipe/
modal-dismiss cleanup, reopen sweeps) tear a menu down through its real teardown
instead of orphaning its stack entry.

Covers ~14 menus across documentLibrary, chatRenderer, cookbookServe,
cookbookRunning, calendar, and compare/panes. Every teardown path — item click,
outside click, swipe, toggle, rebuild, bulk cleanup — routes through the
registry so no entry is ever stranded.

tests/test_esc_menu_stack_js.py pins the registry's LIFO and
exactly-one-per-press guarantees (node-driven; skips when node is absent).
2026-06-01 14:23:22 -04:00
pewdiepie-archdaemon
5ed9b74cd0 Polish email tasks and window controls 2026-06-01 20:56:46 +09:00
pewdiepie-archdaemon
ee62acd3f1 Fix library space toggles 2026-06-01 14:50:06 +09:00
pewdiepie-archdaemon
ace470b437 Let hovered space toggles override stale focus 2026-06-01 14:45:47 +09:00
pewdiepie-archdaemon
e846269d61 Improve space toggles and email warmup 2026-06-01 14:35:38 +09:00
pewdiepie-archdaemon
8218421733 Polish email send and card toggles 2026-06-01 13:52:07 +09:00
chrisdvz.io
ff81a22285 perf(ui): hoist esc() lookup table and build option lists once (#160)
Hoist the HTML-escape lookup table in static/js/ui.js out of the
String.replace callback so it is allocated once instead of on every
matched character. esc() is the canonical escaper aliased across 27
modules and runs on essentially every render, so this removes a lot of
short-lived garbage on the hottest text path. Output is byte-identical
(verified across null/undefined/emoji/attribute edge cases).

Also build the <select> option lists in cookbook-hwfit.js and group.js
by accumulating a string and assigning innerHTML once, instead of
`innerHTML +=` inside a forEach (which makes the browser re-parse the
element's markup on every iteration). Final DOM is unchanged.

Pure micro-optimizations; no behavior change.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 13:09:33 +09:00
pewdiepie-archdaemon
e5c99a5eee Odysseus v1.0 2026-05-31 23:58:26 +09:00