124 lines
3.3 KiB
JavaScript
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();
|