fix(quick-save): Firefox-importScripts-Guard (Event-Page), Sync-Guard auf reale Overlay/Drag-Klassen, Worker-Serialisierung + interne-URL-Filter + kurzer Fehler-Badge
This commit is contained in:
+21
-11
@@ -5,10 +5,13 @@
|
||||
synchron auf Top-Level. Geteilte Logik via importScripts.
|
||||
============================================= */
|
||||
|
||||
// Geteiltes DOM-freies Helfer-Modul aus Phase 1: ensureInbox(boards), uid(),
|
||||
// normalizeBookmark(...). importScripts ist im Service-Worker UND in der
|
||||
// Firefox-Event-Page verfuegbar.
|
||||
importScripts('quicksave-core.js');
|
||||
// Geteiltes DOM-freies Helfer-Modul aus Phase 1: ensureInbox(boards), uid(), normalizeBookmark(...).
|
||||
// Chrome-Service-Worker laedt es via importScripts. Firefox-Event-Page hat KEIN importScripts —
|
||||
// dort kommt das Modul ueber background.scripts (manifest.firefox.json) in den Scope, ensureInbox
|
||||
// ist dann schon definiert. Der Guard verhindert den ReferenceError in der Event-Page.
|
||||
if (typeof importScripts === 'function' && typeof ensureInbox === 'undefined') {
|
||||
importScripts('quicksave-core.js');
|
||||
}
|
||||
|
||||
// chrome.storage.local-Lese-/Schreib-Helfer als Promises (kein Store-Modul im Worker,
|
||||
// das ist DOM/Seiten-gebunden). Identisches Verhalten: get -> Wert oder null.
|
||||
@@ -30,22 +33,26 @@ function bgSet(key, value) {
|
||||
});
|
||||
}
|
||||
|
||||
// Kurze Badge-Bestaetigung, dann automatisch wieder leeren.
|
||||
function flashBadge(text) {
|
||||
// Kurze Badge-Bestaetigung, dann automatisch wieder leeren. color optional (Default gruen).
|
||||
function flashBadge(text, color) {
|
||||
chrome.action.setBadgeText({ text });
|
||||
// Hintergrundfarbe optional, ohne extra Permission moeglich.
|
||||
if (chrome.action.setBadgeBackgroundColor) {
|
||||
chrome.action.setBadgeBackgroundColor({ color: '#1f9d55' });
|
||||
chrome.action.setBadgeBackgroundColor({ color: color || '#1f9d55' });
|
||||
}
|
||||
setTimeout(() => chrome.action.setBadgeText({ text: '' }), 2000);
|
||||
}
|
||||
|
||||
// Interne/nicht speicherbare Seiten (Browser-UI, Extension-Seiten) — kein sinnvolles Bookmark.
|
||||
const UNSAVEABLE_URL = /^(chrome|chrome-extension|about|edge|opera|moz-extension|brave|vivaldi|view-source|devtools):/i;
|
||||
|
||||
// Quick-Save: aktiven Tab lesen, in die Inbox haengen (read-modify-write).
|
||||
async function quickSaveActiveTab() {
|
||||
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
|
||||
const tab = tabs && tabs[0];
|
||||
if (!tab || !tab.url) {
|
||||
flashBadge(chrome.i18n.getMessage('quickSaveNoTab'));
|
||||
if (!tab || !tab.url || UNSAVEABLE_URL.test(tab.url)) {
|
||||
// Kein speicherbarer Tab: kurzer roter Marker (langer Text wird im Badge abgeschnitten).
|
||||
flashBadge('×', '#c0392b');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,9 +70,12 @@ async function quickSaveActiveTab() {
|
||||
}
|
||||
}
|
||||
|
||||
// Listener SYNCHRON auf Top-Level registrieren (Event-Page/Worker-Anforderung).
|
||||
// Quick-Saves serialisieren: zwei schnelle Tastendruecke (Key-Repeat) wuerden sonst parallel
|
||||
// read-modify-write machen und sich gegenseitig ueberschreiben (lost update). Promise-Kette
|
||||
// sorgt fuer sequentielle Ausfuehrung. Listener bleibt SYNCHRON auf Top-Level registriert.
|
||||
let quickSaveChain = Promise.resolve();
|
||||
chrome.commands.onCommand.addListener(command => {
|
||||
if (command === 'quick-save') {
|
||||
quickSaveActiveTab();
|
||||
quickSaveChain = quickSaveChain.then(() => quickSaveActiveTab()).catch(e => console.error('Quick-Save:', e && e.message));
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user