From b5712cbcc779b555b8f2add2270ba819f22223e2 Mon Sep 17 00:00:00 2001 From: Local Dev Date: Sun, 2 Aug 2026 18:50:58 +0200 Subject: [PATCH] Theseus: 'unsaved changes' confirmation on programmatic navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a will-prevent-unload handler on each tab. When a page has a beforeunload handler that returns non-null (typical for forms with unsaved input, in-browser editors with a dirty document, etc.), Electron would silently cancel any navigation attempt. Now we show a native two-button dialog — 'Stay on page' / 'Leave anyway' — matching how mainstream browsers behave. Works for both user-initiated navigation (link clicks) AND our own programmatic loads (address bar, chip switcher, in-tab collision prompt). Answers the operator's ask: 'only if there is unsaved work that can be lost, should a warning appear' (2026-08-02). --- main.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index 1ac035d..fcca960 100644 --- a/main.js +++ b/main.js @@ -4,7 +4,7 @@ // h, Sia s3, direct ip, redirect u). Tabs, nav controls, a search box, a home // page, and optional Tor onion routing. No system daemon; the app is the trust // boundary. -const { app, BrowserWindow, WebContentsView, ipcMain, protocol, session, Menu, clipboard, nativeTheme, shell } = require("electron"); +const { app, BrowserWindow, WebContentsView, ipcMain, protocol, session, Menu, clipboard, nativeTheme, shell, dialog } = require("electron"); const path = require("path"); const http = require("http"); const https = require("https"); @@ -795,6 +795,24 @@ function createTab(initial, opts = {}) { if (isBnsHost(parsed.hostname)) { e.preventDefault(); navigateTab(id, parsed.hostname + parsed.pathname); } } catch {} }); + // "You have unsaved changes" confirmation: fires when the page's beforeunload + // handler is trying to keep the user on the page (e.g. an unsent form draft, + // an editor with a dirty document). Show a native confirm; on "Leave", call + // preventDefault to override the block. Applies to both link clicks AND our + // programmatic loads (chip switcher, address-bar navigation). + wc.on("will-prevent-unload", (e) => { + const parent = BrowserWindow.getFocusedWindow() || win; + const choice = dialog.showMessageBoxSync(parent, { + type: "question", + buttons: ["Stay on page", "Leave anyway"], + defaultId: 0, + cancelId: 0, + title: "Unsaved changes", + message: "This page is asking you to stay.", + detail: "You may have unsaved changes that will be lost if you leave.", + }); + if (choice === 1) e.preventDefault(); // Leave anyway -> override the beforeunload + }); // Links that open a new tab: target="_blank", window.open, Ctrl/middle-click. wc.setWindowOpenHandler(({ url, disposition }) => { if (url && url !== "about:blank") createTab(url, { background: disposition === "background-tab" });