From 6eb2fbb9ca49b83713392e7314dc26b9e485e777 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 18 Nov 2025 22:36:59 +0000
Subject: [PATCH 1/4] Initial plan
From 8caf5e15a3ea012c620a49a5defc422b67213d2a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 18 Nov 2025 22:46:17 +0000
Subject: [PATCH 2/4] Add window.open and link interception to force URLs to
open in main iframe
Co-authored-by: sriail <225764385+sriail@users.noreply.github.com>
---
public/iframe-intercept.js | 53 +++++++++++++++++
src/pages/index.astro | 117 +++++++++++++++++++++++++++++++++++++
2 files changed, 170 insertions(+)
create mode 100644 public/iframe-intercept.js
diff --git a/public/iframe-intercept.js b/public/iframe-intercept.js
new file mode 100644
index 0000000..e98b48c
--- /dev/null
+++ b/public/iframe-intercept.js
@@ -0,0 +1,53 @@
+// This script intercepts window.open calls and link clicks to force them to open in the parent iframe
+// It must be injected into the iframe context after UV/Scramjet initialization
+
+(function() {
+ 'use strict';
+
+ // Store reference to original window.open
+ const originalWindowOpen = window.open;
+
+ // Override window.open to redirect to parent iframe
+ window.open = function(url, target, features) {
+ if (url && window.parent !== window) {
+ // We're in an iframe, communicate with parent to navigate the iframe
+ try {
+ window.parent.postMessage({
+ type: 'navigate-iframe',
+ url: url.toString()
+ }, '*');
+ // Return null since we're not actually opening a window
+ return null;
+ } catch (e) {
+ console.error('Failed to communicate with parent:', e);
+ }
+ }
+ // Fallback to original behavior if not in iframe or message failed
+ return originalWindowOpen.call(this, url, target, features);
+ };
+
+ // Intercept clicks on links with target="_blank" or similar
+ document.addEventListener('click', function(e) {
+ const anchor = e.target.closest('a');
+ if (anchor && anchor.href) {
+ const target = anchor.getAttribute('target');
+ // Intercept _blank, _new, and other new window targets
+ if (target === '_blank' || target === '_new' || target === '_parent' || target === '_top') {
+ e.preventDefault();
+ e.stopPropagation();
+ // Use window.open override which will message parent
+ window.open(anchor.href);
+ }
+ }
+ }, true); // Use capture phase to intercept early
+
+ // Also set base target to prevent default new window behavior
+ const baseTag = document.querySelector('base');
+ if (!baseTag) {
+ const newBase = document.createElement('base');
+ newBase.target = '_self';
+ document.head.insertBefore(newBase, document.head.firstChild);
+ } else if (!baseTag.hasAttribute('target')) {
+ baseTag.target = '_self';
+ }
+})();
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 737b9d0..1797393 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -36,6 +36,46 @@ const link = Astro.url.searchParams.get("redir");
+
+
+
+
`;
+
+// Helper to inject script into HTML responses
+async function injectInterceptScript(response) {
+ const contentType = response.headers.get('content-type') || '';
+ console.log('[SW] Response content-type:', contentType);
+ if (!contentType.includes('text/html')) {
+ console.log('[SW] Not HTML, skipping injection');
+ return response;
+ }
+
+ try {
+ let text = await response.text();
+ console.log('[SW] Got response text, length:', text.length);
+
+ // Inject the script right after the opening tag or at the start
+ if (text.includes(']*)>/, `${INTERCEPT_SCRIPT}`);
+ console.log('[SW] Injected after tag');
+ } else if (text.includes('
]*)>/, `${INTERCEPT_SCRIPT}`);
+ console.log('[SW] Injected after tag');
+ } else {
+ text = INTERCEPT_SCRIPT + text;
+ console.log('[SW] Injected at start');
+ }
+
+ return new Response(text, {
+ status: response.status,
+ statusText: response.statusText,
+ headers: response.headers
+ });
+ } catch (e) {
+ console.error('[SW] Failed to inject script:', e);
+ return response;
+ }
+}
+
self.addEventListener("fetch", function (event) {
event.respondWith(
(async () => {
@@ -59,13 +145,24 @@ 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);
+ // Inject our script into proxied HTML content
+ if (event.request.destination === 'document' || event.request.destination === 'iframe') {
+ response = await injectInterceptScript(response);
+ }
} else if (sj.route(event)) {
- return await sj.fetch(event);
+ response = await sj.fetch(event);
+ // Inject our script into proxied HTML content
+ if (event.request.destination === 'document' || event.request.destination === 'iframe') {
+ response = await injectInterceptScript(response);
+ }
} else {
- return await fetch(request);
+ response = await fetch(request);
}
+
+ return response;
})()
);
});
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 1797393..1cc77de 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -105,13 +105,16 @@ const link = Astro.url.searchParams.get("redir");
// Listen for messages from iframe to navigate it
window.addEventListener('message', (event) => {
+ console.log('Received message:', event.data);
if (event.data && event.data.type === 'navigate-iframe' && event.data.url) {
// Navigate the iframe to the requested URL
+ console.log('Navigating iframe to:', event.data.url);
iframe.src = sw.encodeURL(event.data.url);
}
// Handle internal navigation requests (from our global window.open override)
if (event.data && event.data.type === 'navigate-iframe-internal' && event.data.url) {
// Navigate the iframe to the requested URL
+ console.log('Navigating iframe (internal) to:', event.data.url);
iframe.classList.remove("hidden");
iframe.src = sw.encodeURL(event.data.url);
}
@@ -169,21 +172,25 @@ const link = Astro.url.searchParams.get("redir");
// Inject the interception script into the iframe
try {
if (iframeWin && iframeWin.document) {
+ console.log("Injecting interception script into iframe");
const script = iframeWin.document.createElement('script');
script.textContent = `
(function() {
'use strict';
+ console.log('[Iframe Intercept] Script loaded');
const originalWindowOpen = window.open;
window.open = function(url, target, features) {
+ console.log('[Iframe Intercept] window.open called with:', url, target);
if (url && window.parent !== window) {
try {
+ console.log('[Iframe Intercept] Sending navigate message to parent');
window.parent.postMessage({
type: 'navigate-iframe',
url: url.toString()
}, '*');
return null;
} catch (e) {
- console.error('Failed to communicate with parent:', e);
+ console.error('[Iframe Intercept] Failed to communicate with parent:', e);
}
}
return originalWindowOpen.call(this, url, target, features);
@@ -193,9 +200,11 @@ const link = Astro.url.searchParams.get("redir");
const anchor = e.target.closest('a');
if (anchor && anchor.href) {
const target = anchor.getAttribute('target');
+ console.log('[Iframe Intercept] Link clicked:', anchor.href, 'target:', target);
if (target === '_blank' || target === '_new' || target === '_parent' || target === '_top') {
e.preventDefault();
e.stopPropagation();
+ console.log('[Iframe Intercept] Intercepting link, calling window.open');
window.open(anchor.href);
}
}
@@ -210,8 +219,10 @@ const link = Astro.url.searchParams.get("redir");
if (document.head) {
document.head.insertBefore(newBase, document.head.firstChild);
}
+ console.log('[Iframe Intercept] Created base tag with target="_self"');
} else if (!baseTag.hasAttribute('target')) {
baseTag.target = '_self';
+ console.log('[Iframe Intercept] Set existing base tag target to "_self"');
}
};
if (document.readyState === 'loading') {
@@ -222,6 +233,7 @@ const link = Astro.url.searchParams.get("redir");
})();
`;
iframeWin.document.head.appendChild(script);
+ console.log("Interception script injected successfully");
}
} catch (e) {
// Cross-origin restrictions may prevent this during initial load
diff --git a/test-page.html b/test-page.html
new file mode 100644
index 0000000..a926afc
--- /dev/null
+++ b/test-page.html
@@ -0,0 +1,25 @@
+
+
+
+ Test Page for Window Open
+
+
+ Test Page
+ This page tests window.open and target="_blank" links.
+
+ Test Links:
+
+
+ Test Buttons:
+
+
+
+
+
+
From dadba8a7d49862101614696c7d3b4d59b3dcab7f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 18 Nov 2025 22:58:17 +0000
Subject: [PATCH 4/4] Remove test file
---
test-page.html | 25 -------------------------
1 file changed, 25 deletions(-)
delete mode 100644 test-page.html
diff --git a/test-page.html b/test-page.html
deleted file mode 100644
index a926afc..0000000
--- a/test-page.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- Test Page for Window Open
-
-
- Test Page
- This page tests window.open and target="_blank" links.
-
- Test Links:
-
-
- Test Buttons:
-
-
-
-
-
-