2026-02-10 14:31:02 +01:00

124 lines
3.3 KiB
JavaScript

const DEFAULT_ENDPOINT = "http://127.0.0.1:8765/screenshot";
function $(id) {
return document.getElementById(id);
}
function setStatus(msg, kind) {
const el = $("status");
el.textContent = msg;
el.className = kind || "";
}
async function storageGet(key) {
return new Promise((resolve) => {
chrome.storage.local.get([key], (res) => resolve(res[key]));
});
}
async function storageSet(obj) {
return new Promise((resolve) => {
chrome.storage.local.set(obj, () => resolve());
});
}
async function getActiveTab() {
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
return tabs[0] || null;
}
async function captureVisibleTab() {
// Defaults to current window when windowId is null.
return await chrome.tabs.captureVisibleTab(null, { format: "png" });
}
async function postScreenshot(endpoint, payload) {
const r = await fetch(endpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
const text = await r.text();
let data = null;
try {
data = JSON.parse(text);
} catch {
// ignore
}
if (!r.ok) {
throw new Error(`HTTP ${r.status}: ${text}`);
}
return data;
}
async function ping(endpoint) {
const base = endpoint.replace(/\/screenshot\s*$/, "");
const r = await fetch(`${base}/health`, { method: "GET" });
if (!r.ok) return `HTTP ${r.status}`;
const j = await r.json();
return j && j.ok ? "ok" : "unexpected_response";
}
async function main() {
const endpointEl = $("endpoint");
const captureBtn = $("capture");
const pingBtn = $("ping");
endpointEl.value = (await storageGet("endpoint")) || DEFAULT_ENDPOINT;
endpointEl.addEventListener("change", async () => {
await storageSet({ endpoint: endpointEl.value.trim() });
});
pingBtn.addEventListener("click", async () => {
const endpoint = endpointEl.value.trim() || DEFAULT_ENDPOINT;
setStatus("Pinging...", "");
const msg = await ping(endpoint);
setStatus(`Ping result: ${msg}`, msg === "ok" ? "ok" : "err");
});
captureBtn.addEventListener("click", async () => {
const endpoint = endpointEl.value.trim() || DEFAULT_ENDPOINT;
captureBtn.disabled = true;
setStatus("Capturing visible tab...", "");
try {
const tab = await getActiveTab();
if (!tab) throw new Error("No active tab found");
const dataUrl = await captureVisibleTab();
setStatus("Uploading to local server...", "");
const resp = await postScreenshot(endpoint, {
data_url: dataUrl,
title: tab.title || "",
url: tab.url || "",
ts: new Date().toISOString(),
});
const lines = [];
lines.push("Saved:");
lines.push(` PNG: ${resp.png_path || "(unknown)"}`);
lines.push(` META: ${resp.meta_path || "(unknown)"}`);
if (resp.ran) {
lines.push("Ran:");
if (resp.ran.error) {
lines.push(` error: ${resp.ran.error}`);
} else {
lines.push(` exit: ${resp.ran.exit_code}`);
if (resp.ran.stdout) lines.push(` stdout: ${resp.ran.stdout.trim()}`);
if (resp.ran.stderr) lines.push(` stderr: ${resp.ran.stderr.trim()}`);
}
}
setStatus(lines.join("\n"), "ok");
} catch (e) {
setStatus(String(e && e.message ? e.message : e), "err");
} finally {
captureBtn.disabled = false;
}
});
}
main();