fix(ext/popup): bind form escHandlers to teardown to stop listener leak

This commit is contained in:
adlee-was-taken
2026-04-23 23:09:52 -04:00
parent 23759dc163
commit 706051530e
6 changed files with 36 additions and 6 deletions

View File

@@ -10,12 +10,17 @@ import {
const CARD_KINDS: CardKind[] = ['credit', 'debit', 'gift', 'loyalty', 'other'];
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
let activeFormEscHandler: ((e: KeyboardEvent) => void) | null = null;
export function teardown(): void {
if (activeKeyHandler) {
document.removeEventListener('keydown', activeKeyHandler);
activeKeyHandler = null;
}
if (activeFormEscHandler) {
document.removeEventListener('keydown', activeFormEscHandler);
activeFormEscHandler = null;
}
}
function brandFromNumber(num: string): string {
@@ -187,11 +192,11 @@ export function renderForm(app: HTMLElement, mode: 'add' | 'edit', existing: Ite
const escHandler = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
document.removeEventListener('keydown', escHandler);
setState({ error: null });
navigate(mode === 'edit' ? 'detail' : 'list');
}
};
activeFormEscHandler = escHandler;
document.addEventListener('keydown', escHandler);
(document.getElementById('f-title') as HTMLInputElement | null)?.focus();

View File

@@ -8,12 +8,17 @@ import {
} from '../fields';
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
let activeFormEscHandler: ((e: KeyboardEvent) => void) | null = null;
export function teardown(): void {
if (activeKeyHandler) {
document.removeEventListener('keydown', activeKeyHandler);
activeKeyHandler = null;
}
if (activeFormEscHandler) {
document.removeEventListener('keydown', activeFormEscHandler);
activeFormEscHandler = null;
}
}
function initials(name: string | undefined): string {
@@ -142,11 +147,11 @@ export function renderForm(app: HTMLElement, mode: 'add' | 'edit', existing: Ite
const escHandler = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
document.removeEventListener('keydown', escHandler);
setState({ error: null });
navigate(mode === 'edit' ? 'detail' : 'list');
}
};
activeFormEscHandler = escHandler;
document.addEventListener('keydown', escHandler);
(document.getElementById('f-title') as HTMLInputElement | null)?.focus();

View File

@@ -9,12 +9,17 @@ import {
} from '../fields';
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
let activeFormEscHandler: ((e: KeyboardEvent) => void) | null = null;
export function teardown(): void {
if (activeKeyHandler) {
document.removeEventListener('keydown', activeKeyHandler);
activeKeyHandler = null;
}
if (activeFormEscHandler) {
document.removeEventListener('keydown', activeFormEscHandler);
activeFormEscHandler = null;
}
}
export async function renderDetail(app: HTMLElement, item: Item): Promise<void> {
@@ -141,11 +146,11 @@ export function renderForm(app: HTMLElement, mode: 'add' | 'edit', existing: Ite
const escHandler = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
document.removeEventListener('keydown', escHandler);
setState({ error: null });
navigate(mode === 'edit' ? 'detail' : 'list');
}
};
activeFormEscHandler = escHandler;
document.addEventListener('keydown', escHandler);
(document.getElementById('f-title') as HTMLInputElement | null)?.focus();

View File

@@ -20,6 +20,10 @@ export function teardown(): void {
document.removeEventListener('keydown', activeKeyHandler);
activeKeyHandler = null;
}
if (activeFormEscHandler) {
document.removeEventListener('keydown', activeFormEscHandler);
activeFormEscHandler = null;
}
}
// ----------------------------------------------------------------------
@@ -174,6 +178,7 @@ export async function renderDetail(app: HTMLElement, item: Item): Promise<void>
let totpTickerId: ReturnType<typeof setInterval> | null = null;
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
let activeFormEscHandler: ((e: KeyboardEvent) => void) | null = null;
function stopTotpTicker(): void {
if (totpTickerId !== null) { clearInterval(totpTickerId); totpTickerId = null; }
}
@@ -259,11 +264,11 @@ export function renderForm(app: HTMLElement, mode: 'add' | 'edit', existing: Ite
const escHandler = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
document.removeEventListener('keydown', escHandler);
setState({ error: null });
navigate(mode === 'edit' ? 'detail' : 'list');
}
};
activeFormEscHandler = escHandler;
document.addEventListener('keydown', escHandler);
(document.getElementById('f-title') as HTMLInputElement | null)?.focus();

View File

@@ -8,12 +8,17 @@ import {
} from '../fields';
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
let activeFormEscHandler: ((e: KeyboardEvent) => void) | null = null;
export function teardown(): void {
if (activeKeyHandler) {
document.removeEventListener('keydown', activeKeyHandler);
activeKeyHandler = null;
}
if (activeFormEscHandler) {
document.removeEventListener('keydown', activeFormEscHandler);
activeFormEscHandler = null;
}
}
export async function renderDetail(app: HTMLElement, item: Item): Promise<void> {
@@ -112,11 +117,11 @@ export function renderForm(app: HTMLElement, mode: 'add' | 'edit', existing: Ite
const escHandler = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
document.removeEventListener('keydown', escHandler);
setState({ error: null });
navigate(mode === 'edit' ? 'detail' : 'list');
}
};
activeFormEscHandler = escHandler;
document.addEventListener('keydown', escHandler);
(document.getElementById('f-title') as HTMLInputElement | null)?.focus();

View File

@@ -15,6 +15,7 @@ import {
let totpTickerId: ReturnType<typeof setInterval> | null = null;
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
let activeFormEscHandler: ((e: KeyboardEvent) => void) | null = null;
function stopTotpTicker(): void {
if (totpTickerId !== null) { clearInterval(totpTickerId); totpTickerId = null; }
@@ -28,6 +29,10 @@ export function teardown(): void {
document.removeEventListener('keydown', activeKeyHandler);
activeKeyHandler = null;
}
if (activeFormEscHandler) {
document.removeEventListener('keydown', activeFormEscHandler);
activeFormEscHandler = null;
}
}
// ----------------------------------------------------------------------
@@ -248,11 +253,11 @@ export function renderForm(app: HTMLElement, mode: 'add' | 'edit', existing: Ite
const escHandler = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
document.removeEventListener('keydown', escHandler);
setState({ error: null });
navigate(mode === 'edit' ? 'detail' : 'list');
}
};
activeFormEscHandler = escHandler;
document.addEventListener('keydown', escHandler);
(document.getElementById('f-title') as HTMLInputElement | null)?.focus();