From eb829ca85cb29721c5f9daae1cf5048dc7915223 Mon Sep 17 00:00:00 2001 From: Tw93 Date: Tue, 11 Nov 2025 15:40:10 +0800 Subject: [PATCH] Support force internal navigation parameter --- bin/cli.ts | 8 ++++++++ bin/defaults.ts | 1 + bin/helpers/merge.ts | 2 ++ bin/types.ts | 3 +++ docs/cli-usage.md | 8 ++++++++ docs/cli-usage_CN.md | 8 ++++++++ src-tauri/pake.json | 3 ++- src-tauri/src/app/config.rs | 2 ++ src-tauri/src/inject/event.js | 24 ++++++++++++++++++++++-- 9 files changed, 56 insertions(+), 3 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index 2a74625..78bc857 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -174,6 +174,14 @@ program .default(DEFAULT.startToTray) .hideHelp(), ) + .addOption( + new Option( + '--force-internal-navigation', + 'Keep every link inside the Pake window instead of opening external handlers', + ) + .default(DEFAULT.forceInternalNavigation) + .hideHelp(), + ) .addOption( new Option('--installer-language ', 'Installer language') .default(DEFAULT.installerLanguage) diff --git a/bin/defaults.ts b/bin/defaults.ts index a78501b..fed0e1c 100644 --- a/bin/defaults.ts +++ b/bin/defaults.ts @@ -30,6 +30,7 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = { keepBinary: false, multiInstance: false, startToTray: false, + forceInternalNavigation: false, }; // Just for cli development diff --git a/bin/helpers/merge.ts b/bin/helpers/merge.ts index 311fd92..dbb3630 100644 --- a/bin/helpers/merge.ts +++ b/bin/helpers/merge.ts @@ -73,6 +73,7 @@ export async function mergeConfig( enableDragDrop, multiInstance, startToTray, + forceInternalNavigation, } = options; const { platform } = process; @@ -96,6 +97,7 @@ export async function mergeConfig( enable_wasm: wasm, enable_drag_drop: enableDragDrop, start_to_tray: startToTray && showSystemTray, + force_internal_navigation: forceInternalNavigation, }; Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions }); diff --git a/bin/types.ts b/bin/types.ts index 4559207..3a521a2 100644 --- a/bin/types.ts +++ b/bin/types.ts @@ -96,6 +96,9 @@ export interface PakeCliOptions { // Start app minimized to tray, default false startToTray: boolean; + + // Force navigation to stay inside the Pake window even for external links + forceInternalNavigation: boolean; } export interface PakeAppOptions extends PakeCliOptions { diff --git a/docs/cli-usage.md b/docs/cli-usage.md index c003a8c..8755c6c 100644 --- a/docs/cli-usage.md +++ b/docs/cli-usage.md @@ -204,6 +204,14 @@ Sets whether to disable web shortcuts in the original Pake container, defaults t --disabled-web-shortcuts ``` +#### [force-internal-navigation] + +Keeps every clicked link (even pointing to other domains) inside the Pake window instead of letting the OS open an external browser or helper. Default is `false`. + +```shell +--force-internal-navigation +``` + #### [multi-arch] Package the application to support both Intel and M1 chips, exclusively for macOS. Default is `false`. diff --git a/docs/cli-usage_CN.md b/docs/cli-usage_CN.md index 6ac2d6b..6090d72 100644 --- a/docs/cli-usage_CN.md +++ b/docs/cli-usage_CN.md @@ -202,6 +202,14 @@ pake https://github.com --name GitHub --disabled-web-shortcuts ``` +#### [force-internal-navigation] + +启用后所有点击的链接(即使是跨域)都会在 Pake 窗口内打开,不会再调用外部浏览器或辅助程序。默认 `false`。 + +```shell +--force-internal-navigation +``` + #### [multi-arch] 设置打包结果同时支持 Intel 和 M1 芯片,仅适用于 macOS,默认为 `false`。 diff --git a/src-tauri/pake.json b/src-tauri/pake.json index 97ad31a..60f9b59 100644 --- a/src-tauri/pake.json +++ b/src-tauri/pake.json @@ -17,7 +17,8 @@ "enable_wasm": false, "enable_drag_drop": false, "maximize": false, - "start_to_tray": false + "start_to_tray": false, + "force_internal_navigation": false } ], "user_agent": { diff --git a/src-tauri/src/app/config.rs b/src-tauri/src/app/config.rs index 9246b7b..2544fb5 100644 --- a/src-tauri/src/app/config.rs +++ b/src-tauri/src/app/config.rs @@ -20,6 +20,8 @@ pub struct WindowConfig { pub enable_wasm: bool, pub enable_drag_drop: bool, pub start_to_tray: bool, + #[serde(default)] + pub force_internal_navigation: bool, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src-tauri/src/inject/event.js b/src-tauri/src/inject/event.js index bfe6dea..54ed16d 100644 --- a/src-tauri/src/inject/event.js +++ b/src-tauri/src/inject/event.js @@ -192,6 +192,8 @@ document.addEventListener("DOMContentLoaded", () => { const tauri = window.__TAURI__; const appWindow = tauri.window.getCurrentWindow(); const invoke = tauri.core.invoke; + const pakeConfig = window["pakeConfig"] || {}; + const forceInternalNavigation = pakeConfig.force_internal_navigation === true; if (!document.getElementById("pake-top-dom")) { const topDom = document.createElement("div"); @@ -394,9 +396,15 @@ document.addEventListener("DOMContentLoaded", () => { // Handle _blank links: same domain navigates in-app, cross-domain opens new window if (target === "_blank") { + if (forceInternalNavigation) { + e.preventDefault(); + e.stopImmediatePropagation(); + window.location.href = absoluteUrl; + return; + } + if (isSameDomain(absoluteUrl)) { - // For same-domain links, let the browser/SPA handle it naturally - // This prevents full page reload in SPA apps like Discord + // For same-domain links, let the browser handle it naturally return; } @@ -413,6 +421,10 @@ document.addEventListener("DOMContentLoaded", () => { } if (target === "_new") { + if (forceInternalNavigation) { + return; + } + e.preventDefault(); handleExternalLink(absoluteUrl); return; @@ -435,6 +447,10 @@ document.addEventListener("DOMContentLoaded", () => { // Handle regular links: same domain allows normal navigation, cross-domain opens new window if (!target || target === "_self") { if (!isSameDomain(absoluteUrl)) { + if (forceInternalNavigation) { + return; + } + e.preventDefault(); e.stopImmediatePropagation(); const newWindow = originalWindowOpen.call( @@ -468,6 +484,10 @@ document.addEventListener("DOMContentLoaded", () => { const absoluteUrl = hrefUrl.href; if (!isSameDomain(absoluteUrl)) { + if (forceInternalNavigation) { + return originalWindowOpen.call(window, absoluteUrl, name, specs); + } + handleExternalLink(absoluteUrl); return null; }