From 1dc647f43b1929f5c4d1af393a90a47f56cb745e Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 23 Mar 2026 22:00:37 -0500 Subject: [PATCH] refac --- .../chat/FileNav/PortPreview.svelte | 130 ++++-------------- 1 file changed, 23 insertions(+), 107 deletions(-) diff --git a/src/lib/components/chat/FileNav/PortPreview.svelte b/src/lib/components/chat/FileNav/PortPreview.svelte index 0e029aa08..9ca442602 100644 --- a/src/lib/components/chat/FileNav/PortPreview.svelte +++ b/src/lib/components/chat/FileNav/PortPreview.svelte @@ -5,6 +5,7 @@ const i18n = getContext('i18n'); + export let baseUrl: string; export let port: number; export let path: string = ''; @@ -23,7 +24,6 @@ $: canGoForward = historyIndex < history.length - 1; const pushHistory = (newPath: string) => { - // Trim forward history when navigating from a non-tip position if (historyIndex < history.length - 1) { history = history.slice(0, historyIndex + 1); } @@ -35,6 +35,7 @@ if (!canGoBack) return; historyIndex -= 1; path = history[historyIndex]; + syncUrlBar(); iframeKey += 1; }; @@ -42,28 +43,26 @@ if (!canGoForward) return; historyIndex += 1; path = history[historyIndex]; + syncUrlBar(); iframeKey += 1; }; // ── URLs ───────────────────────────────────────────────────────────── $: proxyUrl = getPortProxyUrl(baseUrl, port, path); - // The proxy path prefix, e.g. "/proxy/8080/" $: proxyPathPrefix = (() => { try { - return new URL(getPortProxyUrl(baseUrl, port, '')).pathname; + return new URL(getPortProxyUrl(baseUrl, port, ''), window.location.origin).pathname; } catch { return `/proxy/${port}/`; } })(); - // Display-friendly localhost URL for the address bar - $: displayUrl = `localhost:${port}${path ? '/' + path : ''}`; - $: urlInput = displayUrl; + const makeDisplayUrl = (p: string) => `localhost:${port}${p ? '/' + p : ''}`; + const syncUrlBar = () => { urlInput = makeDisplayUrl(path); }; + urlInput = makeDisplayUrl(path); - const refresh = () => { - iframeKey += 1; - }; + const refresh = () => { iframeKey += 1; }; const openExternal = () => { window.open(proxyUrl, '_blank', 'noopener,noreferrer'); @@ -84,113 +83,36 @@ path = newPath; pushHistory(path); } + syncUrlBar(); iframeKey += 1; }; /** - * After each iframe load: - * 1. Sync the address bar with the current iframe path - * 2. Inject a click interceptor to rewrite links BEFORE navigation - * 3. Redirect if the page already escaped the proxy (fallback) + * Read the iframe's current location and sync the URL bar. + * If the iframe escaped the proxy prefix, redirect it back. */ const onIframeLoad = () => { isLoading = false; if (!iframeEl) return; try { - const doc = iframeEl.contentDocument; - const win = iframeEl.contentWindow; - if (!doc || !win) return; - - const loc = win.location; - const iframePath = loc?.pathname ?? ''; - const iframeSearch = loc?.search ?? ''; - const iframeHash = loc?.hash ?? ''; + const loc = iframeEl.contentWindow?.location; + if (!loc) return; + const iframePath = loc.pathname ?? ''; + const iframeSearch = loc.search ?? ''; + const iframeHash = loc.hash ?? ''; if (iframePath.startsWith(proxyPathPrefix)) { - // Still inside the proxy — sync address bar const relativePath = iframePath.slice(proxyPathPrefix.length) + iframeSearch + iframeHash; if (relativePath !== path) { path = relativePath; pushHistory(path); - urlInput = displayUrl; + syncUrlBar(); } - - // Inject click interceptor to rewrite links before navigation - injectLinkInterceptor(doc, win); - } else if (iframePath && iframePath !== 'about:blank') { - // Escaped the proxy — redirect back through it - const escapedPath = iframePath.replace(/^\//, '') + iframeSearch + iframeHash; - const correctedUrl = getPortProxyUrl(baseUrl, port, escapedPath); - loc?.replace(correctedUrl); } } catch { // Cross-origin — can't access } }; - - /** - * Inject a click interceptor into the iframe document that rewrites - * anchor hrefs to stay within the proxy path. - */ - const injectLinkInterceptor = (doc: Document, win: Window) => { - // Skip if we already injected - if ((win as any).__portPreviewIntercepted) return; - (win as any).__portPreviewIntercepted = true; - - const prefix = proxyPathPrefix; - - // Intercept all click events on anchors - doc.addEventListener('click', (e: MouseEvent) => { - const anchor = (e.target as HTMLElement)?.closest?.('a'); - if (!anchor || !anchor.href) return; - - try { - const url = new URL(anchor.href, win.location.href); - - // Only intercept same-origin links that escaped the proxy - if (url.origin === win.location.origin && !url.pathname.startsWith(prefix)) { - e.preventDefault(); - e.stopPropagation(); - // Rewrite to go through proxy - const rewrittenPath = prefix + url.pathname.replace(/^\//, '') + url.search + url.hash; - win.location.href = url.origin + rewrittenPath; - } - } catch { - // Invalid URL — let browser handle it - } - }, true); // Use capture phase to intercept before SPA routers - - // Also intercept form submissions - doc.addEventListener('submit', (e: Event) => { - const form = e.target as HTMLFormElement; - if (!form?.action) return; - - try { - const url = new URL(form.action, win.location.href); - if (url.origin === win.location.origin && !url.pathname.startsWith(prefix)) { - form.action = url.origin + prefix + url.pathname.replace(/^\//, '') + url.search; - } - } catch {} - }, true); - - // Intercept window.open and programmatic navigation - const origOpen = win.open.bind(win); - win.open = function(url?: string | URL, ...args: any[]) { - if (url && typeof url === 'string') { - try { - const parsed = new URL(url, win.location.href); - if (parsed.origin === win.location.origin && !parsed.pathname.startsWith(prefix)) { - url = parsed.origin + prefix + parsed.pathname.replace(/^\//, '') + parsed.search + parsed.hash; - } - } catch {} - } - return origOpen(url, ...args); - }; - }; - - const onIframeLoadStart = () => { - isLoading = true; - };
@@ -230,22 +152,16 @@ - + @@ -275,7 +191,7 @@ - +