New capture-tab capability on the addon-host, and the screenshot add-on
uses it to expose three modes in a sidebar launcher panel:
- Visible viewport: Electron's WebContents.capturePage() on the active tab
- Full scrollable page: temp-resize the tab view to document.scrollHeight,
capturePage, restore
- Region: preload overlays a translucent selection div, tracks mousedown /
move / up, sends the rect back; main takes the visible capture and
crops via nativeImage.crop({x,y,width,height})
Saves land in the user's Downloads folder via session.downloadURL — same
pipeline as any file download, so the download chip picks them up.
Filename: theseus-screenshot-<host>-<ISO date>.png. JPEG option for
smaller files.
A follow-up task (task_b9608dc6) reworks this to open captures in a
full-tab editor with crop / draw / annotate / undo / copy-to-clipboard
instead of the current bare launcher.
49 lines
2.1 KiB
JavaScript
49 lines
2.1 KiB
JavaScript
// Screenshot — capture the active tab. The panel drives everything through
|
|
// two messages ("capture" and "save"); main-side capture-tab does the actual
|
|
// pixel work. This module is a thin router.
|
|
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
|
|
module.exports = {
|
|
activate(api) {
|
|
api.registerSidebarPanel({
|
|
id: "main",
|
|
title: "Screenshot",
|
|
icon: "📸",
|
|
page: "panel.html",
|
|
});
|
|
|
|
// Region-select overlay source, loaded once at activation. The panel
|
|
// triggers region mode; main injects this into the tab and awaits the
|
|
// rect it resolves with. Keeping the DOM code in a sibling file (not a
|
|
// JS string in main) lets someone edit the overlay UX without touching
|
|
// the browser core.
|
|
let overlaySource = "";
|
|
try { overlaySource = fs.readFileSync(path.join(api.folder, "panel-preload.js"), "utf8"); }
|
|
catch (e) { api.log("panel-preload.js not readable:", e?.message); }
|
|
|
|
api.onMessage("capture", async (payload) => {
|
|
const mode = String(payload?.mode || "visible");
|
|
const format = payload?.format === "jpeg" ? "jpeg" : "png";
|
|
const quality = Number(payload?.quality) || 90;
|
|
const opts = { mode, format, quality };
|
|
if (mode === "region") opts.overlaySource = overlaySource;
|
|
return api.captureTab(opts);
|
|
});
|
|
|
|
api.onMessage("save", async (payload) => {
|
|
const dataUrl = String(payload?.dataUrl || "");
|
|
const host = String(payload?.host || "tab");
|
|
const format = payload?.format === "jpeg" ? "jpeg" : "png";
|
|
const ext = format === "jpeg" ? "jpg" : "png";
|
|
// ISO date, but with the colons Windows won't accept in filenames swapped
|
|
// out. Second precision is enough; the filename is human-oriented.
|
|
const iso = new Date().toISOString().replace(/[:.]/g, "-").replace(/-\d{3}Z$/, "Z");
|
|
const safeHost = (host || "tab").replace(/[^a-z0-9._-]+/gi, "_") || "tab";
|
|
const filename = `theseus-screenshot-${safeHost}-${iso}.${ext}`;
|
|
return api.saveCapture({ dataUrl, filename });
|
|
});
|
|
|
|
api.log("registered screenshot panel");
|
|
},
|
|
};
|