const extPopup = globalThis.browser ?? globalThis.chrome; function runtimeSend(message) { return new Promise((resolve, reject) => { extPopup.runtime.sendMessage(message, (response) => { const error = extPopup.runtime.lastError; if (error) { reject(new Error(error.message)); return; } resolve(response); }); }); } function hostFromURL(rawURL) { try { return new URL(rawURL).host || rawURL; } catch (_error) { return rawURL || "Current page"; } } function setStatus(title, message, tone) { const card = document.getElementById("status-card"); card.dataset.tone = tone || "neutral"; document.getElementById("status-title").textContent = title; document.getElementById("status-message").textContent = message; } function renderMatches(state) { const root = document.getElementById("matches"); root.textContent = ""; if (!Array.isArray(state.matches) || state.matches.length === 0) { const empty = document.createElement("p"); empty.className = "subtle"; empty.textContent = "No matching entries for this page."; root.appendChild(empty); return; } for (const match of state.matches) { const row = document.createElement("button"); row.type = "button"; row.className = "match-row"; row.innerHTML = ` ${match.title} ${match.username || "No username"} ${match.quality || ""} `; row.addEventListener("click", async () => { row.disabled = true; try { const result = await runtimeSend({ type: "keepassgo-fill-entry", entryId: match.id }); if (!result?.success) { throw new Error(result?.error || "Fill failed."); } setStatus("Filled", `${match.title} was sent to the current page.`, "ready"); } catch (error) { setStatus("Fill failed", error instanceof Error ? error.message : String(error), "error"); } finally { row.disabled = false; } }); root.appendChild(row); } } async function main() { try { const state = await runtimeSend({ type: "keepassgo-popup-state" }); document.getElementById("page-host").textContent = hostFromURL(state.pageUrl || ""); if (!state.configured) { setStatus("Configure access", state.error || "Set the API token in extension settings.", "warning"); renderMatches({ matches: [] }); return; } if (!state.success) { setStatus("KeePassGO unavailable", state.error || "The native host could not reach KeePassGO.", "error"); renderMatches({ matches: [] }); return; } if (state.status?.locked) { setStatus("Vault locked", "Unlock KeePassGO, then open the popup again.", "warning"); renderMatches({ matches: [] }); return; } const count = Array.isArray(state.matches) ? state.matches.length : 0; setStatus("Ready", count === 0 ? "KeePassGO is connected." : `${count} matching entr${count === 1 ? "y" : "ies"} found.`, "ready"); renderMatches(state); } catch (error) { setStatus("Error", error instanceof Error ? error.message : String(error), "error"); renderMatches({ matches: [] }); } } void main();