/** * gemeinsam.js - Hilfsmittel für alle Dialogseiten. */ /** * Verbindung zur Ereignisseite, die offen bleibt, solange der Dialog * geöffnet ist. * * Sie überträgt nichts - ihr einziger Zweck ist, die Ereignisseite am * Leben zu halten. Ohne sie wird die Seite während längerer Vorgänge * beendet, etwa beim Warten auf eine Aufgabe in Paperless, und der * laufende Aufruf schlägt mit "Receiving end does not exist" fehl. */ let dauerverbindung = null; let lebenszeichen = null; export function verbindungHalten() { if (dauerverbindung) return; try { dauerverbindung = browser.runtime.connect({ name: "dialog" }); dauerverbindung.onDisconnect.addListener(() => { dauerverbindung = null; if (lebenszeichen) { clearInterval(lebenszeichen); lebenszeichen = null; } }); // Zusätzlich regelmäßig ein Lebenszeichen senden. Die offene // Verbindung allein hat sich als nicht ausreichend erwiesen: Bei // mehreren Dateien hintereinander wurde die Ereignisseite trotzdem // beendet. Ein tatsächliches Ereignis alle 15 Sekunden setzt die // Untätigkeitsuhr zuverlässig zurück. lebenszeichen = setInterval(() => { try { dauerverbindung?.postMessage({ befehl: "lebenszeichen" }); } catch { clearInterval(lebenszeichen); lebenszeichen = null; } }, 15000); } catch (err) { console.warn("[paperless] Dauerverbindung nicht möglich:", err); } } /** * Ruft die Ereignisseite und wirft bei Fehlern eine Ausnahme. * * Unterscheidet zwei Fälle, die sonst dieselbe nichtssagende Meldung * ergeben ("An unexpected error occurred"): * * * Die Nachricht erreicht keinen Empfänger - das Hintergrundskript * ist nicht geladen oder abgestürzt. * * Der Empfänger meldet einen Fehler zurück. */ export async function ruf(befehl, daten = {}) { let antwort; try { antwort = await browser.runtime.sendMessage({ befehl, ...daten }); } catch (err) { console.error("[paperless] sendMessage", befehl, err); throw new Error( `Das Hintergrundskript antwortet nicht (${befehl}).\n` + `Ursprüngliche Meldung: ${err?.message || err}\n\n` + `Einzelheiten in der Konsole: Extras -> Entwicklerwerkzeuge -> ` + `Debuggen von Add-ons -> Inspizieren.`); } if (antwort === undefined) { throw new Error( `Keine Antwort auf ${befehl}. Das Hintergrundskript ist ` + `vermutlich nicht geladen.`); } if (!antwort?.ok) { throw new Error(antwort?.fehler || `Aufruf ${befehl} fehlgeschlagen`); } return antwort.daten; } /** * Beschriftungen aus _locales einsetzen. * * Elemente mit data-i18n bekommen ihren Text, solche mit * data-i18n-placeholder ihren Platzhalter. Fehlt ein Eintrag, bleibt der * im HTML hinterlegte deutsche Text stehen. */ export function uebersetzeSeite() { // Beim Aufbau der Seite gleich die Verbindung öffnen - jede Seite ruft // diese Funktion, also ist es die verlässlichste Stelle. verbindungHalten(); for (const el of document.querySelectorAll("[data-i18n]")) { const s = browser.i18n.getMessage(el.dataset.i18n); if (s) el.textContent = s; } for (const el of document.querySelectorAll("[data-i18n-placeholder]")) { const s = browser.i18n.getMessage(el.dataset.i18nPlaceholder); if (s) el.placeholder = s; } for (const el of document.querySelectorAll("[data-i18n-title]")) { const s = browser.i18n.getMessage(el.dataset.i18nTitle); if (s) el.title = s; } } export function fehlerAnzeigen(text) { const ziel = document.getElementById("meldung"); if (!ziel) return; ziel.className = "fehler"; ziel.textContent = String(text || "").slice(0, 300); } export function meldungAnzeigen(text) { const ziel = document.getElementById("meldung"); if (!ziel) return; ziel.className = "hinweis"; ziel.textContent = String(text || ""); }