🔗 fix: resolve link navigation jumping to external browser
• Fixed _blank and search links opening external browser in Pake apps • Enhanced same-domain detection including subdomains • Improved window.open() handling for in-app navigation • Added smart cross-domain routing (new window vs external browser) Resolves issues with Bilibili, YouTube, and other packaged applications where internal links would unexpectedly open in system browser.
This commit is contained in:
57
src-tauri/src/inject/event.js
vendored
57
src-tauri/src/inject/event.js
vendored
@@ -186,6 +186,26 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check if URL belongs to the same domain (including subdomains)
|
||||||
|
const isSameDomain = (url) => {
|
||||||
|
try {
|
||||||
|
const linkUrl = new URL(url);
|
||||||
|
const currentUrl = new URL(window.location.href);
|
||||||
|
|
||||||
|
if (linkUrl.hostname === currentUrl.hostname) return true;
|
||||||
|
|
||||||
|
// Extract root domain (e.g., bilibili.com from www.bilibili.com)
|
||||||
|
const getRootDomain = (hostname) => {
|
||||||
|
const parts = hostname.split('.');
|
||||||
|
return parts.length >= 2 ? parts.slice(-2).join('.') : hostname;
|
||||||
|
};
|
||||||
|
|
||||||
|
return getRootDomain(currentUrl.hostname) === getRootDomain(linkUrl.hostname);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const detectAnchorElementClick = e => {
|
const detectAnchorElementClick = e => {
|
||||||
const anchorElement = e.target.closest('a');
|
const anchorElement = e.target.closest('a');
|
||||||
|
|
||||||
@@ -195,9 +215,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const absoluteUrl = hrefUrl.href;
|
const absoluteUrl = hrefUrl.href;
|
||||||
let filename = anchorElement.download || getFilenameFromUrl(absoluteUrl);
|
let filename = anchorElement.download || getFilenameFromUrl(absoluteUrl);
|
||||||
|
|
||||||
// Handling external link redirection, _blank will automatically open.
|
// Handle _blank links: same domain navigates in-app, cross-domain opens new window
|
||||||
if (target === '_blank') {
|
if (target === '_blank') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
|
||||||
|
if (isSameDomain(absoluteUrl)) {
|
||||||
|
window.location.href = absoluteUrl;
|
||||||
|
} else {
|
||||||
|
const newWindow = originalWindowOpen.call(window, absoluteUrl, '_blank', 'width=1200,height=800,scrollbars=yes,resizable=yes');
|
||||||
|
if (!newWindow) handleExternalLink(absoluteUrl);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +238,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
// Process download links for Rust to handle.
|
// Process download links for Rust to handle.
|
||||||
if (isDownloadRequired(absoluteUrl, anchorElement, e) && !isSpecialDownload(absoluteUrl)) {
|
if (isDownloadRequired(absoluteUrl, anchorElement, e) && !isSpecialDownload(absoluteUrl)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
invoke('download_file', { params: { url: absoluteUrl, filename } });
|
invoke('download_file', { params: { url: absoluteUrl, filename } });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle regular links: same domain allows normal navigation, cross-domain opens new window
|
||||||
|
if (!target || target === '_self') {
|
||||||
|
if (!isSameDomain(absoluteUrl)) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
const newWindow = originalWindowOpen.call(window, absoluteUrl, '_blank', 'width=1200,height=800,scrollbars=yes,resizable=yes');
|
||||||
|
if (!newWindow) handleExternalLink(absoluteUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -232,7 +272,20 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
} else {
|
} else {
|
||||||
const baseUrl = window.location.origin + window.location.pathname;
|
const baseUrl = window.location.origin + window.location.pathname;
|
||||||
const hrefUrl = new URL(url, baseUrl);
|
const hrefUrl = new URL(url, baseUrl);
|
||||||
handleExternalLink(hrefUrl.href);
|
const absoluteUrl = hrefUrl.href;
|
||||||
|
|
||||||
|
// Apply same domain logic as anchor links
|
||||||
|
if (isSameDomain(absoluteUrl)) {
|
||||||
|
// Same domain: navigate in app or open new window based on specs
|
||||||
|
if (name === '_blank' || !name) {
|
||||||
|
return originalWindowOpen.call(window, absoluteUrl, '_blank', 'width=1200,height=800,scrollbars=yes,resizable=yes');
|
||||||
|
} else {
|
||||||
|
location.href = absoluteUrl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Cross domain: open in external browser
|
||||||
|
handleExternalLink(absoluteUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Call the original window.open function to maintain its normal functionality.
|
// Call the original window.open function to maintain its normal functionality.
|
||||||
return originalWindowOpen.call(window, url, name, specs);
|
return originalWindowOpen.call(window, url, name, specs);
|
||||||
|
|||||||
Reference in New Issue
Block a user