mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-12 10:19:42 +02:00
fix(tabs): Escape in the rail search box clears only the search (#580)
The global key handler in setupEventListeners() sits on document in the capture phase, so it ran before the box's inline onkeydown: the Escape that cleared the search also ran closeAllPanels() (collapsing the Monitor and Subagents panels), closeHelp() and closeSessionManager(). Calling stopPropagation() from the inline handler came too late. The global Escape branch now claims an Escape whose target is #tabRailSearch while the box holds text, the same way it already claims one for the group menu, the grouped-rail drag and the Tiles count menu, and routes it to handleTabRailSearchKeydown(). An empty box still leaves Escape to the global handler, and an Escape that cancels an IME composition is left to the IME. Tests: the unit test installs the real global listener and asserts that Escape with text in the box closes nothing, that an empty box closes as before, and that an Escape outside the box is not claimed. The browser test installs setupEventListeners() for real in Chromium, so the capture-before-inline ordering is the shipped one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+16
-3
@@ -1427,6 +1427,13 @@ class CodemanApp {
|
||||
this.closeTileCountMenu({ refocus: true });
|
||||
return;
|
||||
}
|
||||
// And so does the rail's search box while it holds text: that Escape
|
||||
// clears the search and nothing else. This listener runs in the capture
|
||||
// phase, before the box's own onkeydown, so the box cannot claim it there.
|
||||
if (e.target?.id === 'tabRailSearch' && this._tabRailSearch) {
|
||||
this.handleTabRailSearchKeydown(e);
|
||||
return;
|
||||
}
|
||||
this.closeAllPanels();
|
||||
this.closeHelp();
|
||||
if (this.attachmentHistoryDrawerOpen) this.closeAttachmentHistory();
|
||||
@@ -5859,10 +5866,16 @@ class CodemanApp {
|
||||
input?.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape in a box that holds text clears the search and nothing else. The
|
||||
* global key handler (setupEventListeners) runs in the CAPTURE phase, before
|
||||
* the box's inline onkeydown, so it is the one that routes the key here and
|
||||
* returns before its close-every-panel branch; stopping propagation from the
|
||||
* inline handler would come too late. An empty box leaves Escape to it, and
|
||||
* an Escape that cancels an IME composition is the IME's.
|
||||
*/
|
||||
handleTabRailSearchKeydown(event) {
|
||||
if (event.key !== 'Escape' || !this._tabRailSearch) return;
|
||||
// Consumed here: the global Escape handler would otherwise close whatever
|
||||
// else is open on the same keypress.
|
||||
if (event.key !== 'Escape' || event.isComposing || !this._tabRailSearch) return;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.clearTabRailSearch();
|
||||
|
||||
Reference in New Issue
Block a user