Step 7a: Bulk ID Check moves to a detached popup window

New files:
  bulk-check.html, bulk-check.js, bulk-check.css

Popup gains a 📋 launcher button next to the ⚙ Options gear. Clicking
it sends `open-bulk-check` to background.js and closes the popup;
background.js owns window lifecycle:

  - chrome.storage.session.bulkCheckWindowId stashes the open window id
  - existing id → chrome.windows.update({ focused, drawAttention })
  - missing or stale id → chrome.windows.create({ type:'popup',
    width:640, height:540 }) and stash the new id
  - chrome.windows.onRemoved clears the stale id on close

Last-paste persisted to chrome.storage.local.bulkCheckLastPaste,
debounced 500ms on input, restored on window open. quickMode is read
from settings at run time, matching previous behavior. Ctrl/Cmd+Enter
inside the textarea triggers the check.

Options page no longer carries the Bulk ID Check fieldset: removed
from options.html (Library Review pdesc updated to note the
relocation) and the matching handlers from options.js
(1903 → 1852 lines). No manifest permission changes — own-page
chrome.windows.create needs no extra permission.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
admin
2026-05-22 21:27:12 +02:00
parent e4ee06b19f
commit ad4df28a66
9 changed files with 321 additions and 64 deletions
+46
View File
@@ -692,6 +692,11 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
})();
return true;
}
if (msg.type === "open-bulk-check") {
openBulkCheckWindow();
sendResponse({ ok: true });
return false;
}
if (msg.type === "dupe-review") {
(async () => {
try {
@@ -1075,3 +1080,44 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
// On install / startup, build context menu
chrome.runtime.onInstalled.addListener(() => ensureContextMenu());
chrome.runtime.onStartup.addListener(() => ensureContextMenu());
// ---------- Bulk Check standalone window ----------
const BULK_CHECK_WIN_KEY = "bulkCheckWindowId";
async function openBulkCheckWindow() {
const session = chrome.storage.session;
try {
const stored = session ? await session.get(BULK_CHECK_WIN_KEY) : {};
const existingId = stored?.[BULK_CHECK_WIN_KEY];
if (existingId) {
try {
await chrome.windows.update(existingId, { focused: true, drawAttention: true });
return;
} catch {
if (session) await session.remove(BULK_CHECK_WIN_KEY);
}
}
const win = await chrome.windows.create({
url: chrome.runtime.getURL("bulk-check.html"),
type: "popup",
width: 640,
height: 540,
});
if (session && win?.id != null) {
await session.set({ [BULK_CHECK_WIN_KEY]: win.id });
}
} catch (e) {
console.warn("openBulkCheckWindow failed:", e);
}
}
chrome.windows.onRemoved.addListener(async (windowId) => {
const session = chrome.storage.session;
if (!session) return;
try {
const stored = await session.get(BULK_CHECK_WIN_KEY);
if (stored?.[BULK_CHECK_WIN_KEY] === windowId) {
await session.remove(BULK_CHECK_WIN_KEY);
}
} catch { /* ignore */ }
});