pake-cli 0.0.1-beta.9 → 0.0.2

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.
Files changed (90) hide show
  1. package/.ecrc.json +3 -0
  2. package/.editorconfig +24 -0
  3. package/.github/FUNDING.yml +2 -2
  4. package/.github/ISSUE_TEMPLATE/bug.md +13 -0
  5. package/.github/workflows/editorconfig-check.yml +23 -0
  6. package/.github/workflows/main.yml +17 -0
  7. package/.github/workflows/rust-code-quality-check.yml +89 -0
  8. package/.prettierignore +4 -0
  9. package/.vscode/settings.json +3 -6
  10. package/CODE_OF_CONDUCT.md +128 -0
  11. package/CONTRIBUTING.md +26 -0
  12. package/LICENSE +21 -0
  13. package/README.md +195 -54
  14. package/README_EN.md +91 -53
  15. package/app.csv +9 -0
  16. package/bin/README.md +72 -0
  17. package/bin/builders/MacBuilder.ts +14 -15
  18. package/bin/builders/base.ts +10 -1
  19. package/bin/builders/common.ts +9 -4
  20. package/bin/cli.ts +12 -5
  21. package/bin/defaults.ts +1 -0
  22. package/bin/options/icon.ts +38 -46
  23. package/bin/options/index.ts +3 -5
  24. package/bin/types.ts +3 -3
  25. package/bin/utils/shell.ts +9 -8
  26. package/bin/utils/tlds.ts +1489 -0
  27. package/bin/utils/url.ts +26 -0
  28. package/dist/twitter.css +176 -0
  29. package/icns2png.py +38 -0
  30. package/package.json +10 -8
  31. package/pake-default.icns +0 -0
  32. package/rollup.config.js +1 -1
  33. package/script/build.bat +80 -0
  34. package/script/build.sh +122 -0
  35. package/script/sd-apple-x64 +0 -0
  36. package/script/sd-linux-x64 +0 -0
  37. package/script/sd.exe +0 -0
  38. package/src-tauri/Cargo.lock +344 -65
  39. package/src-tauri/Cargo.toml +14 -6
  40. package/src-tauri/assets/com-tw93-weread.desktop +10 -0
  41. package/src-tauri/build.rs +1 -1
  42. package/src-tauri/icons/icon.icns +0 -0
  43. package/src-tauri/icons/reference.icns +0 -0
  44. package/src-tauri/icons/translate.icns +0 -0
  45. package/src-tauri/icons/twitter.icns +0 -0
  46. package/src-tauri/icons/{weRead.icns → weread.icns} +0 -0
  47. package/src-tauri/icons/youtube.icns +0 -0
  48. package/src-tauri/png/code_256.ico +0 -0
  49. package/src-tauri/png/code_32.ico +0 -0
  50. package/src-tauri/png/code_512.png +0 -0
  51. package/src-tauri/png/flomo_256.ico +0 -0
  52. package/src-tauri/png/flomo_32.ico +0 -0
  53. package/src-tauri/png/flomo_512.png +0 -0
  54. package/src-tauri/png/reference_256.ico +0 -0
  55. package/src-tauri/png/reference_32.ico +0 -0
  56. package/src-tauri/png/reference_512.png +0 -0
  57. package/src-tauri/png/tool_256.ico +0 -0
  58. package/src-tauri/png/tool_32.ico +0 -0
  59. package/src-tauri/png/tool_512.png +0 -0
  60. package/src-tauri/png/translate_256.ico +0 -0
  61. package/src-tauri/png/translate_32.ico +0 -0
  62. package/src-tauri/png/translate_512.png +0 -0
  63. package/src-tauri/png/twitter_256.ico +0 -0
  64. package/src-tauri/png/twitter_32.ico +0 -0
  65. package/src-tauri/png/twitter_512.png +0 -0
  66. package/src-tauri/png/weread_256.ico +0 -0
  67. package/src-tauri/png/weread_32.ico +0 -0
  68. package/src-tauri/png/weread_512.png +0 -0
  69. package/src-tauri/png/witeboard_256.ico +0 -0
  70. package/src-tauri/png/witeboard_32.ico +0 -0
  71. package/src-tauri/png/witeboard_512.png +0 -0
  72. package/src-tauri/png/youtube_256.ico +0 -0
  73. package/src-tauri/png/youtube_32.ico +0 -0
  74. package/src-tauri/png/youtube_512.png +0 -0
  75. package/src-tauri/png/yuque_256.ico +0 -0
  76. package/src-tauri/png/yuque_32.ico +0 -0
  77. package/src-tauri/png/yuque_512.png +0 -0
  78. package/src-tauri/src/main.rs +128 -25
  79. package/src-tauri/src/pake.js +140 -77
  80. package/src-tauri/tauri.conf.json +31 -14
  81. package/bin/options/title.ts +0 -14
  82. package/dist/cli.js +0 -399
  83. package/src-tauri/icons/anymind.icns +0 -0
  84. package/src-tauri/icons/fanfou.icns +0 -0
  85. package/src-tauri/icons/fone.icns +0 -0
  86. package/src-tauri/icons/jdread.icns +0 -0
  87. package/src-tauri/icons/jike.icns +0 -0
  88. package/src-tauri/icons/roam.icns +0 -0
  89. package/src-tauri/icons/vercel.icns +0 -0
  90. package/src-tauri/icons/whatsapp.icns +0 -0
@@ -12,14 +12,20 @@ rust-version = "1.61.0"
12
12
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13
13
 
14
14
  [build-dependencies]
15
- tauri-build = { version = "1.1.1", features = [] }
15
+ tauri-build = { version = "1.2.0", features = [] }
16
+
16
17
 
17
18
  [dependencies]
18
- serde_json = "1.0.86"
19
- serde = { version = "1.0.145", features = ["derive"] }
20
- tauri = { version = "1.1.1", features = ["api-all"] }
21
- wry = "0.21.1"
22
- tauri-utils = "1.1.1"
19
+ serde_json = "1.0.88"
20
+ serde = { version = "1.0.147", features = ["derive"] }
21
+ tauri = { version = "1.2.0", features = ["api-all"] }
22
+ image = "0.24.5"
23
+ tauri-utils = "1.2.0"
24
+ webbrowser = "0.8.2"
25
+
26
+ [dependencies.wry]
27
+ git = "https://github.com/tauri-apps/wry.git"
28
+ rev = "7c6d64acea4414f7c960b38b80ea9ec3628db2a8"
23
29
 
24
30
  [features]
25
31
  # by default Tauri runs in production mode
@@ -28,3 +34,5 @@ default = [ "custom-protocol" ]
28
34
  # this feature is used used for production builds where `devPath` points to the filesystem
29
35
  # DO NOT remove this
30
36
  custom-protocol = [ "tauri/custom-protocol" ]
37
+ # Enable DevTools for debugging.
38
+ devtools = []
@@ -0,0 +1,10 @@
1
+ [Desktop Entry]
2
+ Encoding=UTF-8
3
+ Categories=Office
4
+ Exec=com-tw93-weread
5
+ Icon=com-tw93-weread
6
+ Name=com-tw93-weread
7
+ Name[zh_CN]=微信阅读
8
+ StartupNotify=true
9
+ Terminal=false
10
+ Type=Application
@@ -1,3 +1,3 @@
1
1
  fn main() {
2
- tauri_build::build()
2
+ tauri_build::build()
3
3
  }
Binary file
Binary file
Binary file
Binary file
File without changes
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
@@ -1,41 +1,103 @@
1
+ // at the top of main.rs - that will prevent the console from showing
2
+ #![windows_subsystem = "windows"]
3
+ extern crate image;
1
4
  use tauri_utils::config::{Config, WindowConfig};
5
+ #[cfg(target_os = "macos")]
6
+ use wry::application::platform::macos::WindowBuilderExtMacOS;
2
7
 
3
- fn main() -> wry::Result<()> {
4
- use wry::{
5
- application::{
6
- accelerator::{Accelerator, SysMods},
7
- event::{Event, StartCause, WindowEvent},
8
- event_loop::{ControlFlow, EventLoop},
9
- keyboard::KeyCode,
10
- menu::{MenuBar as Menu, MenuItem, MenuItemAttributes, MenuType},
11
- platform::macos::WindowBuilderExtMacOS,
12
- window::{Fullscreen, Window, WindowBuilder},
13
- },
14
- webview::WebViewBuilder,
15
- };
8
+ #[cfg(target_os = "macos")]
9
+ use wry::{
10
+ application::{
11
+ accelerator::{Accelerator, SysMods},
12
+ event::{Event, StartCause, WindowEvent},
13
+ event_loop::{ControlFlow, EventLoop},
14
+ keyboard::KeyCode,
15
+ menu::{MenuBar as Menu, MenuItem, MenuItemAttributes, MenuType},
16
+ window::{Fullscreen, Window, WindowBuilder},
17
+ },
18
+ webview::WebViewBuilder,
19
+ };
20
+
21
+ #[cfg(target_os = "windows")]
22
+ use wry::{
23
+ application::{
24
+ event::{Event, StartCause, WindowEvent},
25
+ event_loop::{ControlFlow, EventLoop},
26
+ menu::MenuType,
27
+ window::{Fullscreen, Icon, Window, WindowBuilder},
28
+ },
29
+ webview::WebViewBuilder,
30
+ };
16
31
 
32
+ #[cfg(target_os = "linux")]
33
+ use wry::{
34
+ application::{
35
+ event::{Event, StartCause, WindowEvent},
36
+ event_loop::{ControlFlow, EventLoop},
37
+ menu::MenuType,
38
+ window::{Fullscreen, Window, WindowBuilder},
39
+ },
40
+ webview::WebViewBuilder,
41
+ };
42
+
43
+ fn main() -> wry::Result<()> {
44
+ #[cfg(target_os = "macos")]
17
45
  let mut menu_bar_menu = Menu::new();
46
+ #[cfg(target_os = "macos")]
18
47
  let mut first_menu = Menu::new();
19
-
48
+ #[cfg(target_os = "macos")]
20
49
  first_menu.add_native_item(MenuItem::Hide);
50
+ #[cfg(target_os = "macos")]
21
51
  first_menu.add_native_item(MenuItem::EnterFullScreen);
52
+ #[cfg(target_os = "macos")]
22
53
  first_menu.add_native_item(MenuItem::Minimize);
54
+ #[cfg(target_os = "macos")]
23
55
  first_menu.add_native_item(MenuItem::Separator);
56
+ #[cfg(target_os = "macos")]
24
57
  first_menu.add_native_item(MenuItem::Copy);
58
+ #[cfg(target_os = "macos")]
25
59
  first_menu.add_native_item(MenuItem::Cut);
60
+ #[cfg(target_os = "macos")]
26
61
  first_menu.add_native_item(MenuItem::Paste);
62
+ #[cfg(target_os = "macos")]
27
63
  first_menu.add_native_item(MenuItem::Undo);
64
+ #[cfg(target_os = "macos")]
28
65
  first_menu.add_native_item(MenuItem::Redo);
66
+ #[cfg(target_os = "macos")]
29
67
  first_menu.add_native_item(MenuItem::SelectAll);
68
+ #[cfg(target_os = "macos")]
30
69
  first_menu.add_native_item(MenuItem::Separator);
70
+
71
+ #[cfg(target_os = "macos")]
31
72
  let close_item = first_menu.add_item(
32
73
  MenuItemAttributes::new("CloseWindow")
33
74
  .with_accelerators(&Accelerator::new(SysMods::Cmd, KeyCode::KeyW)),
34
75
  );
76
+
77
+ #[cfg(target_os = "macos")]
35
78
  first_menu.add_native_item(MenuItem::Quit);
36
79
 
80
+ #[cfg(target_os = "macos")]
37
81
  menu_bar_menu.add_submenu("App", true, first_menu);
38
-
82
+ #[cfg(target_os = "linux")]
83
+ let WindowConfig {
84
+ url,
85
+ width,
86
+ height,
87
+ resizable,
88
+ fullscreen,
89
+ ..
90
+ } = get_windows_config().unwrap_or_default();
91
+ #[cfg(target_os = "windows")]
92
+ let WindowConfig {
93
+ url,
94
+ width,
95
+ height,
96
+ resizable,
97
+ fullscreen,
98
+ ..
99
+ } = get_windows_config().unwrap_or_default();
100
+ #[cfg(target_os = "macos")]
39
101
  let WindowConfig {
40
102
  url,
41
103
  width,
@@ -44,21 +106,38 @@ fn main() -> wry::Result<()> {
44
106
  transparent,
45
107
  fullscreen,
46
108
  ..
47
- } = get_windows_config();
109
+ } = get_windows_config().unwrap_or_default();
48
110
  let event_loop = EventLoop::new();
49
- let window = WindowBuilder::new()
111
+
112
+ let common_window = WindowBuilder::new()
50
113
  .with_resizable(resizable)
51
- .with_titlebar_transparent(transparent)
52
114
  .with_fullscreen(if fullscreen {
53
115
  Some(Fullscreen::Borderless(None))
54
116
  } else {
55
117
  None
56
118
  })
119
+ .with_inner_size(wry::application::dpi::LogicalSize::new(width, height));
120
+ #[cfg(target_os = "windows")]
121
+ let icon = load_icon(std::path::Path::new("png/weread_32.ico"));
122
+
123
+ #[cfg(target_os = "windows")]
124
+ let window = common_window
125
+ .with_decorations(true)
126
+ .with_title("")
127
+ .with_window_icon(Some(icon))
128
+ .build(&event_loop)
129
+ .unwrap();
130
+
131
+ #[cfg(target_os = "linux")]
132
+ let window = common_window.with_title("").build(&event_loop).unwrap();
133
+
134
+ #[cfg(target_os = "macos")]
135
+ let window = common_window
57
136
  .with_fullsize_content_view(true)
58
137
  .with_titlebar_buttons_hidden(false)
138
+ .with_titlebar_transparent(transparent)
59
139
  .with_title_hidden(true)
60
140
  .with_menu(menu_bar_menu)
61
- .with_inner_size(wry::application::dpi::LogicalSize::new(width, height))
62
141
  .build(&event_loop)
63
142
  .unwrap();
64
143
 
@@ -71,17 +150,25 @@ fn main() -> wry::Result<()> {
71
150
  } else {
72
151
  window.set_fullscreen(Some(Fullscreen::Borderless(None)));
73
152
  }
153
+ } else if req.starts_with("open_browser") {
154
+ let href = req.replace("open_browser:", "");
155
+ webbrowser::open(&href).expect("no browser");
74
156
  }
75
157
  };
76
158
 
77
- let _webview = WebViewBuilder::new(window)?
159
+ let webview = WebViewBuilder::new(window)?
78
160
  .with_url(&url.to_string())?
79
- // .with_devtools(true)
161
+ .with_devtools(cfg!(feature = "devtools"))
80
162
  .with_initialization_script(include_str!("pake.js"))
81
163
  .with_ipc_handler(handler)
164
+ .with_back_forward_navigation_gestures(true)
82
165
  .build()?;
83
166
 
84
- // _webview.open_devtools();
167
+ #[cfg(feature = "devtools")]
168
+ {
169
+ webview.open_devtools();
170
+ }
171
+
85
172
  event_loop.run(move |event, _, control_flow| {
86
173
  *control_flow = ControlFlow::Wait;
87
174
 
@@ -96,19 +183,35 @@ fn main() -> wry::Result<()> {
96
183
  origin: MenuType::MenuBar,
97
184
  ..
98
185
  } => {
186
+ #[cfg(target_os = "macos")]
99
187
  if menu_id == close_item.clone().id() {
100
- _webview.window().set_minimized(true);
188
+ webview.window().set_minimized(true);
101
189
  }
102
190
  println!("Clicked on {:?}", menu_id);
191
+ println!("Clicked on {:?}", webview.window().is_visible());
103
192
  }
104
193
  _ => (),
105
194
  }
106
195
  });
107
196
  }
108
197
 
109
- fn get_windows_config() -> WindowConfig {
198
+ fn get_windows_config() -> Option<WindowConfig> {
110
199
  let config_file = include_str!("../tauri.conf.json");
111
200
  let config: Config = serde_json::from_str(config_file).expect("failed to parse windows config");
112
201
 
113
- config.tauri.windows[0].clone()
202
+ config.tauri.windows.first().cloned()
203
+ }
204
+
205
+ #[cfg(target_os = "windows")]
206
+ fn load_icon(path: &std::path::Path) -> Icon {
207
+ let (icon_rgba, icon_width, icon_height) = {
208
+ // alternatively, you can embed the icon in the binary through `include_bytes!` macro and use `image::load_from_memory`
209
+ let image = image::open(path)
210
+ .expect("Failed to open icon path")
211
+ .into_rgba8();
212
+ let (width, height) = image.dimensions();
213
+ let rgba = image.into_raw();
214
+ (rgba, width, height)
215
+ };
216
+ Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon")
114
217
  }
@@ -1,6 +1,60 @@
1
- window.addEventListener('DOMContentLoaded', (_event) => {
2
- const style = document.createElement('style');
3
- style.innerHTML = `
1
+ /**
2
+ * @typedef {string} KeyboardKey `event.key` 的代号,
3
+ * 见 <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
4
+ * @typedef {() => void} OnKeyDown 使用者按下 [CtrlKey] 或者 ⌘ [KeyboardKey]时应该执行的行为
5
+ * 以 Ctrl键或者Meta 键 (⌘) 为首的快捷键清单。
6
+ * 每个写在这里的 shortcuts 都会运行 {@link Event.preventDefault}.
7
+ * @type {Record<KeyboardKey, OnKeyDown>}
8
+ */
9
+
10
+ const metaKeyShortcuts = {
11
+ ArrowUp: () => scrollTo(0, 0),
12
+ ArrowDown: () => scrollTo(0, document.body.scrollHeight),
13
+ "[": () => window.history.back(),
14
+ "]": () => window.history.forward(),
15
+ r: () => window.location.reload(),
16
+ "-": () => zoomOut(),
17
+ "=": () => zoomIn(),
18
+ "+": () => zoomIn(),
19
+ 0: () => zoomCommon(() => "100%"),
20
+ };
21
+
22
+ const ctrlKeyShortcuts = {
23
+ ArrowUp: () => scrollTo(0, 0),
24
+ ArrowDown: () => scrollTo(0, document.body.scrollHeight),
25
+ ArrowLeft: () => window.history.back(),
26
+ ArrowRight: () => window.history.forward(),
27
+ r: () => window.location.reload(),
28
+ "-": () => zoomOut(),
29
+ "=": () => zoomIn(),
30
+ "+": () => zoomIn(),
31
+ 0: () => zoomCommon(() => "100%"),
32
+ };
33
+
34
+ window.addEventListener("DOMContentLoaded", (_event) => {
35
+ const style = document.createElement("style");
36
+ style.innerHTML = `
37
+ #page #footer-wrapper,
38
+ .drawing-board .toolbar .toolbar-action,
39
+ .c-swiper-container,
40
+ .download_entry,
41
+ .lang, .copyright,
42
+ .wwads-cn, .adsbygoogle,
43
+ #Bottom > div.content > div.inner,
44
+ #Rightbar .sep20:nth-of-type(5),
45
+ #Rightbar > div.box:nth-child(4),
46
+ #Main > div.box:nth-child(8) > div
47
+ #Wrapper > div.sep20,
48
+ #Main > div.box:nth-child(8),
49
+ #masthead-ad,
50
+ #Rightbar > div:nth-child(6) > div.sidebar_compliance {
51
+ display: none !important;
52
+ }
53
+
54
+ #page .main_header {
55
+ padding-top: 20px;
56
+ }
57
+
4
58
  .panel.give_me .nav_view {
5
59
  top: 154px !important;
6
60
  }
@@ -9,16 +63,21 @@ window.addEventListener('DOMContentLoaded', (_event) => {
9
63
  padding-top: 30px;
10
64
  }
11
65
 
12
- #page .main_header {
13
- padding-top: 20px;
66
+ ytd-masthead>#container.style-scope.ytd-masthead {
67
+ padding-top: 12px !important;
14
68
  }
15
69
 
16
- #page #footer-wrapper,
17
- .drawing-board .toolbar .toolbar-action,
18
- .c-swiper-container,
19
- .download_entry,
20
- .lang, .copyright {
21
- display: none !important;
70
+ .wrap.h1body-exist.max-container > div.menu-tocs > div.menu-btn{
71
+ top: 28px;
72
+ }
73
+
74
+ #Wrapper{
75
+ background-color: #F8F8F8 !important;
76
+ background-image:none !important;
77
+ }
78
+
79
+ #Top {
80
+ border-bottom: none;
22
81
  }
23
82
 
24
83
  .container-with-note #home, .container-with-note #switcher{
@@ -46,85 +105,89 @@ window.addEventListener('DOMContentLoaded', (_event) => {
46
105
  height: 20px;
47
106
  cursor: grab;
48
107
  cursor: -webkit-grab;
108
+ z-index: 90000;
49
109
  }
50
110
  `;
51
- document.head.append(style);
52
- const topDom = document.createElement("div");
53
- topDom.id = "pack-top-dom"
54
- document.body.appendChild(topDom);
55
-
56
- const domEl = document.getElementById('pack-top-dom');
57
-
58
- domEl.addEventListener('mousedown', (e) => {
59
- if (e.buttons === 1 && e.detail !== 2) {
60
- window.ipc.postMessage('drag_window');
61
- }
62
- })
63
-
64
- domEl.addEventListener('touchstart', (e) => {
65
- window.ipc.postMessage('drag_window');
66
- })
67
-
68
- domEl.addEventListener('dblclick', (e) => {
69
- window.ipc.postMessage('fullscreen');
70
- })
71
-
72
- document.addEventListener('keyup', function (event) {
73
- if (event.key === "ArrowUp" && event.metaKey){
74
- scrollTo(0,0);
75
- }
76
- if (event.key === "ArrowDown" && event.metaKey){
77
- window.scrollTo(0, document.body.scrollHeight);
78
- }
79
- if (event.key === "[" && event.metaKey){
80
- window.history.go(-1);
81
- }
82
- if (event.key === "]" && event.metaKey){
83
- window.history.go(1);
84
- }
85
- if (event.key === "r" && event.metaKey){
86
- window.location.reload();
87
- }
88
- if (event.key === "-" && event.metaKey){
89
- zoomOut();
90
- }
91
- if (event.key === "=" && event.metaKey){
92
- zoomIn();
93
- }
94
- if (event.key === "0" && event.metaKey){
95
- document.getElementsByTagName('html')[0].style.zoom = '100%';
96
- window.localStorage.setItem('htmlZoom', '100%');
97
- }
98
- })
99
-
100
- const pakeLinks = document.links;
101
- for (let linkIndex = 0; linkIndex < pakeLinks.length; linkIndex++) {
102
- pakeLinks[linkIndex].target = '_self';
103
- }
111
+ document.head.append(style);
112
+ const topDom = document.createElement("div");
113
+ topDom.id = "pack-top-dom";
114
+ document.body.appendChild(topDom);
115
+
116
+ const domEl = document.getElementById("pack-top-dom");
104
117
 
118
+ domEl.addEventListener("mousedown", (e) => {
119
+ if (e.buttons === 1 && e.detail !== 2) {
120
+ window.ipc.postMessage("drag_window");
121
+ }
122
+ });
123
+
124
+ domEl.addEventListener("touchstart", () => {
125
+ window.ipc.postMessage("drag_window");
126
+ });
127
+
128
+ domEl.addEventListener("dblclick", () => {
129
+ window.ipc.postMessage("fullscreen");
130
+ });
131
+
132
+ document.addEventListener("keyup", function (event) {
133
+ const preventDefault = (f) => {
134
+ event.preventDefault();
135
+ f();
136
+ };
137
+ if (/windows|linux/i.test(navigator.userAgent)) {
138
+ if (event.ctrlKey && event.key in ctrlKeyShortcuts) {
139
+ preventDefault(ctrlKeyShortcuts[event.key]);
140
+ }
141
+ }
142
+ if (/macintosh|mac os x/i.test(navigator.userAgent)) {
143
+ if (event.metaKey && event.key in metaKeyShortcuts) {
144
+ preventDefault(ctrlKeyShortcuts[event.key]);
145
+ }
146
+ }
147
+ });
148
+
149
+ document.addEventListener("click", (e) => {
150
+ const origin = e.target.closest("a");
151
+ if (origin && origin.href) {
152
+ origin.target = "_self";
153
+
154
+ //额外处理下 twitter 的外跳,对于其他需要外跳的可以改这里成对应域名
155
+ const href = origin.href;
156
+ if (
157
+ location.host === "twitter.com" &&
158
+ href.indexOf("twitter.com") === -1
159
+ ) {
160
+ e.preventDefault();
161
+ window.ipc.postMessage(`open_browser:${href}`);
162
+ }
163
+ }
164
+ });
105
165
  });
106
166
 
107
167
  setDefaultZoom();
108
168
 
109
169
  function setDefaultZoom() {
110
- const htmlZoom = window.localStorage.getItem('htmlZoom');
170
+ const htmlZoom = window.localStorage.getItem("htmlZoom");
111
171
  if (htmlZoom) {
112
- document.getElementsByTagName('html')[0].style.zoom = htmlZoom;
172
+ document.getElementsByTagName("html")[0].style.zoom = htmlZoom;
113
173
  }
114
174
  }
115
175
 
116
- function zoomIn() {
117
- const htmlZoom = window.localStorage.getItem('htmlZoom') || '100%';
118
- const html = document.getElementsByTagName('html')[0];
119
- const zoom = parseInt(htmlZoom) < 200 ? (parseInt(htmlZoom) + 10 +'%') : '200%';
176
+ /**
177
+ * @param {(htmlZoom: string) => string} [zoomRule]
178
+ */
179
+ function zoomCommon(zoomRule) {
180
+ const htmlZoom = window.localStorage.getItem("htmlZoom") || "100%";
181
+ const html = document.getElementsByTagName("html")[0];
182
+ const zoom = zoomRule(htmlZoom);
120
183
  html.style.zoom = zoom;
121
- window.localStorage.setItem('htmlZoom', zoom);
184
+ window.localStorage.setItem("htmlZoom", zoom);
185
+ }
186
+
187
+ function zoomIn() {
188
+ zoomCommon((htmlZoom) => `${Math.min(parseInt(htmlZoom) + 10, 200)}%`);
122
189
  }
123
190
 
124
191
  function zoomOut() {
125
- const htmlZoom = window.localStorage.getItem('htmlZoom') || '100%';
126
- const html = document.getElementsByTagName('html')[0];
127
- const zoom = parseInt(htmlZoom) > 30 ? (parseInt(htmlZoom) - 10 +'%') : '30%';
128
- html.style.zoom = zoom;
129
- window.localStorage.setItem('htmlZoom', zoom);
130
- }
192
+ zoomCommon((htmlZoom) => `${Math.max(parseInt(htmlZoom) - 10, 30)}%`);
193
+ }