diff --git a/public/popup-interceptor.js b/public/popup-interceptor.js new file mode 100644 index 0000000..8281dfb --- /dev/null +++ b/public/popup-interceptor.js @@ -0,0 +1,53 @@ +/** + * Popup Interceptor Script + * This script is injected into proxied pages to intercept window.open calls + * and redirect them to the parent iframe instead of opening new tabs/windows. + * + * The script only runs in iframe contexts and intercepts popups that would + * normally open in new tabs/windows (target="_blank", "_new", or empty). + */ + +(function () { + "use strict"; + + // Only run if we're in an iframe + if (window.self === window.top) { + return; + } + + // Store the original window.open function + const originalWindowOpen = window.open; + + // Override window.open to intercept popup attempts + window.open = function (url, target, features) { + console.log("[Radius] Intercepting window.open:", url, target); + + // If target is _blank, _new, or not specified, intercept it + if (!target || target === "_blank" || target === "_new" || target === "") { + // Send message to parent window to open the URL in the main iframe + try { + window.top.postMessage( + { + type: "radius-popup-intercept", + url: url ? url.toString() : "" + }, + "*" + ); + + console.log("[Radius] Popup intercepted and sent to parent"); + + // Return null since we're not actually opening a new window + return null; + } catch (e) { + console.error("[Radius] Failed to send popup intercept message:", e); + // Fallback to original behavior if messaging fails + return originalWindowOpen.call(this, url, target, features); + } + } + + // For other targets (like named frames), use the original function + return originalWindowOpen.call(this, url, target, features); + }; + + console.log("[Radius] Popup interceptor initialized"); +})(); diff --git a/public/sw.js b/public/sw.js index efad95a..a7e52a6 100644 --- a/public/sw.js +++ b/public/sw.js @@ -59,13 +59,48 @@ self.addEventListener("fetch", function (event) { request = enhanceCaptchaRequest(event.request); } + let response; if (url.startsWith(location.origin + __uv$config.prefix)) { - return await uv.fetch(event); + response = await uv.fetch(event); } else if (sj.route(event)) { - return await sj.fetch(event); + response = await sj.fetch(event); } else { - return await fetch(request); + response = await fetch(request); } + + // Inject popup interceptor script into HTML pages + if (response && response.headers.get("content-type")?.includes("text/html")) { + // Only inject into proxied content + if (url.startsWith(location.origin + __uv$config.prefix) || sj.route(event)) { + try { + const text = await response.text(); + // Inject the popup interceptor script at the beginning of the body or head + const injectedScript = ''; + let modifiedText = text; + + // Try to inject into first, then , then at start of html + if (text.includes("")) { + modifiedText = text.replace("", "" + injectedScript); + } else if (text.includes("")) { + modifiedText = text.replace("", "" + injectedScript); + } else if (text.includes("")) { + modifiedText = text.replace("", "" + injectedScript); + } + + // Create new response with modified content + response = new Response(modifiedText, { + status: response.status, + statusText: response.statusText, + headers: response.headers + }); + } catch (e) { + console.error("[Radius SW] Failed to inject popup interceptor:", e); + // Return original response if injection fails + } + } + } + + return response; })() ); }); diff --git a/src/pages/index.astro b/src/pages/index.astro index 737b9d0..3ecae90 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -32,7 +32,7 @@ const link = Astro.url.searchParams.get("redir"); */} -