pake-cli 3.1.1 → 3.2.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -25
- package/dist/cli.js +145 -81
- package/dist/dev.js +39 -20
- package/dist/dev.js.map +1 -1
- package/package.json +15 -17
- package/src-tauri/.cargo/config.toml +5 -0
- package/src-tauri/Cargo.lock +1337 -1111
- package/src-tauri/Cargo.toml +12 -12
- package/src-tauri/assets/{com-tw93-weread.desktop → com-tw93-weekly.desktop} +4 -4
- package/src-tauri/gen/schemas/acl-manifests.json +1 -1
- package/src-tauri/gen/schemas/desktop-schema.json +906 -421
- package/src-tauri/gen/schemas/macOS-schema.json +906 -421
- package/src-tauri/icons/deepseek.icns +0 -0
- package/src-tauri/icons/grok.icns +0 -0
- package/src-tauri/icons/weekly.icns +0 -0
- package/src-tauri/pake.json +3 -2
- package/src-tauri/png/chatgpt_256.ico +0 -0
- package/src-tauri/png/chatgpt_32.ico +0 -0
- package/src-tauri/png/chatgpt_512.png +0 -0
- package/src-tauri/png/deepseek_256.ico +0 -0
- package/src-tauri/png/deepseek_32.ico +0 -0
- package/src-tauri/png/deepseek_512.png +0 -0
- package/src-tauri/png/excalidraw_256.ico +0 -0
- package/src-tauri/png/excalidraw_32.ico +0 -0
- package/src-tauri/png/excalidraw_512.png +0 -0
- package/src-tauri/png/flomo_256.ico +0 -0
- package/src-tauri/png/flomo_32.ico +0 -0
- package/src-tauri/png/flomo_512.png +0 -0
- package/src-tauri/png/gemini_256.ico +0 -0
- package/src-tauri/png/gemini_32.ico +0 -0
- package/src-tauri/png/gemini_512.png +0 -0
- package/src-tauri/png/grok_256.ico +0 -0
- package/src-tauri/png/grok_32.ico +0 -0
- package/src-tauri/png/grok_512.png +0 -0
- package/src-tauri/png/icon_256.ico +0 -0
- package/src-tauri/png/icon_32.ico +0 -0
- package/src-tauri/png/icon_512.png +0 -0
- package/src-tauri/png/lizhi_256.ico +0 -0
- package/src-tauri/png/lizhi_32.ico +0 -0
- package/src-tauri/png/lizhi_512.png +0 -0
- package/src-tauri/png/programmusic_256.ico +0 -0
- package/src-tauri/png/programmusic_32.ico +0 -0
- package/src-tauri/png/programmusic_512.png +0 -0
- package/src-tauri/png/qwerty_256.ico +0 -0
- package/src-tauri/png/qwerty_32.ico +0 -0
- package/src-tauri/png/qwerty_512.png +0 -0
- package/src-tauri/png/twitter_256.ico +0 -0
- package/src-tauri/png/twitter_32.ico +0 -0
- package/src-tauri/png/twitter_512.png +0 -0
- package/src-tauri/png/wechat_256.ico +0 -0
- package/src-tauri/png/wechat_32.ico +0 -0
- package/src-tauri/png/wechat_512.png +0 -0
- package/src-tauri/png/weekly_256.ico +0 -0
- package/src-tauri/png/weekly_32.ico +0 -0
- package/src-tauri/png/weekly_512.png +0 -0
- package/src-tauri/png/weread_256.ico +0 -0
- package/src-tauri/png/weread_32.ico +0 -0
- package/src-tauri/png/weread_512.png +0 -0
- package/src-tauri/png/xiaohongshu_256.ico +0 -0
- package/src-tauri/png/xiaohongshu_32.ico +0 -0
- package/src-tauri/png/xiaohongshu_512.png +0 -0
- package/src-tauri/png/youtube_256.ico +0 -0
- package/src-tauri/png/youtube_32.ico +0 -0
- package/src-tauri/png/youtube_512.png +0 -0
- package/src-tauri/png/youtubemusic_256.ico +0 -0
- package/src-tauri/png/youtubemusic_32.ico +0 -0
- package/src-tauri/png/youtubemusic_512.png +0 -0
- package/src-tauri/src/app/config.rs +1 -0
- package/src-tauri/src/app/setup.rs +3 -1
- package/src-tauri/src/app/window.rs +25 -3
- package/src-tauri/src/inject/component.js +6 -5
- package/src-tauri/src/inject/event.js +143 -62
- package/src-tauri/src/inject/style.js +29 -8
- package/src-tauri/src/lib.rs +18 -12
- package/src-tauri/src/util.rs +4 -4
- package/src-tauri/tauri.conf.json +3 -3
- package/src-tauri/tauri.linux.conf.json +4 -2
- package/src-tauri/tauri.macos.conf.json +1 -1
- package/src-tauri/tauri.windows.conf.json +2 -2
- package/src-tauri/.pake/pake.json +0 -30
- package/src-tauri/.pake/tauri.conf.json +0 -24
- package/src-tauri/.pake/tauri.macos.conf.json +0 -15
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src-tauri/pake.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"windows": [
|
|
3
3
|
{
|
|
4
|
-
"url": "https://
|
|
4
|
+
"url": "https://weekly.tw93.fun/",
|
|
5
5
|
"url_type": "web",
|
|
6
6
|
"hide_title_bar": true,
|
|
7
7
|
"fullscreen": false,
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"always_on_top": false,
|
|
12
12
|
"dark_mode": false,
|
|
13
13
|
"activation_shortcut": "",
|
|
14
|
-
"disabled_web_shortcuts": false
|
|
14
|
+
"disabled_web_shortcuts": false,
|
|
15
|
+
"hide_on_close": true
|
|
15
16
|
}
|
|
16
17
|
],
|
|
17
18
|
"user_agent": {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -67,7 +67,9 @@ pub fn set_global_shortcut(app: &AppHandle, shortcut: String) -> tauri::Result<(
|
|
|
67
67
|
let last_triggered = Arc::clone(&last_triggered);
|
|
68
68
|
move |app, event, _shortcut| {
|
|
69
69
|
let mut last_triggered = last_triggered.lock().unwrap();
|
|
70
|
-
if Instant::now().duration_since(*last_triggered)
|
|
70
|
+
if Instant::now().duration_since(*last_triggered)
|
|
71
|
+
< Duration::from_millis(300)
|
|
72
|
+
{
|
|
71
73
|
return;
|
|
72
74
|
}
|
|
73
75
|
*last_triggered = Instant::now();
|
|
@@ -6,6 +6,9 @@ use tauri::{App, Config, Url, WebviewUrl, WebviewWindow, WebviewWindowBuilder};
|
|
|
6
6
|
#[cfg(target_os = "macos")]
|
|
7
7
|
use tauri::{Theme, TitleBarStyle};
|
|
8
8
|
|
|
9
|
+
#[cfg(target_os = "windows")]
|
|
10
|
+
use tauri::Theme;
|
|
11
|
+
|
|
9
12
|
pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) -> WebviewWindow {
|
|
10
13
|
let package_name = tauri_config.clone().product_name.unwrap();
|
|
11
14
|
let _data_dir = get_data_dir(app.handle(), package_name);
|
|
@@ -43,9 +46,13 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
|
|
|
43
46
|
.initialization_script(include_str!("../inject/style.js"))
|
|
44
47
|
.initialization_script(include_str!("../inject/custom.js"));
|
|
45
48
|
|
|
49
|
+
// Configure proxy if specified
|
|
46
50
|
if !config.proxy_url.is_empty() {
|
|
47
|
-
|
|
48
|
-
window_builder.proxy_url(
|
|
51
|
+
if let Ok(proxy_url) = Url::from_str(&config.proxy_url) {
|
|
52
|
+
window_builder = window_builder.proxy_url(proxy_url);
|
|
53
|
+
#[cfg(debug_assertions)]
|
|
54
|
+
println!("Proxy configured: {}", config.proxy_url);
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
#[cfg(target_os = "macos")]
|
|
@@ -62,11 +69,26 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
|
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
71
|
|
|
65
|
-
#[cfg(
|
|
72
|
+
#[cfg(target_os = "windows")]
|
|
73
|
+
{
|
|
74
|
+
window_builder = window_builder
|
|
75
|
+
.data_directory(_data_dir)
|
|
76
|
+
.title(app.package_info().name.clone());
|
|
77
|
+
|
|
78
|
+
// Set theme to None for automatic system theme detection on Windows
|
|
79
|
+
// This allows the window to respond to system theme changes automatically
|
|
80
|
+
window_builder = window_builder.theme(None);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#[cfg(target_os = "linux")]
|
|
66
84
|
{
|
|
67
85
|
window_builder = window_builder
|
|
68
86
|
.data_directory(_data_dir)
|
|
69
87
|
.title(app.package_info().name.clone());
|
|
88
|
+
|
|
89
|
+
// Set theme to None for automatic system theme detection on Linux
|
|
90
|
+
// This allows the window to respond to system theme changes automatically
|
|
91
|
+
window_builder = window_builder.theme(None);
|
|
70
92
|
}
|
|
71
93
|
|
|
72
94
|
window_builder.build().expect("Failed to build window")
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
document.addEventListener(
|
|
1
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
2
2
|
// Toast
|
|
3
3
|
function pakeToast(msg) {
|
|
4
|
-
const m = document.createElement(
|
|
4
|
+
const m = document.createElement("div");
|
|
5
5
|
m.innerHTML = msg;
|
|
6
6
|
m.style.cssText =
|
|
7
|
-
|
|
7
|
+
"max-width:60%;min-width: 80px;padding:0 12px;height: 32px;color: rgb(255, 255, 255);line-height: 32px;text-align: center;border-radius: 8px;position: fixed; bottom:24px;right: 28px;z-index: 999999;background: rgba(0, 0, 0,.8);font-size: 13px;";
|
|
8
8
|
document.body.appendChild(m);
|
|
9
9
|
setTimeout(function () {
|
|
10
10
|
const d = 0.5;
|
|
11
|
-
m.style.transition =
|
|
12
|
-
|
|
11
|
+
m.style.transition =
|
|
12
|
+
"transform " + d + "s ease-in, opacity " + d + "s ease-in";
|
|
13
|
+
m.style.opacity = "0";
|
|
13
14
|
setTimeout(function () {
|
|
14
15
|
document.body.removeChild(m);
|
|
15
16
|
}, d * 1000);
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
const shortcuts = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
0: () => setZoom(
|
|
2
|
+
"[": () => window.history.back(),
|
|
3
|
+
"]": () => window.history.forward(),
|
|
4
|
+
"-": () => zoomOut(),
|
|
5
|
+
"=": () => zoomIn(),
|
|
6
|
+
"+": () => zoomIn(),
|
|
7
|
+
0: () => setZoom("100%"),
|
|
8
8
|
r: () => window.location.reload(),
|
|
9
9
|
ArrowUp: () => scrollTo(0, 0),
|
|
10
10
|
ArrowDown: () => scrollTo(0, document.body.scrollHeight),
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
function setZoom(zoom) {
|
|
14
|
-
const html = document.getElementsByTagName(
|
|
14
|
+
const html = document.getElementsByTagName("html")[0];
|
|
15
15
|
html.style.zoom = zoom;
|
|
16
|
-
window.localStorage.setItem(
|
|
16
|
+
window.localStorage.setItem("htmlZoom", zoom);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function zoomCommon(zoomChange) {
|
|
20
|
-
const currentZoom = window.localStorage.getItem(
|
|
20
|
+
const currentZoom = window.localStorage.getItem("htmlZoom") || "100%";
|
|
21
21
|
setZoom(zoomChange(currentZoom));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function zoomIn() {
|
|
25
|
-
zoomCommon(currentZoom => `${Math.min(parseInt(currentZoom) + 10, 200)}%`);
|
|
25
|
+
zoomCommon((currentZoom) => `${Math.min(parseInt(currentZoom) + 10, 200)}%`);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function zoomOut() {
|
|
29
|
-
zoomCommon(currentZoom => `${Math.max(parseInt(currentZoom) - 10, 30)}%`);
|
|
29
|
+
zoomCommon((currentZoom) => `${Math.max(parseInt(currentZoom) - 10, 30)}%`);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function handleShortcut(event) {
|
|
@@ -47,42 +47,45 @@ function isDownloadLink(url) {
|
|
|
47
47
|
'svg', 'swf', 'tar', 'tif', 'tiff', 'ts', 'txt', 'wav', 'webm', 'webp',
|
|
48
48
|
'wma', 'wmv', 'xls', 'xlsx', 'xml', 'zip', 'json', 'yaml', '7zip', 'mkv',
|
|
49
49
|
];
|
|
50
|
-
const downloadLinkPattern = new RegExp(
|
|
50
|
+
const downloadLinkPattern = new RegExp(
|
|
51
|
+
`\\.(${fileExtensions.join("|")})$`,
|
|
52
|
+
"i",
|
|
53
|
+
);
|
|
51
54
|
return downloadLinkPattern.test(url);
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
document.addEventListener(
|
|
57
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
55
58
|
const tauri = window.__TAURI__;
|
|
56
59
|
const appWindow = tauri.window.getCurrentWindow();
|
|
57
60
|
const invoke = tauri.core.invoke;
|
|
58
61
|
|
|
59
|
-
if (!document.getElementById(
|
|
60
|
-
const topDom = document.createElement(
|
|
61
|
-
topDom.id =
|
|
62
|
+
if (!document.getElementById("pake-top-dom")) {
|
|
63
|
+
const topDom = document.createElement("div");
|
|
64
|
+
topDom.id = "pake-top-dom";
|
|
62
65
|
document.body.appendChild(topDom);
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
const domEl = document.getElementById(
|
|
68
|
+
const domEl = document.getElementById("pake-top-dom");
|
|
66
69
|
|
|
67
|
-
domEl.addEventListener(
|
|
70
|
+
domEl.addEventListener("touchstart", () => {
|
|
68
71
|
appWindow.startDragging();
|
|
69
72
|
});
|
|
70
73
|
|
|
71
|
-
domEl.addEventListener(
|
|
74
|
+
domEl.addEventListener("mousedown", (e) => {
|
|
72
75
|
e.preventDefault();
|
|
73
76
|
if (e.buttons === 1 && e.detail !== 2) {
|
|
74
77
|
appWindow.startDragging();
|
|
75
78
|
}
|
|
76
79
|
});
|
|
77
80
|
|
|
78
|
-
domEl.addEventListener(
|
|
79
|
-
appWindow.isFullscreen().then(fullscreen => {
|
|
81
|
+
domEl.addEventListener("dblclick", () => {
|
|
82
|
+
appWindow.isFullscreen().then((fullscreen) => {
|
|
80
83
|
appWindow.setFullscreen(!fullscreen);
|
|
81
84
|
});
|
|
82
85
|
});
|
|
83
86
|
|
|
84
|
-
if (window[
|
|
85
|
-
document.addEventListener(
|
|
87
|
+
if (window["pakeConfig"]?.disabled_web_shortcuts !== true) {
|
|
88
|
+
document.addEventListener("keyup", (event) => {
|
|
86
89
|
if (/windows|linux/i.test(navigator.userAgent) && event.ctrlKey) {
|
|
87
90
|
handleShortcut(event);
|
|
88
91
|
}
|
|
@@ -96,7 +99,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
96
99
|
function collectUrlToBlobs() {
|
|
97
100
|
const backupCreateObjectURL = window.URL.createObjectURL;
|
|
98
101
|
window.blobToUrlCaches = new Map();
|
|
99
|
-
window.URL.createObjectURL = blob => {
|
|
102
|
+
window.URL.createObjectURL = (blob) => {
|
|
100
103
|
const url = backupCreateObjectURL.call(window.URL, blob);
|
|
101
104
|
window.blobToUrlCaches.set(url, blob);
|
|
102
105
|
return url;
|
|
@@ -104,7 +107,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
function convertBlobUrlToBinary(blobUrl) {
|
|
107
|
-
return new Promise(resolve => {
|
|
110
|
+
return new Promise((resolve) => {
|
|
108
111
|
const blob = window.blobToUrlCaches.get(blobUrl);
|
|
109
112
|
const reader = new FileReader();
|
|
110
113
|
|
|
@@ -116,7 +119,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
function downloadFromDataUri(dataURI, filename) {
|
|
119
|
-
const byteString = atob(dataURI.split(
|
|
122
|
+
const byteString = atob(dataURI.split(",")[1]);
|
|
120
123
|
// write the bytes of the string to an ArrayBuffer
|
|
121
124
|
const bufferArray = new ArrayBuffer(byteString.length);
|
|
122
125
|
|
|
@@ -129,7 +132,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
// write the ArrayBuffer to a binary, and you're done
|
|
132
|
-
invoke(
|
|
135
|
+
invoke("download_file_by_binary", {
|
|
133
136
|
params: {
|
|
134
137
|
filename,
|
|
135
138
|
binary: Array.from(binary),
|
|
@@ -138,8 +141,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
function downloadFromBlobUrl(blobUrl, filename) {
|
|
141
|
-
convertBlobUrlToBinary(blobUrl).then(binary => {
|
|
142
|
-
invoke(
|
|
144
|
+
convertBlobUrlToBinary(blobUrl).then((binary) => {
|
|
145
|
+
invoke("download_file_by_binary", {
|
|
143
146
|
params: {
|
|
144
147
|
filename,
|
|
145
148
|
binary,
|
|
@@ -151,20 +154,20 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
151
154
|
// detect blob download by createElement("a")
|
|
152
155
|
function detectDownloadByCreateAnchor() {
|
|
153
156
|
const createEle = document.createElement;
|
|
154
|
-
document.createElement = el => {
|
|
155
|
-
if (el !==
|
|
157
|
+
document.createElement = (el) => {
|
|
158
|
+
if (el !== "a") return createEle.call(document, el);
|
|
156
159
|
const anchorEle = createEle.call(document, el);
|
|
157
160
|
|
|
158
161
|
// use addEventListener to avoid overriding the original click event.
|
|
159
162
|
anchorEle.addEventListener(
|
|
160
|
-
|
|
161
|
-
e => {
|
|
163
|
+
"click",
|
|
164
|
+
(e) => {
|
|
162
165
|
const url = anchorEle.href;
|
|
163
166
|
const filename = anchorEle.download || getFilenameFromUrl(url);
|
|
164
167
|
if (window.blobToUrlCaches.has(url)) {
|
|
165
168
|
downloadFromBlobUrl(url, filename);
|
|
166
169
|
// case: download from dataURL -> convert dataURL ->
|
|
167
|
-
} else if (url.startsWith(
|
|
170
|
+
} else if (url.startsWith("data:")) {
|
|
168
171
|
downloadFromDataUri(url, filename);
|
|
169
172
|
}
|
|
170
173
|
},
|
|
@@ -176,18 +179,42 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
// process special download protocol['data:','blob:']
|
|
179
|
-
const isSpecialDownload = url =>
|
|
182
|
+
const isSpecialDownload = (url) =>
|
|
183
|
+
["blob", "data"].some((protocol) => url.startsWith(protocol));
|
|
180
184
|
|
|
181
|
-
const isDownloadRequired = (url, anchorElement, e) =>
|
|
185
|
+
const isDownloadRequired = (url, anchorElement, e) =>
|
|
186
|
+
anchorElement.download || e.metaKey || e.ctrlKey || isDownloadLink(url);
|
|
182
187
|
|
|
183
|
-
const handleExternalLink = url => {
|
|
184
|
-
invoke(
|
|
188
|
+
const handleExternalLink = (url) => {
|
|
189
|
+
invoke("plugin:shell|open", {
|
|
185
190
|
path: url,
|
|
186
191
|
});
|
|
187
192
|
};
|
|
188
193
|
|
|
189
|
-
|
|
190
|
-
|
|
194
|
+
// Check if URL belongs to the same domain (including subdomains)
|
|
195
|
+
const isSameDomain = (url) => {
|
|
196
|
+
try {
|
|
197
|
+
const linkUrl = new URL(url);
|
|
198
|
+
const currentUrl = new URL(window.location.href);
|
|
199
|
+
|
|
200
|
+
if (linkUrl.hostname === currentUrl.hostname) return true;
|
|
201
|
+
|
|
202
|
+
// Extract root domain (e.g., bilibili.com from www.bilibili.com)
|
|
203
|
+
const getRootDomain = (hostname) => {
|
|
204
|
+
const parts = hostname.split(".");
|
|
205
|
+
return parts.length >= 2 ? parts.slice(-2).join(".") : hostname;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
return (
|
|
209
|
+
getRootDomain(currentUrl.hostname) === getRootDomain(linkUrl.hostname)
|
|
210
|
+
);
|
|
211
|
+
} catch (e) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const detectAnchorElementClick = (e) => {
|
|
217
|
+
const anchorElement = e.target.closest("a");
|
|
191
218
|
|
|
192
219
|
if (anchorElement && anchorElement.href) {
|
|
193
220
|
const target = anchorElement.target;
|
|
@@ -195,28 +222,61 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
195
222
|
const absoluteUrl = hrefUrl.href;
|
|
196
223
|
let filename = anchorElement.download || getFilenameFromUrl(absoluteUrl);
|
|
197
224
|
|
|
198
|
-
//
|
|
199
|
-
if (target ===
|
|
225
|
+
// Handle _blank links: same domain navigates in-app, cross-domain opens new window
|
|
226
|
+
if (target === "_blank") {
|
|
200
227
|
e.preventDefault();
|
|
228
|
+
e.stopImmediatePropagation();
|
|
229
|
+
|
|
230
|
+
if (isSameDomain(absoluteUrl)) {
|
|
231
|
+
window.location.href = absoluteUrl;
|
|
232
|
+
} else {
|
|
233
|
+
const newWindow = originalWindowOpen.call(
|
|
234
|
+
window,
|
|
235
|
+
absoluteUrl,
|
|
236
|
+
"_blank",
|
|
237
|
+
"width=1200,height=800,scrollbars=yes,resizable=yes",
|
|
238
|
+
);
|
|
239
|
+
if (!newWindow) handleExternalLink(absoluteUrl);
|
|
240
|
+
}
|
|
201
241
|
return;
|
|
202
242
|
}
|
|
203
243
|
|
|
204
|
-
if (target ===
|
|
244
|
+
if (target === "_new") {
|
|
205
245
|
e.preventDefault();
|
|
206
246
|
handleExternalLink(absoluteUrl);
|
|
207
247
|
return;
|
|
208
248
|
}
|
|
209
249
|
|
|
210
250
|
// Process download links for Rust to handle.
|
|
211
|
-
if (
|
|
251
|
+
if (
|
|
252
|
+
isDownloadRequired(absoluteUrl, anchorElement, e) &&
|
|
253
|
+
!isSpecialDownload(absoluteUrl)
|
|
254
|
+
) {
|
|
212
255
|
e.preventDefault();
|
|
213
|
-
|
|
256
|
+
e.stopImmediatePropagation();
|
|
257
|
+
invoke("download_file", { params: { url: absoluteUrl, filename } });
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Handle regular links: same domain allows normal navigation, cross-domain opens new window
|
|
262
|
+
if (!target || target === "_self") {
|
|
263
|
+
if (!isSameDomain(absoluteUrl)) {
|
|
264
|
+
e.preventDefault();
|
|
265
|
+
e.stopImmediatePropagation();
|
|
266
|
+
const newWindow = originalWindowOpen.call(
|
|
267
|
+
window,
|
|
268
|
+
absoluteUrl,
|
|
269
|
+
"_blank",
|
|
270
|
+
"width=1200,height=800,scrollbars=yes,resizable=yes",
|
|
271
|
+
);
|
|
272
|
+
if (!newWindow) handleExternalLink(absoluteUrl);
|
|
273
|
+
}
|
|
214
274
|
}
|
|
215
275
|
}
|
|
216
276
|
};
|
|
217
277
|
|
|
218
278
|
// Prevent some special websites from executing in advance, before the click event is triggered.
|
|
219
|
-
document.addEventListener(
|
|
279
|
+
document.addEventListener("click", detectAnchorElementClick, true);
|
|
220
280
|
|
|
221
281
|
collectUrlToBlobs();
|
|
222
282
|
detectDownloadByCreateAnchor();
|
|
@@ -225,14 +285,35 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
225
285
|
const originalWindowOpen = window.open;
|
|
226
286
|
window.open = function (url, name, specs) {
|
|
227
287
|
// Apple login and google login
|
|
228
|
-
if (name ===
|
|
288
|
+
if (name === "AppleAuthentication") {
|
|
229
289
|
//do nothing
|
|
230
|
-
} else if (
|
|
290
|
+
} else if (
|
|
291
|
+
specs &&
|
|
292
|
+
(specs.includes("height=") || specs.includes("width="))
|
|
293
|
+
) {
|
|
231
294
|
location.href = url;
|
|
232
295
|
} else {
|
|
233
296
|
const baseUrl = window.location.origin + window.location.pathname;
|
|
234
297
|
const hrefUrl = new URL(url, baseUrl);
|
|
235
|
-
|
|
298
|
+
const absoluteUrl = hrefUrl.href;
|
|
299
|
+
|
|
300
|
+
// Apply same domain logic as anchor links
|
|
301
|
+
if (isSameDomain(absoluteUrl)) {
|
|
302
|
+
// Same domain: navigate in app or open new window based on specs
|
|
303
|
+
if (name === "_blank" || !name) {
|
|
304
|
+
return originalWindowOpen.call(
|
|
305
|
+
window,
|
|
306
|
+
absoluteUrl,
|
|
307
|
+
"_blank",
|
|
308
|
+
"width=1200,height=800,scrollbars=yes,resizable=yes",
|
|
309
|
+
);
|
|
310
|
+
} else {
|
|
311
|
+
location.href = absoluteUrl;
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
314
|
+
// Cross domain: open in external browser
|
|
315
|
+
handleExternalLink(absoluteUrl);
|
|
316
|
+
}
|
|
236
317
|
}
|
|
237
318
|
// Call the original window.open function to maintain its normal functionality.
|
|
238
319
|
return originalWindowOpen.call(window, url, name, specs);
|
|
@@ -247,27 +328,27 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
247
328
|
|
|
248
329
|
// Fix Chinese input method "Enter" on Safari
|
|
249
330
|
document.addEventListener(
|
|
250
|
-
|
|
251
|
-
e => {
|
|
331
|
+
"keydown",
|
|
332
|
+
(e) => {
|
|
252
333
|
if (e.keyCode === 229) e.stopPropagation();
|
|
253
334
|
},
|
|
254
335
|
true,
|
|
255
336
|
);
|
|
256
337
|
});
|
|
257
338
|
|
|
258
|
-
document.addEventListener(
|
|
259
|
-
let permVal =
|
|
339
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
340
|
+
let permVal = "granted";
|
|
260
341
|
window.Notification = function (title, options) {
|
|
261
342
|
const { invoke } = window.__TAURI__.core;
|
|
262
|
-
const body = options?.body ||
|
|
263
|
-
let icon = options?.icon ||
|
|
343
|
+
const body = options?.body || "";
|
|
344
|
+
let icon = options?.icon || "";
|
|
264
345
|
|
|
265
346
|
// If the icon is a relative path, convert to full path using URI
|
|
266
|
-
if (icon.startsWith(
|
|
347
|
+
if (icon.startsWith("/")) {
|
|
267
348
|
icon = window.location.origin + icon;
|
|
268
349
|
}
|
|
269
350
|
|
|
270
|
-
invoke(
|
|
351
|
+
invoke("send_notification", {
|
|
271
352
|
params: {
|
|
272
353
|
title,
|
|
273
354
|
body,
|
|
@@ -276,19 +357,19 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
276
357
|
});
|
|
277
358
|
};
|
|
278
359
|
|
|
279
|
-
window.Notification.requestPermission = async () =>
|
|
360
|
+
window.Notification.requestPermission = async () => "granted";
|
|
280
361
|
|
|
281
|
-
Object.defineProperty(window.Notification,
|
|
362
|
+
Object.defineProperty(window.Notification, "permission", {
|
|
282
363
|
enumerable: true,
|
|
283
364
|
get: () => permVal,
|
|
284
|
-
set: v => {
|
|
365
|
+
set: (v) => {
|
|
285
366
|
permVal = v;
|
|
286
367
|
},
|
|
287
368
|
});
|
|
288
369
|
});
|
|
289
370
|
|
|
290
371
|
function setDefaultZoom() {
|
|
291
|
-
const htmlZoom = window.localStorage.getItem(
|
|
372
|
+
const htmlZoom = window.localStorage.getItem("htmlZoom");
|
|
292
373
|
if (htmlZoom) {
|
|
293
374
|
setZoom(htmlZoom);
|
|
294
375
|
}
|
|
@@ -296,5 +377,5 @@ function setDefaultZoom() {
|
|
|
296
377
|
|
|
297
378
|
function getFilenameFromUrl(url) {
|
|
298
379
|
const urlPath = new URL(url).pathname;
|
|
299
|
-
return urlPath.substring(urlPath.lastIndexOf(
|
|
380
|
+
return urlPath.substring(urlPath.lastIndexOf("/") + 1);
|
|
300
381
|
}
|