Merge pull request #465 from tw93/feat/add_external_scripts
feat: Support for custom injection of external JS and CSS files during app generation.
This commit is contained in:
23
bin/builders/common.ts
vendored
23
bin/builders/common.ts
vendored
@@ -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
1
bin/cli.ts
vendored
@@ -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
1
bin/defaults.ts
vendored
@@ -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
17
bin/helpers/combine.ts
vendored
Normal 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;
|
||||
}
|
||||
@@ -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
3
bin/types.ts
vendored
@@ -43,6 +43,9 @@ export interface PakeCliOptions {
|
||||
|
||||
/** 调试模式,会输出更多日志 */
|
||||
debug: boolean;
|
||||
|
||||
/** 需要注入页面的外部脚本 */
|
||||
inject: string[];
|
||||
}
|
||||
|
||||
export interface PakeAppOptions extends PakeCliOptions {
|
||||
|
||||
67
dist/cli.js
vendored
67
dist/cli.js
vendored
@@ -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) {
|
||||
|
||||
@@ -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
1
src-tauri/src/inject/_INJECT_.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
// empty
|
||||
Reference in New Issue
Block a user