feat: pake can use external scripts

This commit is contained in:
jeasonnow
2023-06-08 16:48:19 +08:00
parent 8ce401735f
commit 9acca818fd
11 changed files with 99 additions and 21 deletions

View File

@@ -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) {

1
bin/cli.ts vendored
View File

@@ -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();

1
bin/defaults.ts vendored
View File

@@ -15,6 +15,7 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
iterCopyFile: false,
systemTrayIcon: '',
debug: false,
inject: [],
};
export const DEFAULT_APP_NAME = 'Pake';

17
bin/helpers/combine.ts vendored Normal file
View File

@@ -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;
}

View File

@@ -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);

3
bin/types.ts vendored
View File

@@ -43,6 +43,9 @@ export interface PakeCliOptions {
/** 调试模式,会输出更多日志 */
debug: boolean;
/** 需要注入页面的外部脚本 */
inject: string[];
}
export interface PakeAppOptions extends PakeCliOptions {

67
dist/cli.js vendored
View File

@@ -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 <string>', '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) {

View File

@@ -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")]
{

1
src-tauri/src/inject/_INJECT_.js vendored Normal file
View File

@@ -0,0 +1 @@
// empty