From 9d54213ed08fa75b2879da2bb211892b5d6736a1 Mon Sep 17 00:00:00 2001 From: Gagancreates Date: Thu, 11 Jun 2026 01:42:17 +0530 Subject: [PATCH] fix: open links from HTML report iframes in the system browser Links inside the sandboxed iframe that renders a background-task/workspace index.html did nothing on click, unlike the markdown viewer which opens links in the browser. Two causes: target="_blank" links were blocked by the sandbox before reaching the window-open handler, and plain links fire will-frame-navigate (subframe), which the app did not handle (will-navigate only covers the main frame). - Add allow-popups to the HtmlFileViewer iframe sandbox so target="_blank" reaches setWindowOpenHandler, which routes to shell.openExternal. - Handle will-frame-navigate in main, routing external subframe navigations to the system browser. Scoped to app://workspace frames so third-party note embeds (YouTube/Figma/Twitter) keep their internal navigation. --- apps/x/apps/main/src/main.ts | 32 +++++++++++++++---- .../src/components/html-file-viewer.tsx | 7 +++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/x/apps/main/src/main.ts b/apps/x/apps/main/src/main.ts index f4415b5d..40e49e35 100644 --- a/apps/x/apps/main/src/main.ts +++ b/apps/x/apps/main/src/main.ts @@ -253,14 +253,34 @@ function createWindow() { return { action: "deny" }; }); - // Handle navigation to external URLs (e.g., clicking a link without target="_blank") - win.webContents.on("will-navigate", (event, url) => { + // Handle navigation to external URLs (e.g., clicking a link without target="_blank"). + // Returns true when the URL was external and routed to the system browser. + const routeExternalNavigation = (url: string): boolean => { const isInternal = url.startsWith("app://") || url.startsWith("http://localhost:5173"); - if (!isInternal) { - event.preventDefault(); - shell.openExternal(url); - } + if (isInternal) return false; + shell.openExternal(url); + return true; + }; + + win.webContents.on("will-navigate", (event, url) => { + if (routeExternalNavigation(url)) event.preventDefault(); + }); + + // Subframe navigations (e.g. links clicked inside the sandboxed iframe that + // renders a background-task / workspace `index.html`) fire `will-frame-navigate`, + // not `will-navigate`. Route their external links to the system browser too, + // so HTML reports behave like the markdown viewer. Main-frame navigations are + // already handled by `will-navigate` above — skip them here to avoid double-open. + // + // Scope this to our own HTML viewer frames (identified by their app://workspace + // document origin). Third-party note embeds (YouTube, Figma, Twitter via the + // embed/iframe blocks) load from their own origins — leave their internal + // navigation untouched so the embeds keep working. + win.webContents.on("will-frame-navigate", (event) => { + if (event.isMainFrame) return; + if (!event.frame?.url.startsWith("app://workspace/")) return; + if (routeExternalNavigation(event.url)) event.preventDefault(); }); // Attach the embedded browser pane manager to this window. diff --git a/apps/x/apps/renderer/src/components/html-file-viewer.tsx b/apps/x/apps/renderer/src/components/html-file-viewer.tsx index 8343af28..79cccbc7 100644 --- a/apps/x/apps/renderer/src/components/html-file-viewer.tsx +++ b/apps/x/apps/renderer/src/components/html-file-viewer.tsx @@ -110,7 +110,12 @@ export function HtmlFileViewer({ path }: HtmlFileViewerProps) {