Theseus: fix collision blank-page + broken-BCDN-open bugs
Two related bugs both caused by the tab's will-navigate handler racing with
programmatic loads:
Bug A (chip switch BCDN -> ICANN shows blank page, BCDN-priority mode):
fallbackToWeb() calls webContents.loadURL('https://<host>/') to serve the
ICANN version. That fired will-navigate, which saw a dotted host, ran
isBnsHost() -> true, and RE-INVOKED navigateTab() recursively — but the
transient='icann' override had already been consumed, so the recursive call
fell back to bcnr-first, canceling the fallback mid-flight. Tab showed blank
because both loads collided.
Fix: mark programmatic loads with t.internalNav so will-navigate skips them.
Bug B ('Ask each time' -> Open BCDN doesn't load):
Was going through a meta-refresh from bns://collision-choose/ to
bns://<host>/?_collision=bcnr. The meta-refresh bypassed navigateTab, so the
chrome/prov state was never updated (address bar, badges stayed stale).
Fix: will-navigate now catches bns://collision-choose/ FIRST, applies the
remember flag, sets t.collisionOverride, and routes via navigateTab so
chrome + prov update correctly.
Removed the serveBns collision-choose handler + the ?_collision URL-param
path in loadBns (both dead now that will-navigate handles it).
Result:
- Soft-mode 'Open with...' -> Open BCDN loads the BCDN site cleanly.
- Chip switcher flips BCDN <-> ICANN with no blank flash, correct chrome.
This commit is contained in:
parent
bf54c245b7
commit
c3f771ac1c
1 changed files with 29 additions and 29 deletions
58
main.js
58
main.js
|
|
@ -532,34 +532,8 @@ async function serveBns(request) {
|
|||
const host = url.hostname.toLowerCase();
|
||||
const reqPath = decodeURIComponent(url.pathname) || "/";
|
||||
|
||||
// Special host: apply a soft-mode "Open with…" choice submitted by
|
||||
// collision.html, then redirect the tab to the actual target. Persistent
|
||||
// memory (byName/byTld) is written HERE; the one-shot BCDN choice rides
|
||||
// along via a ?_collision=bcnr param that loadBns consumes.
|
||||
if (host === "collision-choose") {
|
||||
const p = url.searchParams;
|
||||
const target = String(p.get("host") || "").toLowerCase();
|
||||
const cTld = String(p.get("tld") || "").toLowerCase();
|
||||
const cChoice = p.get("choice");
|
||||
const cRem = p.get("remember") || "no";
|
||||
const rest = p.get("resturl") || "/";
|
||||
if (cChoice === "bcnr" || cChoice === "icann") {
|
||||
rememberCollision(target, cTld, cChoice, cRem);
|
||||
}
|
||||
let dest;
|
||||
if (cChoice === "icann") {
|
||||
dest = "https://" + target + rest;
|
||||
} else {
|
||||
// BCNR/BCDN: bounce back through the bns:// resolver with a one-shot
|
||||
// marker so loadBns won't re-prompt for this specific load.
|
||||
const sep = rest.includes("?") ? "&" : "?";
|
||||
dest = "bns://" + target + rest + sep + "_collision=bcnr";
|
||||
}
|
||||
const html = `<!doctype html><meta charset="utf-8"><title>Opening…</title>` +
|
||||
`<meta http-equiv="refresh" content="0;url=${dest.replace(/"/g, """)}">` +
|
||||
`<body style="background:#0f1116;color:#9ca3af;font:14px system-ui;padding:24px">Opening ${target}…</body>`;
|
||||
return new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } });
|
||||
}
|
||||
// (bns://collision-choose/ is handled by the will-navigate listener attached
|
||||
// to each tab — it fires BEFORE the request reaches this protocol handler.)
|
||||
|
||||
let rec = entries.get(host);
|
||||
if (!rec) { try { await resolveHost(host); } catch {} rec = entries.get(host); }
|
||||
|
|
@ -778,7 +752,30 @@ function createTab(initial, opts = {}) {
|
|||
wc.on("did-stop-loading", () => setLoading(tab, false));
|
||||
wc.on("will-navigate", (e, u) => {
|
||||
try {
|
||||
// Skip our own programmatic loads. fallbackToWeb calls loadURL("https://<host>/")
|
||||
// and that host is often a BCNR-registered dotted name — without this guard,
|
||||
// isBnsHost() would send us right back into navigateTab, canceling the
|
||||
// fallback (blank-page bug 2026-08-02).
|
||||
if (tab.internalNav) return;
|
||||
const parsed = new URL(u);
|
||||
// Intercept the collision-choose posted by the in-tab "Open with…" page,
|
||||
// apply the remember flag, set a one-shot transient override so loadBns
|
||||
// doesn't re-prompt, and route via navigateTab so chrome/prov stay in sync.
|
||||
if (parsed.protocol === "bns:" && parsed.hostname === "collision-choose") {
|
||||
e.preventDefault();
|
||||
const p = parsed.searchParams;
|
||||
const target = String(p.get("host") || "").toLowerCase();
|
||||
const cTld = String(p.get("tld") || "").toLowerCase();
|
||||
const cChoice = p.get("choice");
|
||||
const cRem = p.get("remember") || "no";
|
||||
const rest = p.get("resturl") || "/";
|
||||
if (!target) return;
|
||||
if (cChoice === "bcnr" || cChoice === "icann") {
|
||||
rememberCollision(target, cTld, cChoice, cRem);
|
||||
tab.collisionOverride = cChoice; // one-shot, consumed by loadBns
|
||||
}
|
||||
return navigateTab(id, target + rest);
|
||||
}
|
||||
if (parsed.protocol === "bns:") return;
|
||||
if (isBnsHost(parsed.hostname)) { e.preventDefault(); navigateTab(id, parsed.hostname + parsed.pathname); }
|
||||
} catch {}
|
||||
|
|
@ -901,7 +898,10 @@ async function loadBns(t, id, host, rest, tld) {
|
|||
if (id === activeId) pushNav({ host, kind: "resolving", tld, registry });
|
||||
const fallbackToWeb = async (reason) => {
|
||||
t.url = "https://" + host + (rest === "/" ? "" : rest);
|
||||
try { await t.view.webContents.loadURL(t.url); } catch {}
|
||||
t.internalNav = true;
|
||||
try { await t.view.webContents.loadURL(t.url); }
|
||||
catch (e) { console.warn("fallback loadURL failed:", e?.message); }
|
||||
finally { t.internalNav = false; }
|
||||
t.prov = { host, kind: "web", note: `fallback: ${reason}`, tld, registry };
|
||||
if (id === activeId) pushNav(t.prov);
|
||||
emitTabs();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue