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 { npmDirectory } from '@/utils/dir.js';
|
||||||
import logger from '@/options/logger.js';
|
import logger from '@/options/logger.js';
|
||||||
|
import combineFiles from '@/helpers/combine.js';
|
||||||
|
|
||||||
type DangerousRemoteDomainIpAccess = {
|
type DangerousRemoteDomainIpAccess = {
|
||||||
domain: string;
|
domain: string;
|
||||||
@@ -64,6 +65,7 @@ export async function mergeTauriConfig(
|
|||||||
iterCopyFile,
|
iterCopyFile,
|
||||||
identifier,
|
identifier,
|
||||||
name,
|
name,
|
||||||
|
inject,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const tauriConfWindowOptions = {
|
const tauriConfWindowOptions = {
|
||||||
@@ -298,6 +300,27 @@ export async function mergeTauriConfig(
|
|||||||
// 设置安全调用 window.__TAURI__ 的安全域名为设置的应用域名
|
// 设置安全调用 window.__TAURI__ 的安全域名为设置的应用域名
|
||||||
setSecurityConfigWithUrl(tauriConf, url);
|
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 = "";
|
let configPath = "";
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
|
|||||||
1
bin/cli.ts
vendored
1
bin/cli.ts
vendored
@@ -41,6 +41,7 @@ program
|
|||||||
DEFAULT_PAKE_OPTIONS.targets
|
DEFAULT_PAKE_OPTIONS.targets
|
||||||
)
|
)
|
||||||
.option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent)
|
.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) => {
|
.action(async (url: string, options: PakeCliOptions) => {
|
||||||
checkUpdateTips();
|
checkUpdateTips();
|
||||||
|
|
||||||
|
|||||||
1
bin/defaults.ts
vendored
1
bin/defaults.ts
vendored
@@ -15,6 +15,7 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
|
|||||||
iterCopyFile: false,
|
iterCopyFile: false,
|
||||||
systemTrayIcon: '',
|
systemTrayIcon: '',
|
||||||
debug: false,
|
debug: false,
|
||||||
|
inject: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_APP_NAME = 'Pake';
|
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")
|
// detect blob download by createElement("a")
|
||||||
function detectDownloadByCreateAnchor() {
|
function detectDownloadByCreateAnchor() {
|
||||||
const createEle = document.createElement;
|
const createEle = document.createElement;
|
||||||
|
const tauri = window.__TAURI__;
|
||||||
document.createElement = (el) => {
|
document.createElement = (el) => {
|
||||||
if (el !== "a") return createEle.call(document, el);
|
if (el !== "a") return createEle.call(document, el);
|
||||||
const anchorEle = 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;
|
debug: boolean;
|
||||||
|
|
||||||
|
/** 需要注入页面的外部脚本 */
|
||||||
|
inject: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PakeAppOptions extends PakeCliOptions {
|
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 fs$1 from 'fs/promises';
|
||||||
import fs2 from 'fs-extra';
|
import fs2 from 'fs-extra';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import URL from 'node:url';
|
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { fileTypeFromBuffer } from 'file-type';
|
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
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
PERFORMANCE OF THIS SOFTWARE.
|
PERFORMANCE OF THIS SOFTWARE.
|
||||||
***************************************************************************** */
|
***************************************************************************** */
|
||||||
|
/* global Reflect, Promise */
|
||||||
|
|
||||||
|
|
||||||
function __awaiter(thisArg, _arguments, P, generator) {
|
function __awaiter(thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
@@ -61,6 +62,7 @@ const DEFAULT_PAKE_OPTIONS = {
|
|||||||
iterCopyFile: false,
|
iterCopyFile: false,
|
||||||
systemTrayIcon: '',
|
systemTrayIcon: '',
|
||||||
debug: false,
|
debug: false,
|
||||||
|
inject: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const tlds = [
|
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) {
|
function promptText(message, initial) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const response = yield prompts({
|
const response = yield prompts({
|
||||||
@@ -1641,12 +1658,17 @@ function promptText(message, initial) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function setSecurityConfigWithUrl(tauriConfig, url) {
|
function setSecurityConfigWithUrl(tauriConfig, url) {
|
||||||
const { hostname } = URL.parse(url);
|
const myURL = new URL(url);
|
||||||
tauriConfig.tauri.security.dangerousRemoteDomainIpcAccess[0].domain = hostname;
|
const currentUrlConfig = {
|
||||||
|
domain: myURL.hostname,
|
||||||
|
windows: ["pake"],
|
||||||
|
enableTauriAPI: true,
|
||||||
|
};
|
||||||
|
tauriConfig.tauri.security.dangerousRemoteDomainIpcAccess = [currentUrlConfig];
|
||||||
}
|
}
|
||||||
function mergeTauriConfig(url, options, tauriConf) {
|
function mergeTauriConfig(url, options, tauriConf) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
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 = {
|
const tauriConfWindowOptions = {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
@@ -1869,6 +1891,24 @@ function mergeTauriConfig(url, options, tauriConf) {
|
|||||||
}
|
}
|
||||||
// 设置安全调用 window.__TAURI__ 的安全域名为设置的应用域名
|
// 设置安全调用 window.__TAURI__ 的安全域名为设置的应用域名
|
||||||
setSecurityConfigWithUrl(tauriConf, url);
|
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 = "";
|
let configPath = "";
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
@@ -2109,22 +2149,13 @@ function checkRustInstalled() {
|
|||||||
|
|
||||||
var tauri$3 = {
|
var tauri$3 = {
|
||||||
security: {
|
security: {
|
||||||
csp: null,
|
csp: null
|
||||||
dangerousRemoteDomainIpcAccess: [
|
|
||||||
{
|
|
||||||
domain: "weread.qq.com",
|
|
||||||
windows: [
|
|
||||||
"pake"
|
|
||||||
],
|
|
||||||
enableTauriAPI: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
updater: {
|
updater: {
|
||||||
active: false
|
active: false
|
||||||
},
|
},
|
||||||
systemTray: {
|
systemTray: {
|
||||||
iconPath: "png/icon_512.png",
|
iconPath: "png/weread_512.png",
|
||||||
iconAsTemplate: true
|
iconAsTemplate: true
|
||||||
},
|
},
|
||||||
allowlist: {
|
allowlist: {
|
||||||
@@ -2591,8 +2622,8 @@ var type = "module";
|
|||||||
var exports = "./dist/pake.js";
|
var exports = "./dist/pake.js";
|
||||||
var license = "MIT";
|
var license = "MIT";
|
||||||
var dependencies = {
|
var dependencies = {
|
||||||
"@tauri-apps/api": "^1.2.0",
|
"@tauri-apps/api": "^1.3.0",
|
||||||
"@tauri-apps/cli": "^1.2.3",
|
"@tauri-apps/cli": "^1.3.1",
|
||||||
axios: "^1.1.3",
|
axios: "^1.1.3",
|
||||||
chalk: "^5.1.2",
|
chalk: "^5.1.2",
|
||||||
commander: "^9.4.1",
|
commander: "^9.4.1",
|
||||||
@@ -2623,6 +2654,7 @@ var devDependencies = {
|
|||||||
concurrently: "^7.5.0",
|
concurrently: "^7.5.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
rollup: "^3.3.0",
|
rollup: "^3.3.0",
|
||||||
|
tauri: "^0.15.0",
|
||||||
tslib: "^2.4.1",
|
tslib: "^2.4.1",
|
||||||
typescript: "^4.9.3"
|
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('-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('--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('--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* () {
|
.action((url, options) => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
checkUpdateTips();
|
checkUpdateTips();
|
||||||
if (!url) {
|
if (!url) {
|
||||||
|
|||||||
@@ -26,10 +26,8 @@ pub fn get_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wind
|
|||||||
.resizable(window_config.resizable)
|
.resizable(window_config.resizable)
|
||||||
.fullscreen(window_config.fullscreen)
|
.fullscreen(window_config.fullscreen)
|
||||||
.inner_size(window_config.width, window_config.height)
|
.inner_size(window_config.width, window_config.height)
|
||||||
.disable_file_drop_handler() //Very annoying, otherwise dragging files to the window will not work.
|
.disable_file_drop_handler()
|
||||||
.initialization_script(include_str!("../inject/style.js"))
|
.initialization_script(include_str!("../inject/_INJECT_.js")); //Very annoying, otherwise dragging files to the window will not work.
|
||||||
.initialization_script(include_str!("../inject/event.js"))
|
|
||||||
.initialization_script(include_str!("../inject/component.js"));
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[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