fix(ext/popup): stop Escape from leaking past the generator panel

Two related bugs from the gen-panel rewrite (ac15f06):

1. Escape key was bubbling to view-level keydown handlers in login.ts
   and settings-vault.ts, causing the press that closed the panel to
   also navigate the user away from the form/settings. Fix: call
   e.stopPropagation() in the panel's escHandler before closing.

2. settings-vault.teardown() didn't close any open generator panel,
   leaving the panel's escHandler registered and activePanel state
   stale across view transitions. Fix: call closeGeneratorPanel()
   first in teardown.

Plus a configure-defaults context test for the action-row composition
(no use/cancel buttons in that context).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-04-25 00:36:10 -04:00
parent ac15f060e9
commit 010c4263ba
3 changed files with 14 additions and 1 deletions

View File

@@ -157,4 +157,13 @@ describe('generator-panel', () => {
expect(isGeneratorPanelOpen()).toBe(false); expect(isGeneratorPanelOpen()).toBe(false);
expect(document.querySelector('.gen-panel')).toBeNull(); expect(document.querySelector('.gen-panel')).toBeNull();
}); });
it("configure-defaults context renders only the save-default action (no use/cancel)", async () => {
const { parent, trigger } = setupMount();
openGeneratorPanel({ parent, trigger, initial: DEFAULT_REQ, context: 'configure-defaults' });
await new Promise((r) => setTimeout(r, 50));
expect(document.querySelector('#gen-save-default')).not.toBeNull();
expect(document.querySelector('#gen-use')).toBeNull();
expect(document.querySelector('#gen-cancel')).toBeNull();
});
}); });

View File

@@ -106,7 +106,10 @@ export function openGeneratorPanel(opts: OpenPanelOpts): void {
opts.trigger.setAttribute('aria-expanded', 'true'); opts.trigger.setAttribute('aria-expanded', 'true');
const escHandler = (e: KeyboardEvent): void => { const escHandler = (e: KeyboardEvent): void => {
if (e.key === 'Escape') closeGeneratorPanel(); if (e.key === 'Escape') {
e.stopPropagation();
closeGeneratorPanel();
}
}; };
document.addEventListener('keydown', escHandler); document.addEventListener('keydown', escHandler);

View File

@@ -12,6 +12,7 @@ let pendingSettings: VaultSettings | null = null;
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null; let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
export function teardown(): void { export function teardown(): void {
closeGeneratorPanel();
if (activeKeyHandler) { if (activeKeyHandler) {
document.removeEventListener('keydown', activeKeyHandler); document.removeEventListener('keydown', activeKeyHandler);
activeKeyHandler = null; activeKeyHandler = null;