From af05604e99b4f27cc6b5f227d61ac85049a030e8 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Thu, 4 Jun 2026 15:12:38 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20backup=20viewer=20close=20button=20?= =?UTF-8?q?=E2=80=94=20add=20missing=20onclick=20to=20renderError=20+=20Es?= =?UTF-8?q?cape=20key=20+=20proper=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/js/backups.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/frontend/js/backups.js b/frontend/js/backups.js index e523189..d579f15 100644 --- a/frontend/js/backups.js +++ b/frontend/js/backups.js @@ -91,6 +91,14 @@ function createOverlay() { if (e.target === overlay) close(); }); + // Keyboard: Escape closes the viewer + _escHandler = (e) => { + if (e.key === 'Escape' && state.overlay) { + close(); + } + }; + document.addEventListener('keydown', _escHandler); + const panel = document.createElement('div'); panel.className = 'backup-viewer-panel'; panel.id = 'backup-viewer-panel'; @@ -124,17 +132,23 @@ function setBody(html) { } } +let _escHandler = null; + function close() { - if (state.overlay) { - state.overlay.classList.remove('active'); - setTimeout(() => { - if (state.overlay) state.overlay.remove(); - state.overlay = null; - }, 200); + if (!state.overlay) return; + // Remove keyboard listener + if (_escHandler) { + document.removeEventListener('keydown', _escHandler); + _escHandler = null; } + state.overlay.classList.remove('active'); + setTimeout(() => { + if (state.overlay) state.overlay.remove(); + state.overlay = null; + }, 200); } -// Expose globally for inline onclick handlers (bypasses text-node target issues) +// Expose globally for inline onclick handlers window._backupViewerClose = close; // --------------------------------------------------------------------------- @@ -156,10 +170,10 @@ function renderLoading() { } function renderError(msg) { - return ` + return \`

Backups

- +

${escapeHtml(msg)}