🎨 Optimize the code structure
This commit is contained in:
33
README_CN.md
33
README_CN.md
@@ -228,6 +228,13 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
|
|||||||
<sub><b>Pan93412</b></sub>
|
<sub><b>Pan93412</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/jeasonnow">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/16950207?v=4" width="90;" alt="jeasonnow"/>
|
||||||
|
<br />
|
||||||
|
<sub><b>Santree</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/wanghanzhen">
|
<a href="https://github.com/wanghanzhen">
|
||||||
<img src="https://avatars.githubusercontent.com/u/25301012?v=4" width="90;" alt="wanghanzhen"/>
|
<img src="https://avatars.githubusercontent.com/u/25301012?v=4" width="90;" alt="wanghanzhen"/>
|
||||||
@@ -248,15 +255,15 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
|
|||||||
<br />
|
<br />
|
||||||
<sub><b>Essesoul</b></sub>
|
<sub><b>Essesoul</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td></tr>
|
||||||
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/AielloChan">
|
<a href="https://github.com/AielloChan">
|
||||||
<img src="https://avatars.githubusercontent.com/u/7900765?v=4" width="90;" alt="AielloChan"/>
|
<img src="https://avatars.githubusercontent.com/u/7900765?v=4" width="90;" alt="AielloChan"/>
|
||||||
<br />
|
<br />
|
||||||
<sub><b>Aiello</b></sub>
|
<sub><b>Aiello</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td></tr>
|
</td>
|
||||||
<tr>
|
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/m1911star">
|
<a href="https://github.com/m1911star">
|
||||||
<img src="https://avatars.githubusercontent.com/u/4948120?v=4" width="90;" alt="m1911star"/>
|
<img src="https://avatars.githubusercontent.com/u/4948120?v=4" width="90;" alt="m1911star"/>
|
||||||
@@ -271,13 +278,6 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
|
|||||||
<sub><b>Pake Actions</b></sub>
|
<sub><b>Pake Actions</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
|
||||||
<a href="https://github.com/jeasonnow">
|
|
||||||
<img src="https://avatars.githubusercontent.com/u/16950207?v=4" width="90;" alt="jeasonnow"/>
|
|
||||||
<br />
|
|
||||||
<sub><b>Santree</b></sub>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/QingZ11">
|
<a href="https://github.com/QingZ11">
|
||||||
<img src="https://avatars.githubusercontent.com/u/38887077?v=4" width="90;" alt="QingZ11"/>
|
<img src="https://avatars.githubusercontent.com/u/38887077?v=4" width="90;" alt="QingZ11"/>
|
||||||
@@ -328,6 +328,13 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
|
|||||||
<sub><b>Fechin</b></sub>
|
<sub><b>Fechin</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/Milo123459">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/50248166?v=4" width="90;" alt="Milo123459"/>
|
||||||
|
<br />
|
||||||
|
<sub><b>Milo</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/princemaple">
|
<a href="https://github.com/princemaple">
|
||||||
<img src="https://avatars.githubusercontent.com/u/1329716?v=4" width="90;" alt="princemaple"/>
|
<img src="https://avatars.githubusercontent.com/u/1329716?v=4" width="90;" alt="princemaple"/>
|
||||||
@@ -348,15 +355,15 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
|
|||||||
<br />
|
<br />
|
||||||
<sub><b>Null</b></sub>
|
<sub><b>Null</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td></tr>
|
||||||
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/liusishan">
|
<a href="https://github.com/liusishan">
|
||||||
<img src="https://avatars.githubusercontent.com/u/33129823?v=4" width="90;" alt="liusishan"/>
|
<img src="https://avatars.githubusercontent.com/u/33129823?v=4" width="90;" alt="liusishan"/>
|
||||||
<br />
|
<br />
|
||||||
<sub><b>Liusishan</b></sub>
|
<sub><b>Liusishan</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td></tr>
|
</td>
|
||||||
<tr>
|
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/piaoyidage">
|
<a href="https://github.com/piaoyidage">
|
||||||
<img src="https://avatars.githubusercontent.com/u/5135405?v=4" width="90;" alt="piaoyidage"/>
|
<img src="https://avatars.githubusercontent.com/u/5135405?v=4" width="90;" alt="piaoyidage"/>
|
||||||
|
|||||||
4
bin/cli.ts
vendored
4
bin/cli.ts
vendored
@@ -38,8 +38,8 @@ program
|
|||||||
.option('--iter-copy-file', 'Copy files when URL is a local file', DEFAULT.iterCopyFile)
|
.option('--iter-copy-file', 'Copy files when URL is a local file', DEFAULT.iterCopyFile)
|
||||||
.option('--multi-arch', 'Only for Mac, supports both Intel and M1', DEFAULT.multiArch)
|
.option('--multi-arch', 'Only for Mac, supports both Intel and M1', DEFAULT.multiArch)
|
||||||
.option('--targets <string>', 'Only for Linux, option "deb" or "appimage"', DEFAULT.targets)
|
.option('--targets <string>', 'Only for Linux, option "deb" or "appimage"', DEFAULT.targets)
|
||||||
.option('--inject [injects...]', 'Inject .js or .css for this app', DEFAULT.inject)
|
.option('--inject [injects...]', 'Injection of .js or .css Files', DEFAULT.inject)
|
||||||
.option('--safe-domain [domains...]', 'Please enter the security domains that need to be configured', DEFAULT.safeDomain)
|
.option('--safe-domain [domains...]', 'Domains that Require Security Configuration"', DEFAULT.safeDomain)
|
||||||
.option('--debug', 'Debug mode', DEFAULT.debug)
|
.option('--debug', 'Debug mode', DEFAULT.debug)
|
||||||
.version(packageJson.version, '-v, --version', 'Output the current version')
|
.version(packageJson.version, '-v, --version', 'Output the current version')
|
||||||
.action(async (url: string, options: PakeCliOptions) => {
|
.action(async (url: string, options: PakeCliOptions) => {
|
||||||
|
|||||||
6
bin/defaults.ts
vendored
6
bin/defaults.ts
vendored
@@ -19,9 +19,11 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
|
|||||||
safeDomain: [],
|
safeDomain: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
// just for cli development
|
// Just for cli development
|
||||||
export const DEFAULT_DEV_PAKE_OPTIONS: PakeCliOptions & {url: string} = {
|
export const DEFAULT_DEV_PAKE_OPTIONS: PakeCliOptions & {url: string} = {
|
||||||
...DEFAULT_PAKE_OPTIONS,
|
...DEFAULT_PAKE_OPTIONS,
|
||||||
url: 'https://weread.qq.com',
|
url: 'https://weread.qq.com',
|
||||||
name: 'Weread',
|
name: 'WeRead',
|
||||||
|
safeDomain:['weread.qq.com'],
|
||||||
|
transparent: true,
|
||||||
}
|
}
|
||||||
22
dist/cli.js
vendored
22
dist/cli.js
vendored
@@ -11,17 +11,17 @@ import { fileURLToPath } from 'url';
|
|||||||
import dns from 'dns';
|
import dns from 'dns';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
import fs from 'fs';
|
||||||
import updateNotifier from 'update-notifier';
|
import updateNotifier from 'update-notifier';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { dir } from 'tmp-promise';
|
import { dir } from 'tmp-promise';
|
||||||
import { fileTypeFromBuffer } from 'file-type';
|
import { fileTypeFromBuffer } from 'file-type';
|
||||||
import psl from 'psl';
|
import psl from 'psl';
|
||||||
import isUrl from 'is-url';
|
import isUrl from 'is-url';
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
var name = "pake-cli";
|
var name = "pake-cli";
|
||||||
var version = "2.2.5";
|
var version = "2.2.5";
|
||||||
var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 很简单的用 Rust 打包网页生成很小的桌面 App。";
|
var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。";
|
||||||
var engines = {
|
var engines = {
|
||||||
node: ">=16.0.0"
|
node: ">=16.0.0"
|
||||||
};
|
};
|
||||||
@@ -53,12 +53,14 @@ var scripts = {
|
|||||||
start: "npm run dev",
|
start: "npm run dev",
|
||||||
dev: "npm run tauri dev",
|
dev: "npm run tauri dev",
|
||||||
build: "npm run tauri build --release",
|
build: "npm run tauri build --release",
|
||||||
|
"build:debug": "npm run tauri build -- --debug",
|
||||||
"build:mac": "npm run tauri build -- --target universal-apple-darwin",
|
"build:mac": "npm run tauri build -- --target universal-apple-darwin",
|
||||||
"build:all-unix": "chmod +x ./script/build.sh && ./script/build.sh",
|
"build:all-unix": "chmod +x ./script/build.sh && ./script/build.sh",
|
||||||
"build:all-windows": "pwsh ./script/build.ps1",
|
"build:all-windows": "pwsh ./script/build.ps1",
|
||||||
analyze: "cd src-tauri && cargo bloat --release --crates",
|
analyze: "cd src-tauri && cargo bloat --release --crates",
|
||||||
tauri: "tauri",
|
tauri: "tauri",
|
||||||
cli: "rollup -c rollup.config.js --watch",
|
cli: "rollup -c rollup.config.js --watch",
|
||||||
|
"cli:dev": "cross-env NODE_ENV=development rollup -c rollup.config.js -w",
|
||||||
"cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
|
"cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
|
||||||
prepublishOnly: "npm run cli:build"
|
prepublishOnly: "npm run cli:build"
|
||||||
};
|
};
|
||||||
@@ -86,6 +88,7 @@ var devDependencies = {
|
|||||||
"@rollup/plugin-alias": "^4.0.2",
|
"@rollup/plugin-alias": "^4.0.2",
|
||||||
"@rollup/plugin-commonjs": "^23.0.2",
|
"@rollup/plugin-commonjs": "^23.0.2",
|
||||||
"@rollup/plugin-json": "^5.0.2",
|
"@rollup/plugin-json": "^5.0.2",
|
||||||
|
"@rollup/plugin-replace": "^5.0.2",
|
||||||
"@rollup/plugin-terser": "^0.1.0",
|
"@rollup/plugin-terser": "^0.1.0",
|
||||||
"@types/fs-extra": "^9.0.13",
|
"@types/fs-extra": "^9.0.13",
|
||||||
"@types/is-url": "^1.2.30",
|
"@types/is-url": "^1.2.30",
|
||||||
@@ -137,7 +140,7 @@ var user_agent = {
|
|||||||
windows: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
|
windows: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
|
||||||
};
|
};
|
||||||
var menu = {
|
var menu = {
|
||||||
macos: true,
|
macos: false,
|
||||||
linux: false,
|
linux: false,
|
||||||
windows: false
|
windows: false
|
||||||
};
|
};
|
||||||
@@ -146,11 +149,14 @@ var system_tray = {
|
|||||||
linux: true,
|
linux: true,
|
||||||
windows: true
|
windows: true
|
||||||
};
|
};
|
||||||
|
var inject = [
|
||||||
|
];
|
||||||
var pakeConf = {
|
var pakeConf = {
|
||||||
windows: windows,
|
windows: windows,
|
||||||
user_agent: user_agent,
|
user_agent: user_agent,
|
||||||
menu: menu,
|
menu: menu,
|
||||||
system_tray: system_tray
|
system_tray: system_tray,
|
||||||
|
inject: inject
|
||||||
};
|
};
|
||||||
|
|
||||||
var tauri$3 = {
|
var tauri$3 = {
|
||||||
@@ -170,7 +176,7 @@ var tauri$3 = {
|
|||||||
active: false
|
active: false
|
||||||
},
|
},
|
||||||
systemTray: {
|
systemTray: {
|
||||||
iconPath: "png/weread_512.png",
|
iconPath: "png/icon_512.png",
|
||||||
iconAsTemplate: true
|
iconAsTemplate: true
|
||||||
},
|
},
|
||||||
allowlist: {
|
allowlist: {
|
||||||
@@ -619,7 +625,7 @@ async function mergeConfig(url, options, tauriConf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tauriConf.tauri.systemTray.iconPath = trayIconPath;
|
tauriConf.tauri.systemTray.iconPath = trayIconPath;
|
||||||
const injectFilePath = path.join(npmDirectory, `src-tauri/src/inject/_INJECT_.js`);
|
const injectFilePath = path.join(npmDirectory, `src-tauri/src/inject/custom.js`);
|
||||||
// inject js or css files
|
// inject js or css files
|
||||||
if (inject?.length > 0) {
|
if (inject?.length > 0) {
|
||||||
if (!inject.every(item => item.endsWith('.css') || item.endsWith('.js'))) {
|
if (!inject.every(item => item.endsWith('.css') || item.endsWith('.js'))) {
|
||||||
@@ -1023,8 +1029,8 @@ program
|
|||||||
.option('--iter-copy-file', 'Copy files when URL is a local file', DEFAULT_PAKE_OPTIONS.iterCopyFile)
|
.option('--iter-copy-file', 'Copy files when URL is a local file', DEFAULT_PAKE_OPTIONS.iterCopyFile)
|
||||||
.option('--multi-arch', 'Only for Mac, supports both Intel and M1', DEFAULT_PAKE_OPTIONS.multiArch)
|
.option('--multi-arch', 'Only for Mac, supports both Intel and M1', DEFAULT_PAKE_OPTIONS.multiArch)
|
||||||
.option('--targets <string>', 'Only for Linux, option "deb" or "appimage"', DEFAULT_PAKE_OPTIONS.targets)
|
.option('--targets <string>', 'Only for Linux, option "deb" or "appimage"', DEFAULT_PAKE_OPTIONS.targets)
|
||||||
.option('--inject [injects...]', 'inject .js or .css for this app', DEFAULT_PAKE_OPTIONS.inject)
|
.option('--inject [injects...]', 'Injection of .js or .css Files', DEFAULT_PAKE_OPTIONS.inject)
|
||||||
.option('--safe-domain [domains...]', 'domains that can call window.__TAURI__ and use ipc', DEFAULT_PAKE_OPTIONS.safeDomain)
|
.option('--safe-domain [domains...]', 'Domains that Require Security Configuration"', DEFAULT_PAKE_OPTIONS.safeDomain)
|
||||||
.option('--debug', 'Debug mode', DEFAULT_PAKE_OPTIONS.debug)
|
.option('--debug', 'Debug mode', DEFAULT_PAKE_OPTIONS.debug)
|
||||||
.version(packageJson.version, '-v, --version', 'Output the current version')
|
.version(packageJson.version, '-v, --version', 'Output the current version')
|
||||||
.action(async (url, options) => {
|
.action(async (url, options) => {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import {spawn, exec} from 'child_process';
|
import { spawn, exec } from 'child_process';
|
||||||
|
|
||||||
|
|
||||||
// just run in development mode
|
// just run in development mode
|
||||||
export default function pakeCliDevPlugin() {
|
export default function pakeCliDevPlugin() {
|
||||||
@@ -16,7 +15,7 @@ export default function pakeCliDevPlugin() {
|
|||||||
const command = 'node';
|
const command = 'node';
|
||||||
const cliCmdArgs = ['./dist/dev.js'];
|
const cliCmdArgs = ['./dist/dev.js'];
|
||||||
|
|
||||||
cliChildProcess = spawn(command, cliCmdArgs, {detached: true});
|
cliChildProcess = spawn(command, cliCmdArgs, { detached: true });
|
||||||
|
|
||||||
cliChildProcess.stdout.on('data', (data) => {
|
cliChildProcess.stdout.on('data', (data) => {
|
||||||
console.log(chalk.green(data.toString()));
|
console.log(chalk.green(data.toString()));
|
||||||
@@ -45,6 +44,6 @@ export default function pakeCliDevPlugin() {
|
|||||||
process.exit(code);
|
process.exit(code);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
5
rollup.config.js
vendored
5
rollup.config.js
vendored
@@ -25,12 +25,13 @@ export default {
|
|||||||
plugins: [
|
plugins: [
|
||||||
json(),
|
json(),
|
||||||
typescript({
|
typescript({
|
||||||
tsconfig: "tsconfig.json",
|
tsconfig: 'tsconfig.json',
|
||||||
clean: true, // 清理缓存
|
clean: true, // Clear cache
|
||||||
}),
|
}),
|
||||||
commonjs(),
|
commonjs(),
|
||||||
replace({
|
replace({
|
||||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
||||||
|
preventAssignment: true,
|
||||||
}),
|
}),
|
||||||
alias({
|
alias({
|
||||||
entries: [{ find: '@', replacement: path.join(appRootPath.path, 'bin') }],
|
entries: [{ find: '@', replacement: path.join(appRootPath.path, 'bin') }],
|
||||||
|
|||||||
Binary file not shown.
@@ -2,7 +2,7 @@
|
|||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
"url": "https://weread.qq.com/",
|
"url": "https://weread.qq.com/",
|
||||||
"transparent": false,
|
"transparent": true,
|
||||||
"fullscreen": false,
|
"fullscreen": false,
|
||||||
"width": 1200,
|
"width": 1200,
|
||||||
"height": 780,
|
"height": 780,
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ pub fn get_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wind
|
|||||||
.initialization_script(include_str!("../inject/component.js"))
|
.initialization_script(include_str!("../inject/component.js"))
|
||||||
.initialization_script(include_str!("../inject/event.js"))
|
.initialization_script(include_str!("../inject/event.js"))
|
||||||
.initialization_script(include_str!("../inject/style.js"))
|
.initialization_script(include_str!("../inject/style.js"))
|
||||||
.initialization_script(include_str!("../inject/custom.js")); //Very annoying, otherwise dragging files to the window will not work.
|
//This is necessary to allow for file injection by external developers for customization purposes.
|
||||||
|
.initialization_script(include_str!("../inject/custom.js"));
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
|
|||||||
8
src-tauri/src/inject/custom.js
vendored
8
src-tauri/src/inject/custom.js
vendored
@@ -1,2 +1,6 @@
|
|||||||
// This file is used to merge the injected external js and css files
|
/*
|
||||||
// and you can also directly add script files that you want to attach to the application in this fil
|
* This file serves as a collection point for external JS and CSS dependencies.
|
||||||
|
* It amalgamates these external resources for easier injection into the application.
|
||||||
|
* Additionally, you can directly include any script files in this file
|
||||||
|
* that you wish to attach to the application.
|
||||||
|
*/
|
||||||
|
|||||||
187
src-tauri/src/inject/event.js
vendored
187
src-tauri/src/inject/event.js
vendored
@@ -68,95 +68,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
document.body.appendChild(topDom);
|
document.body.appendChild(topDom);
|
||||||
const domEl = document.getElementById('pack-top-dom');
|
const domEl = document.getElementById('pack-top-dom');
|
||||||
|
|
||||||
|
|
||||||
// Collect blob urls to blob by overriding window.URL.createObjectURL
|
|
||||||
function collectUrlToBlobs() {
|
|
||||||
const backupCreateObjectURL = window.URL.createObjectURL;
|
|
||||||
window.blobToUrlCaches = new Map();
|
|
||||||
window.URL.createObjectURL = (blob) => {
|
|
||||||
const url = backupCreateObjectURL.call(window.URL, blob);
|
|
||||||
window.blobToUrlCaches.set(url, blob);
|
|
||||||
return url;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertBlobUrlToBinary(blobUrl) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const blob = window.blobToUrlCaches.get(blobUrl);
|
|
||||||
const reader = new FileReader();
|
|
||||||
|
|
||||||
reader.readAsArrayBuffer(blob);
|
|
||||||
reader.onload = () => {
|
|
||||||
resolve(Array.from(new Uint8Array(reader.result)));
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function downladFromDataUri(dataURI, filename) {
|
|
||||||
const byteString = atob(dataURI.split(',')[1]);
|
|
||||||
// write the bytes of the string to an ArrayBuffer
|
|
||||||
const bufferArray = new ArrayBuffer(byteString.length);
|
|
||||||
|
|
||||||
// create a view into the buffer
|
|
||||||
const binary = new Uint8Array(bufferArray);
|
|
||||||
|
|
||||||
// set the bytes of the buffer to the correct values
|
|
||||||
for (var i = 0; i < byteString.length; i++) {
|
|
||||||
binary[i] = byteString.charCodeAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the ArrayBuffer to a binary, and you're done
|
|
||||||
invoke('download_file_by_binary', {
|
|
||||||
params: {
|
|
||||||
filename,
|
|
||||||
binary: Array.from(binary)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadFromBlobUrl(blobUrl, filename) {
|
|
||||||
convertBlobUrlToBinary(blobUrl).then((binary) => {
|
|
||||||
invoke('download_file_by_binary', {
|
|
||||||
params: {
|
|
||||||
filename,
|
|
||||||
binary
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// detect blob download by createElement("a")
|
|
||||||
function detectDownloadByCreateAnchor() {
|
|
||||||
const createEle = document.createElement;
|
|
||||||
document.createElement = (el) => {
|
|
||||||
if (el !== 'a') return createEle.call(document, el);
|
|
||||||
const anchorEle = createEle.call(document, el);
|
|
||||||
|
|
||||||
// use addEventListener to avoid overriding the original click event.
|
|
||||||
anchorEle.addEventListener('click', (e) => {
|
|
||||||
const url = anchorEle.href;
|
|
||||||
const filename = anchorEle.download || getFilenameFromUrl(url);
|
|
||||||
if (window.blobToUrlCaches.has(url)) {
|
|
||||||
downloadFromBlobUrl(url, filename);
|
|
||||||
// case: downoload from dataURL -> convert dataURL ->
|
|
||||||
} else if (url.startsWith('data:')) {
|
|
||||||
downladFromDataUri(url, filename);
|
|
||||||
} else {
|
|
||||||
handleExternalLink(e, url);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
return anchorEle;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
domEl.addEventListener('touchstart', () => {
|
domEl.addEventListener('touchstart', () => {
|
||||||
appWindow.startDragging().then();
|
appWindow.startDragging().then();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
domEl.addEventListener('mousedown', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (e.buttons === 1 && e.detail !== 2) {
|
||||||
|
appWindow.startDragging().then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
domEl.addEventListener('dblclick', () => {
|
domEl.addEventListener('dblclick', () => {
|
||||||
appWindow.isFullscreen().then((fullscreen) => {
|
appWindow.isFullscreen().then((fullscreen) => {
|
||||||
appWindow.setFullscreen(!fullscreen).then();
|
appWindow.setFullscreen(!fullscreen).then();
|
||||||
@@ -172,8 +94,90 @@ function detectDownloadByCreateAnchor() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Collect blob urls to blob by overriding window.URL.createObjectURL
|
||||||
|
function collectUrlToBlobs() {
|
||||||
|
const backupCreateObjectURL = window.URL.createObjectURL;
|
||||||
|
window.blobToUrlCaches = new Map();
|
||||||
|
window.URL.createObjectURL = (blob) => {
|
||||||
|
const url = backupCreateObjectURL.call(window.URL, blob);
|
||||||
|
window.blobToUrlCaches.set(url, blob);
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertBlobUrlToBinary(blobUrl) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const blob = window.blobToUrlCaches.get(blobUrl);
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.readAsArrayBuffer(blob);
|
||||||
|
reader.onload = () => {
|
||||||
|
resolve(Array.from(new Uint8Array(reader.result)));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadFromDataUri(dataURI, filename) {
|
||||||
|
const byteString = atob(dataURI.split(',')[1]);
|
||||||
|
// write the bytes of the string to an ArrayBuffer
|
||||||
|
const bufferArray = new ArrayBuffer(byteString.length);
|
||||||
|
|
||||||
|
// create a view into the buffer
|
||||||
|
const binary = new Uint8Array(bufferArray);
|
||||||
|
|
||||||
|
// set the bytes of the buffer to the correct values
|
||||||
|
for (let i = 0; i < byteString.length; i++) {
|
||||||
|
binary[i] = byteString.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the ArrayBuffer to a binary, and you're done
|
||||||
|
invoke('download_file_by_binary', {
|
||||||
|
params: {
|
||||||
|
filename,
|
||||||
|
binary: Array.from(binary)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadFromBlobUrl(blobUrl, filename) {
|
||||||
|
convertBlobUrlToBinary(blobUrl).then((binary) => {
|
||||||
|
invoke('download_file_by_binary', {
|
||||||
|
params: {
|
||||||
|
filename,
|
||||||
|
binary
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// detect blob download by createElement("a")
|
||||||
|
function detectDownloadByCreateAnchor() {
|
||||||
|
const createEle = document.createElement;
|
||||||
|
document.createElement = (el) => {
|
||||||
|
if (el !== 'a') return createEle.call(document, el);
|
||||||
|
const anchorEle = createEle.call(document, el);
|
||||||
|
|
||||||
|
// use addEventListener to avoid overriding the original click event.
|
||||||
|
anchorEle.addEventListener('click', (e) => {
|
||||||
|
const url = anchorEle.href;
|
||||||
|
const filename = anchorEle.download || getFilenameFromUrl(url);
|
||||||
|
if (window.blobToUrlCaches.has(url)) {
|
||||||
|
downloadFromBlobUrl(url, filename);
|
||||||
|
// case: download from dataURL -> convert dataURL ->
|
||||||
|
} else if (url.startsWith('data:')) {
|
||||||
|
downloadFromDataUri(url, filename);
|
||||||
|
} else {
|
||||||
|
handleExternalLink(e, url);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
return anchorEle;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const isExternalLink = (url, host) => window.location.host !== host;
|
const isExternalLink = (url, host) => window.location.host !== host;
|
||||||
// process special download protocal['data:','blob:']
|
// process special download protocol['data:','blob:']
|
||||||
const isSpecialDownload = (url) => ['blob', 'data'].some(protocal => url.startsWith(protocal));
|
const isSpecialDownload = (url) => ['blob', 'data'].some(protocal => url.startsWith(protocal));
|
||||||
|
|
||||||
const isDownloadRequired = (url, anchorElement, e) =>
|
const isDownloadRequired = (url, anchorElement, e) =>
|
||||||
@@ -186,7 +190,7 @@ function detectDownloadByCreateAnchor() {
|
|||||||
|
|
||||||
const handleDownloadLink = (e, url, filename) => {
|
const handleDownloadLink = (e, url, filename) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
invoke('download_file', { params: { url, filename } });
|
invoke('download_file', {params: {url, filename}});
|
||||||
};
|
};
|
||||||
|
|
||||||
const detectAnchorElementClick = (e) => {
|
const detectAnchorElementClick = (e) => {
|
||||||
@@ -217,7 +221,7 @@ function detectDownloadByCreateAnchor() {
|
|||||||
|
|
||||||
// Rewrite the window.open function.
|
// Rewrite the window.open function.
|
||||||
const originalWindowOpen = window.open;
|
const originalWindowOpen = window.open;
|
||||||
window.open = function(url, name, specs) {
|
window.open = function (url, name, specs) {
|
||||||
// Apple login and google login
|
// Apple login and google login
|
||||||
if (name === 'AppleAuthentication') {
|
if (name === 'AppleAuthentication') {
|
||||||
//do nothing
|
//do nothing
|
||||||
@@ -257,10 +261,3 @@ function getFilenameFromUrl(url) {
|
|||||||
const urlPath = new URL(url).pathname;
|
const urlPath = new URL(url).pathname;
|
||||||
return urlPath.substring(urlPath.lastIndexOf('/') + 1);
|
return urlPath.substring(urlPath.lastIndexOf('/') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Determine the language of the current system.
|
|
||||||
function getSystemLanguage() {
|
|
||||||
const lang = navigator.language.substr(0, 2);
|
|
||||||
return lang === 'ch' ? 'ch' : 'en';
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,9 +9,7 @@
|
|||||||
"dangerousRemoteDomainIpcAccess": [
|
"dangerousRemoteDomainIpcAccess": [
|
||||||
{
|
{
|
||||||
"domain": "weread.qq.com",
|
"domain": "weread.qq.com",
|
||||||
"windows": [
|
"windows": ["pake"],
|
||||||
"pake"
|
|
||||||
],
|
|
||||||
"enableTauriAPI": true
|
"enableTauriAPI": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -27,9 +25,7 @@
|
|||||||
"all": true,
|
"all": true,
|
||||||
"fs": {
|
"fs": {
|
||||||
"all": true,
|
"all": true,
|
||||||
"scope": [
|
"scope": ["$DOWNLOAD/*"]
|
||||||
"$DOWNLOAD/*"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,9 +17,7 @@
|
|||||||
},
|
},
|
||||||
"resources": [],
|
"resources": [],
|
||||||
"shortDescription": "",
|
"shortDescription": "",
|
||||||
"targets": [
|
"targets": ["dmg"]
|
||||||
"dmg"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user