From 9acca818fd768007b27b0a920a2edb4b7f75493f Mon Sep 17 00:00:00 2001 From: jeasonnow Date: Thu, 8 Jun 2023 16:48:19 +0800 Subject: [PATCH] feat: pake can use external scripts --- bin/builders/common.ts | 23 ++++++++ bin/cli.ts | 1 + bin/defaults.ts | 1 + bin/helpers/combine.ts | 17 ++++++ {src-tauri/src => bin}/inject/component.js | 0 {src-tauri/src => bin}/inject/event.js | 1 + {src-tauri/src => bin}/inject/style.js | 0 bin/types.ts | 3 + dist/cli.js | 67 ++++++++++++++++------ src-tauri/src/app/window.rs | 6 +- src-tauri/src/inject/_INJECT_.js | 1 + 11 files changed, 99 insertions(+), 21 deletions(-) create mode 100644 bin/helpers/combine.ts rename {src-tauri/src => bin}/inject/component.js (100%) rename {src-tauri/src => bin}/inject/event.js (99%) rename {src-tauri/src => bin}/inject/style.js (100%) create mode 100644 src-tauri/src/inject/_INJECT_.js diff --git a/bin/builders/common.ts b/bin/builders/common.ts index 7fe7b81..d091290 100644 --- a/bin/builders/common.ts +++ b/bin/builders/common.ts @@ -7,6 +7,7 @@ import {TauriConfig} from 'tauri/src/types'; import { npmDirectory } from '@/utils/dir.js'; import logger from '@/options/logger.js'; +import combineFiles from '@/helpers/combine.js'; type DangerousRemoteDomainIpAccess = { domain: string; @@ -64,6 +65,7 @@ export async function mergeTauriConfig( iterCopyFile, identifier, name, + inject, } = options; const tauriConfWindowOptions = { @@ -298,6 +300,27 @@ export async function mergeTauriConfig( // 设置安全调用 window.__TAURI__ 的安全域名为设置的应用域名 setSecurityConfigWithUrl(tauriConf, url); + // 内部注入文件 + const internalInjectScripts = [ + path.join(npmDirectory, 'bin/inject/component.js'), + path.join(npmDirectory, 'bin/inject/event.js'), + path.join(npmDirectory, 'bin/inject/style.js'), + ]; + + let injectFiles = [...internalInjectScripts]; + // 注入外部 js css + if (inject?.length > 0) { + if (!inject.every(item => item.endsWith('.css') || item.endsWith('.js'))) { + logger.error("The injected file must be in either CSS or JS format."); + return; + } + const files = inject.map(relativePath => path.join(process.cwd(), relativePath)); + injectFiles = injectFiles.concat(...files); + tauriConf.pake.inject = files; + } + combineFiles(injectFiles); + + // 保存配置文件 let configPath = ""; switch (process.platform) { diff --git a/bin/cli.ts b/bin/cli.ts index 35777a9..dbd426d 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -41,6 +41,7 @@ program DEFAULT_PAKE_OPTIONS.targets ) .option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent) + .option('--inject [injects...]', 'inject .js or .css for this app', DEFAULT_PAKE_OPTIONS.inject) .action(async (url: string, options: PakeCliOptions) => { checkUpdateTips(); diff --git a/bin/defaults.ts b/bin/defaults.ts index 48e4972..830f114 100644 --- a/bin/defaults.ts +++ b/bin/defaults.ts @@ -15,6 +15,7 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = { iterCopyFile: false, systemTrayIcon: '', debug: false, + inject: [], }; export const DEFAULT_APP_NAME = 'Pake'; diff --git a/bin/helpers/combine.ts b/bin/helpers/combine.ts new file mode 100644 index 0000000..d2c030f --- /dev/null +++ b/bin/helpers/combine.ts @@ -0,0 +1,17 @@ +import path from 'path'; +import fs from 'fs'; +import { npmDirectory } from '@/utils/dir.js'; + +export default async function combineFiles(files: string[]) { + const output = path.join(npmDirectory, `src-tauri/src/inject/_INJECT_.js`); + + const contents = files.map(file => { + const fileContent = fs.readFileSync(file); + if (file.endsWith('.css')) { + return "window.addEventListener('DOMContentLoaded', (_event) => { const css = `" + fileContent + "`; const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); });"; + } + return fileContent; + }); + fs.writeFileSync(output, contents.join('\n')); + return files; +} \ No newline at end of file diff --git a/src-tauri/src/inject/component.js b/bin/inject/component.js similarity index 100% rename from src-tauri/src/inject/component.js rename to bin/inject/component.js diff --git a/src-tauri/src/inject/event.js b/bin/inject/event.js similarity index 99% rename from src-tauri/src/inject/event.js rename to bin/inject/event.js index 9124802..41ffde8 100644 --- a/src-tauri/src/inject/event.js +++ b/bin/inject/event.js @@ -264,6 +264,7 @@ function convertBlobUrlToBinary(blobUrl) { // detect blob download by createElement("a") function detectDownloadByCreateAnchor() { const createEle = document.createElement; + const tauri = window.__TAURI__; document.createElement = (el) => { if (el !== "a") return createEle.call(document, el); const anchorEle = createEle.call(document, el); diff --git a/src-tauri/src/inject/style.js b/bin/inject/style.js similarity index 100% rename from src-tauri/src/inject/style.js rename to bin/inject/style.js diff --git a/bin/types.ts b/bin/types.ts index 02955f9..778a07f 100644 --- a/bin/types.ts +++ b/bin/types.ts @@ -43,6 +43,9 @@ export interface PakeCliOptions { /** 调试模式,会输出更多日志 */ debug: boolean; + + /** 需要注入页面的外部脚本 */ + inject: string[]; } export interface PakeAppOptions extends PakeCliOptions { diff --git a/dist/cli.js b/dist/cli.js index b6b78a6..4a4514d 100644 --- a/dist/cli.js +++ b/dist/cli.js @@ -9,7 +9,6 @@ import path from 'path'; import fs$1 from 'fs/promises'; import fs2 from 'fs-extra'; import chalk from 'chalk'; -import URL from 'node:url'; import crypto from 'crypto'; import axios from 'axios'; import { fileTypeFromBuffer } from 'file-type'; @@ -35,6 +34,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ +/* global Reflect, Promise */ + function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } @@ -61,6 +62,7 @@ const DEFAULT_PAKE_OPTIONS = { iterCopyFile: false, systemTrayIcon: '', debug: false, + inject: [], }; const tlds = [ @@ -1629,6 +1631,21 @@ const logger = { } }; +function combineFiles(files) { + return __awaiter(this, void 0, void 0, function* () { + const output = path.join(npmDirectory, `src-tauri/src/inject/_INJECT_.js`); + const contents = files.map(file => { + const fileContent = fs.readFileSync(file); + if (file.endsWith('.css')) { + return "window.addEventListener('DOMContentLoaded', (_event) => { const css = `" + fileContent + "`; const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); });"; + } + return fileContent; + }); + fs.writeFileSync(output, contents.join('\n')); + return files; + }); +} + function promptText(message, initial) { return __awaiter(this, void 0, void 0, function* () { const response = yield prompts({ @@ -1641,12 +1658,17 @@ function promptText(message, initial) { }); } function setSecurityConfigWithUrl(tauriConfig, url) { - const { hostname } = URL.parse(url); - tauriConfig.tauri.security.dangerousRemoteDomainIpcAccess[0].domain = hostname; + const myURL = new URL(url); + const currentUrlConfig = { + domain: myURL.hostname, + windows: ["pake"], + enableTauriAPI: true, + }; + tauriConfig.tauri.security.dangerousRemoteDomainIpcAccess = [currentUrlConfig]; } function mergeTauriConfig(url, options, tauriConf) { return __awaiter(this, void 0, void 0, function* () { - const { width, height, fullscreen, transparent, resizable, userAgent, showMenu, showSystemTray, systemTrayIcon, iterCopyFile, identifier, name, } = options; + const { width, height, fullscreen, transparent, resizable, userAgent, showMenu, showSystemTray, systemTrayIcon, iterCopyFile, identifier, name, inject, } = options; const tauriConfWindowOptions = { width, height, @@ -1869,6 +1891,24 @@ function mergeTauriConfig(url, options, tauriConf) { } // 设置安全调用 window.__TAURI__ 的安全域名为设置的应用域名 setSecurityConfigWithUrl(tauriConf, url); + // 内部注入文件 + const internalInjectScripts = [ + path.join(npmDirectory, 'bin/inject/component.js'), + path.join(npmDirectory, 'bin/inject/event.js'), + path.join(npmDirectory, 'bin/inject/style.js'), + ]; + let injectFiles = [...internalInjectScripts]; + // 注入外部 js css + if ((inject === null || inject === void 0 ? void 0 : inject.length) > 0) { + if (!inject.every(item => item.endsWith('.css') || item.endsWith('.js'))) { + logger.error("The injected file must be in either CSS or JS format."); + return; + } + const files = inject.map(relativePath => path.join(process.cwd(), relativePath)); + injectFiles = injectFiles.concat(...files); + tauriConf.pake.inject = files; + } + combineFiles(injectFiles); // 保存配置文件 let configPath = ""; switch (process.platform) { @@ -2109,22 +2149,13 @@ function checkRustInstalled() { var tauri$3 = { security: { - csp: null, - dangerousRemoteDomainIpcAccess: [ - { - domain: "weread.qq.com", - windows: [ - "pake" - ], - enableTauriAPI: true - } - ] + csp: null }, updater: { active: false }, systemTray: { - iconPath: "png/icon_512.png", + iconPath: "png/weread_512.png", iconAsTemplate: true }, allowlist: { @@ -2591,8 +2622,8 @@ var type = "module"; var exports = "./dist/pake.js"; var license = "MIT"; var dependencies = { - "@tauri-apps/api": "^1.2.0", - "@tauri-apps/cli": "^1.2.3", + "@tauri-apps/api": "^1.3.0", + "@tauri-apps/cli": "^1.3.1", axios: "^1.1.3", chalk: "^5.1.2", commander: "^9.4.1", @@ -2623,6 +2654,7 @@ var devDependencies = { concurrently: "^7.5.0", "cross-env": "^7.0.3", rollup: "^3.3.0", + tauri: "^0.15.0", tslib: "^2.4.1", typescript: "^4.9.3" }; @@ -2669,6 +2701,7 @@ program .option('-m, --multi-arch', "available for Mac only, and supports both Intel and M1", DEFAULT_PAKE_OPTIONS.multiArch) .option('--targets ', 'only for linux, default is "deb", option "appaimge" or "all"(deb & appimage)', DEFAULT_PAKE_OPTIONS.targets) .option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent) + .option('--inject [injects...]', 'inject .js or .css for this app', DEFAULT_PAKE_OPTIONS.inject) .action((url, options) => __awaiter(void 0, void 0, void 0, function* () { checkUpdateTips(); if (!url) { diff --git a/src-tauri/src/app/window.rs b/src-tauri/src/app/window.rs index 16c7f3e..c2c6c82 100644 --- a/src-tauri/src/app/window.rs +++ b/src-tauri/src/app/window.rs @@ -26,10 +26,8 @@ pub fn get_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wind .resizable(window_config.resizable) .fullscreen(window_config.fullscreen) .inner_size(window_config.width, window_config.height) - .disable_file_drop_handler() //Very annoying, otherwise dragging files to the window will not work. - .initialization_script(include_str!("../inject/style.js")) - .initialization_script(include_str!("../inject/event.js")) - .initialization_script(include_str!("../inject/component.js")); + .disable_file_drop_handler() + .initialization_script(include_str!("../inject/_INJECT_.js")); //Very annoying, otherwise dragging files to the window will not work. #[cfg(target_os = "macos")] { diff --git a/src-tauri/src/inject/_INJECT_.js b/src-tauri/src/inject/_INJECT_.js new file mode 100644 index 0000000..cfa374b --- /dev/null +++ b/src-tauri/src/inject/_INJECT_.js @@ -0,0 +1 @@ +// empty \ No newline at end of file