diff --git a/scripts/batchCloseConfirmation.test.ts b/scripts/batchCloseConfirmation.test.ts new file mode 100644 index 0000000..e2e93fa --- /dev/null +++ b/scripts/batchCloseConfirmation.test.ts @@ -0,0 +1,17 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import test from 'node:test'; + +const viewer = readFileSync(new URL('../src/lib/MarkdownViewer.svelte', import.meta.url), 'utf8'); + +test('batch tab-close commands use the existing dirty-tab confirmation flow', () => { + assert.match(viewer, /async function closeTabsWithConfirmation\(tabIds: string\[\]\)/); + assert.match( + viewer, + /for \(const tabId of tabIds\) \{\s*if \(!\(await canCloseTab\(tabId\)\)\) return;\s*tabManager\.closeTab\(tabId\);\s*\}/, + ); + assert.match(viewer, /menu-tab-close-others[\s\S]*await closeTabsWithConfirmation\(tabsToClose\)/); + assert.match(viewer, /menu-tab-close-right[\s\S]*await closeTabsWithConfirmation\(tabsToClose\)/); + assert.match(viewer, /appWindow\.listen\('menu-tab-close-others', async \(event\)/); + assert.match(viewer, /appWindow\.listen\('menu-tab-close-right', async \(event\)/); +}); diff --git a/src/lib/MarkdownViewer.svelte b/src/lib/MarkdownViewer.svelte index 25bfce4..f2a0cd5 100644 --- a/src/lib/MarkdownViewer.svelte +++ b/src/lib/MarkdownViewer.svelte @@ -2073,6 +2073,13 @@ import { t } from './utils/i18n.js'; await destroyWindowAfterTabsClosed(); } + async function closeTabsWithConfirmation(tabIds: string[]) { + for (const tabId of tabIds) { + if (!(await canCloseTab(tabId))) return; + tabManager.closeTab(tabId); + } + } + async function destroyWindowAfterTabsClosed() { if (settings.restoreStateOnReopen) { await persistWindowState(); @@ -2940,19 +2947,19 @@ import { t } from './utils/i18n.js'; }), ); unlisteners.push( - await appWindow.listen('menu-tab-close-others', (event) => { + await appWindow.listen('menu-tab-close-others', async (event) => { const tabId = event.payload as string; const tabsToClose = tabManager.tabs.filter((t) => t.id !== tabId).map((t) => t.id); - tabsToClose.forEach((id) => tabManager.closeTab(id)); + await closeTabsWithConfirmation(tabsToClose); }), ); unlisteners.push( - await appWindow.listen('menu-tab-close-right', (event) => { + await appWindow.listen('menu-tab-close-right', async (event) => { const tabId = event.payload as string; const index = tabManager.tabs.findIndex((t) => t.id === tabId); if (index !== -1) { const tabsToClose = tabManager.tabs.slice(index + 1).map((t) => t.id); - tabsToClose.forEach((id) => tabManager.closeTab(id)); + await closeTabsWithConfirmation(tabsToClose); } }), );