From 915ab8a87a91b4f561c0c9c4d342a71581bae7a4 Mon Sep 17 00:00:00 2001 From: ZDDC Date: Sun, 3 May 2026 18:54:55 -0500 Subject: [PATCH] fix(preview): make HTML iframe links navigate (zddc-server-backed archive) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User report: opening an .html file with a '../.archive/' hyperlink in a new tab works (zddc-server intercepts and serves the right file), but clicking the same link inside the file previewer does nothing. Two combined causes: 1. The previewer's iframe was loaded from a blob: URL (built from the file's bytes). Relative URLs in the iframe resolve relative to the blob URL — '../.archive/X.html' becomes 'blob:.../.archive/ X.html', which is gibberish. The browser never sends a request to the server, so the .archive interception never fires. 2. sandbox="" disables every iframe capability including popups, so even is silently swallowed. Fix per tool: - archive (table.js): for HTML preview, use file.url (the real server URL) directly when available; fall back to blob only for File-System-Access-API mode where there's no server to intercept anyway. Now relative links in archived HTMLs resolve against the actual server origin and the .archive interception fires as designed. Sandbox loosens to allow-same-origin + allow-popups + allow-popups-to-escape-sandbox so resources within the iframe load and link clicks (default target / target=_blank / middle- click) work normally. allow-scripts is intentionally NOT set — archived HTML still cannot run JS in the popup's origin. - transmittal (files-preview.js) + classifier (preview.js): same sandbox loosening for consistency. These tools' files are typically local (FileSystemAccessAPI), so the file.url branch doesn't apply — relative URLs that depend on a server still won't resolve in local mode (intrinsic limitation, no server). Tested behavior preserved: - PDFs: unchanged (no sandbox, browser's PDF viewer handles). - Images / docx / xlsx / tiff / zip / text: unchanged. - HTML in zddc-server-backed archive: relative '../.archive/' links now navigate the iframe to the correct target file. --- archive/js/table.js | 25 ++++++++++++++++++++++--- classifier/js/preview.js | 9 +++++---- transmittal/js/files-preview.js | 15 ++++++++++----- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/archive/js/table.js b/archive/js/table.js index ce5034f..4ee09b3 100644 --- a/archive/js/table.js +++ b/archive/js/table.js @@ -345,9 +345,28 @@ */ async function showFilePreview(file) { const ext = file.extension.toLowerCase(); - + try { - const url = await getFileBlobUrl(file); + // For HTML preview, prefer the file's real server URL over a + // blob URL when available (zddc-server-backed archives have + // file.url set; local FileSystemAccessAPI mode doesn't). + // + // Why it matters: HTML files in an archive often link to + // sibling/parent paths via relative URLs — e.g. + // ../.archive/.html — which zddc-server intercepts + // and resolves. From a blob: URL the relative resolution + // produces blob:.../.archive/X.html, which never reaches the + // server. Loading the iframe from the actual https://zddc.../ + // URL means relative links resolve back to the server and the + // .archive interception fires as designed. + // + // Other types (pdf, images rendered via canvas / iframe etc.) + // are content-only — they don't depend on relative URLs — so + // a blob URL is fine. + const isHtml = ext === 'html' || ext === 'htm'; + const url = (isHtml && file.url) + ? file.url + : await getFileBlobUrl(file); // Mirror the parent window's theme in the popup const parentTheme = document.documentElement.getAttribute('data-theme') || ''; @@ -511,7 +530,7 @@ ${(ext === 'pdf' || ext === 'html' || ext === 'htm') - ? '' + ? '' : '
Loading preview...
'}