fix(theseus/addons): captureTab skips addon-owned tabs
Reported: the Screenshot dropdown produces a blank white PNG "every time".
Verified end-to-end via CDP: the FIRST capture on a real page (silentmode.st)
worked (221 KB, real pixels). Every capture after that came back as a
uniform-white 1920×899 PNG (~24 KB, all bytes 255/255/255/255 confirmed by
canvas getImageData in the editor tab).
Root cause: api.captureTab reads activeTab(), which after the first successful
run is the editor.html tab the add-on just opened. CDP Page.captureScreenshot
on the editor's own tab happily snapshots its still-blank canvas, and the
addon writes that white PNG into scratch → opens a new editor showing it →
next re-capture snapshots THAT editor → all-white feedback loop.
Fix: track the last active tab that isn't an add-on-owned page (or the
Settings tab) in setActive(), and have captureTab fall back to it when the
current active tab has an addonId or settings flag. Last resort: the first
non-addon non-settings tab in the list. If none exists, throw a clear "open
a page you'd like to shoot first" error instead of returning white pixels.
No new capability; no manifest change; addons keep calling
api.captureTab({mode}) exactly as before. Ships in the next Theseus release.
This commit is contained in:
parent
a28c0c5fe4
commit
dc58d0426a
1 changed files with 26 additions and 1 deletions
27
main.js
27
main.js
|
|
@ -1534,8 +1534,24 @@ function initAddons() {
|
|||
// region — run the caller-supplied overlay source in the tab, wait
|
||||
// for a rect (or null = cancel), then capturePage(rect).
|
||||
captureTab: async (opts, addonId) => {
|
||||
const t = activeTab();
|
||||
// Prefer the currently-active tab, BUT if that's an add-on-owned page
|
||||
// (e.g. the screenshot editor is already up when the user re-picks a
|
||||
// mode from the dropdown), fall back to the most-recently-active real
|
||||
// tab. Otherwise a second capture snapshots the editor's still-blank
|
||||
// canvas and every follow-up produces a white PNG.
|
||||
let t = activeTab();
|
||||
if (t && (t.addonId || t.settings)) {
|
||||
const fallback = tabById(lastCapturableTabId);
|
||||
if (fallback && !fallback.addonId && !fallback.settings) t = fallback;
|
||||
else {
|
||||
// Last resort: any non-addon non-settings tab in the list.
|
||||
t = tabs.find((x) => !x.addonId && !x.settings) || t;
|
||||
}
|
||||
}
|
||||
if (!t) throw new Error("no active tab");
|
||||
if (t.addonId || t.settings) {
|
||||
throw new Error("no capturable tab — open a page you'd like to shoot first");
|
||||
}
|
||||
const wc = t.view.webContents;
|
||||
const host = t?.prov?.host || (() => { try { return new URL(wc.getURL()).host; } catch { return ""; } })();
|
||||
const mode = String(opts?.mode || "visible");
|
||||
|
|
@ -1686,6 +1702,11 @@ const tabs = []; // { id, view, title, url, prov }
|
|||
let activeId = null, tabSeq = 0;
|
||||
const tabById = (id) => tabs.find((t) => t.id === id);
|
||||
const activeTab = () => tabById(activeId);
|
||||
// The most-recently-active non-addon tab. captureTab falls back to this when
|
||||
// the currently-active tab is an add-on-owned page (e.g. the screenshot
|
||||
// editor itself) — otherwise a re-triggered capture snapshots the editor's
|
||||
// still-blank canvas instead of the page the user actually wants to shoot.
|
||||
let lastCapturableTabId = null;
|
||||
|
||||
// Provenance goes to BOTH the top chrome (registry badge + site-info panel) and
|
||||
// the bottom status line, so the resolver detail lives on the bottom bar.
|
||||
|
|
@ -2018,6 +2039,10 @@ function setActive(id) {
|
|||
if (target) target.view.setVisible(true);
|
||||
for (const t of tabs) if (t.id !== id) t.view.setVisible(false);
|
||||
const t = activeTab();
|
||||
// Track the last active tab that isn't an add-on-owned page so captureTab
|
||||
// has a sensible fallback when the user re-triggers the dropdown from
|
||||
// inside (say) the screenshot editor.
|
||||
if (t && !t.addonId && !t.settings) lastCapturableTabId = t.id;
|
||||
if (t?.prov) pushNav(t.prov);
|
||||
chrome.webContents.send("bcnr-offer", t?.bcnrOffer ? { host: t.bcnrOffer.host, tld: t.bcnrOffer.tld, registry: REGISTRY } : null);
|
||||
emitTabs();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue