diff --git a/bundled-addons/screenshot/addon.json b/bundled-addons/screenshot/addon.json
index b2eeb70..7b12a98 100644
--- a/bundled-addons/screenshot/addon.json
+++ b/bundled-addons/screenshot/addon.json
@@ -1,7 +1,7 @@
{
"id": "screenshot",
"name": "Screenshot",
- "version": "0.2.3",
+ "version": "0.2.4",
"description": "Capture the current tab — visible viewport, entire scrollable page, or a rectangle you draw. Pick a mode from a toolbar dropdown; the capture opens in a full-tab editor (crop, annotate, redact, save).",
"author": "Silent Mode",
"icon": "📸",
diff --git a/bundled-addons/screenshot/editor.js b/bundled-addons/screenshot/editor.js
index 54aad05..fd48a37 100644
--- a/bundled-addons/screenshot/editor.js
+++ b/bundled-addons/screenshot/editor.js
@@ -112,10 +112,38 @@ function loadImage(url) {
}
async function init() {
- if (!srcUrl) { toast("Missing ?src=", true); return; }
+ // Preferred source: a pending capture handed to us through addon storage
+ // (the toolbar-menu capture path). A file:// src won't load — Chromium
+ // treats the editor at file:///…/addons/screenshot/editor.html as a
+ // different origin from the scratch PNG at file:///…/addons-data/…,
+ // so
quietly errors. Storage-based delivery sidesteps the origin
+ // entirely.
+ let dataUrl = null;
+ let toolFromPending = "";
+ let pendingName = baseName;
+ try {
+ if (window.silentmode?.storage) {
+ const pending = await window.silentmode.storage.get("__pending", null);
+ if (pending && pending.dataUrl) {
+ dataUrl = pending.dataUrl;
+ toolFromPending = pending.tool || "";
+ if (pending.name) { pendingName = pending.name; nameEl.textContent = pending.name; document.title = pending.name + " — editor"; }
+ // Clear so a later editor open (e.g. "recent captures") doesn't
+ // accidentally reload the same capture.
+ await window.silentmode.storage.set("__pending", null);
+ }
+ }
+ } catch (e) { console.warn("editor: storage read failed:", e); }
+ // Fallback path — retained so the "openRecent" flow (which currently
+ // still passes ?src=file://) keeps working after we teach it to use
+ // storage too.
+ if (!dataUrl) {
+ if (!srcUrl) { toast("No capture to edit", true); return; }
+ dataUrl = srcUrl;
+ }
let img;
- try { img = await loadImage(srcUrl); }
- catch (e) { toast(e.message, true); return; }
+ try { img = await loadImage(dataUrl); }
+ catch (e) { toast("Couldn't load capture: " + e.message, true); return; }
sizeCanvases(img.naturalWidth, img.naturalHeight);
cctx.drawImage(img, 0, 0);
undo = [];
@@ -123,7 +151,8 @@ async function init() {
pushSnapshot(); // baseline so the very first edit is undoable
updateUndoButtons();
fitBoard();
- if (initialTool) setTool(initialTool);
+ const t = initialTool || toolFromPending;
+ if (t) setTool(t);
}
// Scale the stage to fit within the board when the image is bigger than
diff --git a/bundled-addons/screenshot/index.js b/bundled-addons/screenshot/index.js
index c9c7d1e..22512a1 100644
--- a/bundled-addons/screenshot/index.js
+++ b/bundled-addons/screenshot/index.js
@@ -83,11 +83,20 @@ module.exports = {
recent.unshift({ id: name, name, path: written.path, url: fileUrl(written.path), bytes: written.bytes, at: Date.now(), mode: id });
recent = pruneRecent(recent);
api.storage.set("recent", recent);
+ // Hand the raw data URL to the editor tab through addon storage. We
+ // used to pass `?src=file://…` and let the editor load the scratch
+ // file, but Chromium's file:// origin policy blocks
from
+ // cross-directory file loads: editor.html lives under
+ // /addons/screenshot/ and scratch PNGs land under
+ // /addons-data/screenshot-scratch/, which is a sibling of
+ // the addon dir, and the load quietly fails — the editor initializes
+ // but the image never draws, so every subsequent tool (draw, save,
+ // discard) operates on a still-empty canvas. Storage isn't
+ // origin-scoped, so the editor can pull the data URL out and paint
+ // it locally.
+ api.storage.set("__pending", { name, dataUrl: cap.dataUrl, tool: id === "region" ? "crop" : "", at: Date.now() });
api.log(`captured ${id} → ${name} (${written.bytes} bytes)`);
- // Region mode = land in the crop tool immediately so the user can trim
- // further if the freehand rect was rough.
- const tool = id === "region" ? "crop" : "";
- api.openTab("editor.html", { query: { src: fileUrl(written.path), name, tool } });
+ api.openTab("editor.html", { query: { name } });
return { ok: true, name };
});