Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #177

Open
wants to merge 57 commits into
base: dev
Choose a base branch
from
Open

Dev #177

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
12ed009
🐞 fix(修复server下无法注入js|css到页面中的问题):
WhiteSevs Jul 19, 2024
2a9e4bb
fix: 修复server下在via/x浏览器上缺失Api的问题
WhiteSevs Jul 19, 2024
0bb0d50
fix: 🐛 新增函数用于处理GM api兼容问题
WhiteSevs Jul 20, 2024
902600f
fix: 🐛 修复mountGmApiFn未执行的问题
WhiteSevs Jul 20, 2024
16f5cb8
feat: 新增对申请的Api的值进行判空处理
WhiteSevs Jul 20, 2024
7fb5952
feat: 新增配置项server.ssl
WhiteSevs Jul 20, 2024
291d74a
refactor: ssl => entryUrlProtocol @default "origin"
WhiteSevs Jul 21, 2024
d40f393
revert: 删除新增的配置项entryUrlProtocol
WhiteSevs Jul 21, 2024
f4e4444
fix: window.close delay time 500 => 1000
WhiteSevs Jul 21, 2024
2d940a3
fix: window.close delay time 3500
WhiteSevs Jul 21, 2024
c0f8c89
fix: 修改修复GM api的逻辑,即注册到document下,而非window下
WhiteSevs Jul 21, 2024
61a1910
Merge branch 'main' of https://github.com/lisonge/vite-plugin-monkey
WhiteSevs Jul 23, 2024
9b6bdca
fix: compat not defined in pkg/package.json but exist in pkg/subpath …
lisonge Jul 21, 2024
0b0bbbb
chore: update demo
lisonge Jul 21, 2024
81d3786
chore: remove useless code
lisonge Jul 21, 2024
d50360b
chore: v4.0.5
lisonge Jul 21, 2024
a219cd8
fix: can not collect grant when minify (#166)
lisonge Jul 21, 2024
6924154
chore: v4.0.6
lisonge Jul 21, 2024
15f5cf7
Merge branch 'main' of https://github.com/WhiteSevs/vite-plugin-monkey
WhiteSevs Jul 25, 2024
b192c73
fix: 修复cssSideEffects注入问题
WhiteSevs Jul 25, 2024
6f9fe45
feat: 新增配置build.metaLocalFileName
WhiteSevs Jul 25, 2024
dff9c52
chore: remove deprecated vscode extension
festoney8 Sep 3, 2024
56a93e9
chore: volta
lisonge Sep 16, 2024
2441a29
feat: add tampermonkey tag (#181)
lisonge Sep 16, 2024
e996387
refactor: add TypeScript interfaces for various functionalities
lisonge Nov 15, 2024
a45c039
feat: add type
lisonge Nov 26, 2024
c1566c8
refactor: update dependencies, rm unused files
lisonge Dec 3, 2024
dd7dd63
fix: gm type
lisonge Dec 5, 2024
cb52f59
fix: transform_type
lisonge Dec 9, 2024
539f5c5
perf: redirectClient
lisonge Dec 10, 2024
8af8a0d
perf: 优化注入流程
WhiteSevs Dec 10, 2024
7944008
Merge branch 'dev' of https://github.com/lisonge/vite-plugin-monkey i…
WhiteSevs Dec 10, 2024
94ca32d
fix: GmApi is not defined
WhiteSevs Dec 10, 2024
73bc8f1
fix: GmApi => GmContextType
WhiteSevs Dec 10, 2024
bdabd57
feat: add GM new Api
WhiteSevs Dec 10, 2024
22ad500
feat: transform context type
lisonge Dec 11, 2024
933e084
chore: update playground
lisonge Dec 11, 2024
d3b9297
perf: fix vite client
lisonge Dec 12, 2024
87699fd
chore: add redirectClient comment link
lisonge Dec 12, 2024
13d37a5
perf: remove svg inline plugin
lisonge Dec 12, 2024
1a757b6
chore: v5.0.0-beta.1
lisonge Dec 12, 2024
666b180
chore: v5.0.0-beta.2
lisonge Dec 12, 2024
ccc0338
feat: update create monkey
lisonge Dec 12, 2024
e1dbb91
chore: pnpm build:playground
lisonge Dec 12, 2024
f2b8af0
fix: gm_api
lisonge Dec 12, 2024
235af7c
chore: v5.0.0-beta.3
lisonge Dec 12, 2024
7e2d8bc
chore: use react 18
lisonge Dec 13, 2024
d640065
chore: update dependencies
lisonge Dec 13, 2024
96bfc18
Merge branch 'dev' of https://github.com/lisonge/vite-plugin-monkey i…
WhiteSevs Dec 14, 2024
7cf31d4
Merge branch 'dev' of https://github.com/lisonge/vite-plugin-monkey i…
WhiteSevs Dec 15, 2024
e1a130b
🐞 fix: fix mount GM
WhiteSevs Dec 15, 2024
1d9e783
Merge branch 'dev' of https://github.com/lisonge/vite-plugin-monkey i…
WhiteSevs Dec 20, 2024
3b5f565
Merge branch 'dev' of https://github.com/lisonge/vite-plugin-monkey i…
WhiteSevs Dec 21, 2024
f0f7227
Merge branch 'dev' of https://github.com/lisonge/vite-plugin-monkey i…
WhiteSevs Dec 31, 2024
d71ad71
🎈 perf: 调整file协议
WhiteSevs Dec 31, 2024
51eeb3f
🦄 refactor: 重构部分代码
WhiteSevs Dec 31, 2024
e6ec8b0
Merge branch 'dev' of https://github.com/lisonge/vite-plugin-monkey i…
WhiteSevs Jan 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/vite-plugin-monkey/src/client/window.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { MonkeyWindow } from './types/_context';
import type { GmContextType } from '../client/index';

const key =
`__monkeyWindow-` +
Expand All @@ -10,5 +11,17 @@ const key =
}
})();

const api_key =
`__monkeyApi-` +
(() => {
try {
return new URL(import.meta.url).origin;
} catch {
return location.origin;
}
})();
// @ts-ignore
export const monkeyWindow: MonkeyWindow = document[key] ?? window;

// @ts-ignore
export const monkeyApi: GmContextType = document[api_key] ?? Object.freeze({});
194 changes: 167 additions & 27 deletions packages/vite-plugin-monkey/src/node/inject_template.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { GmContextType } from '../client/index';

export const fn2string = <T extends (...args: any[]) => any>(
fn: T,
...args: Parameters<T>
Expand Down Expand Up @@ -29,6 +31,80 @@ export const fcToHtml = <T extends (...args: any[]) => any>(
);
};

/**
* 根据meta信息生成处理@grant 注入到window
* 可修复GM_xxx is undefined
* @package entrySrc 脚本入口地址
* @param metaData // ==UserScript== 信息
*/
export const serverInjectGMApiFn = (entrySrc: string, metaData: string) => {
const api_key = `__monkeyApi-` + new URL(entrySrc).origin;

const metaDataSplit = metaData.split('\n');
/** 每一项都是@grant的兼容处理函数字符串 */
const grantCompatibilityProcessing: string[] = [];
/** 是否已添加GM.的处理 */
let isAddGMList = false;
for (let index = 0; index < metaDataSplit.length; index++) {
const metaDataItem = metaDataSplit[index];
const metaGrantValueMatch = metaDataItem.match(
/[\s]*\/\/[\s]*@grant[\s]+([\S]+)/i,
);
if (metaGrantValueMatch) {
const metaGrantValue =
metaGrantValueMatch[metaGrantValueMatch.length - 1].trim();
if (metaGrantValue.startsWith('GM.')) {
// GM.addElement
// GM.addStyle
// ...
if (isAddGMList) {
continue;
}
isAddGMList = true;
grantCompatibilityProcessing.push(`
if (window.GM == null && typeof GM === "object") {
Reflect.set(GM_Api, "GM", GM);
GM_repair_count++;
}`);
} else if (metaGrantValue.startsWith('window.')) {
// ↓不做处理
// window.close
// window.focus
// window.onurlchange
} else {
grantCompatibilityProcessing.push(`
if (typeof ${metaGrantValue} !== "undefined" && ${metaGrantValue} != null && window.${metaGrantValue} == null) {
Reflect.set(GM_Api, "${metaGrantValue}", ${metaGrantValue});
GM_repair_count++;
}`);
}
}
}

return `
;(()=>{
let GM_Api = {};
let GM_repair_count = 0;
if (typeof unsafeWindow !== "undefined" && unsafeWindow == window) {
console.log("[vite-plugin-monkey] window == unsafeWindow repair GM api");
${grantCompatibilityProcessing.join('\n')}
} else {
if(typeof unsafeWindow === "object" && unsafeWindow){
if (unsafeWindow.GM == null && typeof GM === "object") {
Reflect.set(GM_Api, "GM", GM);
GM_repair_count++;
}
}
}
Object.freeze(GM_Api);
document["${api_key}"] = GM_Api;
if(GM_repair_count > 0){
console.log("[vite-plugin-monkey] repair GM api count: " + GM_repair_count);
}
})();
`;
};

export interface ScriptOptions {
entrySrc: string;
}
Expand All @@ -42,60 +118,124 @@ export const serverInjectFn = ({ entrySrc }: ScriptOptions) => {
// @ts-ignore
document[key] = window;
console.log(`[vite-plugin-monkey] mount monkeyWindow to document`);
const entryScript = document.createElement('script');
entryScript.type = 'module';
// @ts-ignore
if (typeof GM_addElement === 'function') {
if (window.trustedTypes) {
// https://github.com/lisonge/vite-plugin-monkey/issues/205
// @ts-ignore
GM_addElement(document.head, 'script', {
type: 'module',
src: entrySrc,
const policy = window.trustedTypes.createPolicy(key, {
createScriptURL: (input: unknown) => input,
});
const trustedScriptURL = policy.createScriptURL(entrySrc);
entryScript.src = trustedScriptURL;
} else {
const script = document.createElement('script');
script.type = 'module';
// @ts-ignore
if (window.trustedTypes) {
// https://github.com/lisonge/vite-plugin-monkey/issues/205
// @ts-ignore
const policy = window.trustedTypes.createPolicy(key, {
createScriptURL: (input: unknown) => input,
});
const trustedScriptURL = policy.createScriptURL(entrySrc);
script.src = trustedScriptURL;
entryScript.src = entrySrc;
}

const injectFn = function () {
let mountPositionStr = '';
if (document.head) {
if (document.head.firstChild) {
document.head.insertBefore(entryScript, document.head.firstChild);
mountPositionStr = 'document.head first';
} else {
document.head.appendChild(entryScript);
mountPositionStr = 'document.head last';
}
} else {
script.src = entrySrc;
if (document.documentElement) {
if (document.documentElement.firstChild) {
document.documentElement.insertBefore(
entryScript,
document.documentElement.firstChild,
);
mountPositionStr = 'document.documentElement first';
} else {
document.documentElement.appendChild(entryScript);
mountPositionStr = 'document.documentElement last';
}
} else {
// 部分情况下documentElement未加载出来
}
}
document.head.append(script);
return mountPositionStr == '' ? null : mountPositionStr;
};

const mountPosition = injectFn();
if (mountPosition == null) {
const intervalId = setInterval(() => {
const __mountPosition__ = injectFn();
if (__mountPosition__ != null) {
clearInterval(intervalId);
console.log(
`[vite-plugin-monkey] interval check mount entry module to ` +
__mountPosition__,
);
}
}, 5);
} else {
console.log(`[vite-plugin-monkey] mount entry module to ` + mountPosition);
}
};

export const cssInjectFn = (css: string) => {
const style = document.createElement('style');
style.dataset.source = 'vite-plugin-monkey';
style.textContent = css;
if (document.head) {
document.head.appendChild(style);
} else if (document.documentElement.childNodes.length === 0) {
document.documentElement.appendChild(style);
} else {
document.documentElement.insertBefore(
style,
document.documentElement.childNodes[0],
);
}
console.log(`[vite-plugin-monkey] mount entry module to document.head`);
};

export const mountGmApiFn = (meta: ImportMeta, apiNames: string[] = []) => {
const key = `__monkeyWindow-` + new URL(meta.url).origin;
const api_key = `__monkeyApi-` + new URL(meta.url).origin;
// @ts-ignore
const monkeyWindow: Window = document[key];
// @ts-ignore
const monkeyApi: Partial<GmContextType> = document[api_key] ?? {};
if (!monkeyWindow) {
console.log(`[vite-plugin-monkey] not found monkeyWindow`);
return;
}

// @ts-ignore
window.unsafeWindow = window;
window.unsafeWindow = monkeyApi?.unsafeWindow ?? window;
console.log(`[vite-plugin-monkey] mount unsafeWindow to unsafeWindow`);

apiNames.push('GM');
let mountedApiSize = 0;
const mountedApiNameList = [];
// @ts-ignore
const unmountedApiNameList = [];
// extra import api
apiNames.push('GM', 'unsafeWindow');
apiNames.forEach((apiName) => {
// @ts-ignore
const fn = monkeyWindow[apiName];
const fn = monkeyApi?.[apiName] ?? monkeyWindow[apiName];
if (fn) {
// @ts-ignore
window[apiName] = monkeyWindow[apiName];
mountedApiSize++;
window[apiName] = fn;
mountedApiNameList.push(apiName);
} else {
unmountedApiNameList.push(apiName);
}
});
console.log(
`[vite-plugin-monkey] mount ${mountedApiSize}/${apiNames.length} GM api to unsafeWindow`,
`[vite-plugin-monkey] mount ${mountedApiNameList.length}/${apiNames.length} GM_api to unsafeWindow`,
);
if (unmountedApiNameList.length) {
console.log(
// @ts-ignore
`[vite-plugin-monkey] unmount ${unmountedApiNameList.join('、')}`,
);
}
};

export const virtualHtmlTemplate = async (url: string) => {
Expand All @@ -105,7 +245,7 @@ export const virtualHtmlTemplate = async (url: string) => {
u.searchParams.set('origin', u.origin);
if (window == window.parent) {
location.href = u.href;
await delay(500);
await delay(3500);
window.close();
return;
}
Expand Down Expand Up @@ -185,7 +325,7 @@ export const previewTemplate = async (urls: string[]) => {
if (window == window.parent && urls.length == 1) {
const u = new URL(urls[0], location.origin);
location.href = u.href;
await delay(500);
await delay(3500);
window.close();
return;
} else if (urls.length == 0) {
Expand Down
29 changes: 25 additions & 4 deletions packages/vite-plugin-monkey/src/node/option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export const resolvedOption = (
} = pluginOption.userscript ?? {};

const { fileName = projectPkg.name + '.user.js' } = build;
let { metaFileName } = build;
let { metaFileName, metaLocalFileName } = build;
if (typeof metaFileName == 'string') {
const t = metaFileName;
metaFileName = () => t;
Expand All @@ -222,7 +222,17 @@ export const resolvedOption = (
metaFileName = undefined;
}

if (typeof metaLocalFileName == 'string') {
const tt = metaLocalFileName;
metaLocalFileName = () => tt;
} else if (metaLocalFileName === true) {
metaLocalFileName = () =>
fileName.replace(/\.user\.js$/, '.meta.local.user.js');
} else if (metaLocalFileName === false) {
metaLocalFileName = undefined;
}
const metaFileFc = metaFileName;
const metaLocalFileFc = metaLocalFileName;

const cssSideEffects =
build.cssSideEffects ||
Expand All @@ -234,9 +244,17 @@ export const resolvedOption = (
GM_addStyle(e);
return;
}
const o = document.createElement('style');
o.textContent = e;
document.head.append(o);
function addStyle(cssText: string) {
let $style = document.createElement('style');
$style.innerHTML = cssText;
if (document.head) {
document.head.appendChild($style);
} else {
document.documentElement.appendChild($style);
}
return $style;
}
addStyle(e);
};
});

Expand Down Expand Up @@ -299,6 +317,9 @@ export const resolvedOption = (
build: {
fileName,
metaFileName: metaFileFc ? () => metaFileFc(fileName) : undefined,
metaLocalFileName: metaLocalFileFc
? () => metaLocalFileFc(fileName)
: undefined,
autoGrant: build.autoGrant ?? true,
externalGlobals: externalGlobals,
externalResource: externalResource2,
Expand Down
20 changes: 19 additions & 1 deletion packages/vite-plugin-monkey/src/node/plugins/finalBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '../topLevelAwait';
import type { FinalMonkeyOption } from '../types';
import { finalMonkeyOptionToComment } from '../userscript';
import path from 'path';

const __entry_name = `__monkey.entry.js`;

Expand All @@ -31,7 +32,10 @@ export const finalBundlePlugin = (finalOption: FinalMonkeyOption): Plugin => {
async configResolved(resolvedConfig) {
viteConfig = resolvedConfig;
},
async generateBundle(_, rawBundle) {
async generateBundle(outputOptions, rawBundle) {
// 输出的目录
let outputPath =
outputOptions.dir || path.resolve(viteConfig.build.outDir);
const entryChunks: OutputChunk[] = [];
const chunks: OutputChunk[] = [];
Object.values(rawBundle).forEach((chunk) => {
Expand Down Expand Up @@ -257,6 +261,20 @@ export const finalBundlePlugin = (finalOption: FinalMonkeyOption): Plugin => {
),
});
}

if (finalOption.build.metaLocalFileName) {
let filePath = path.join(outputPath!, finalOption.build.fileName);
this.emitFile({
type: 'asset',
fileName: finalOption.build.metaLocalFileName(),
source: await finalMonkeyOptionToComment(
finalOption,
collectGrantSet,
'meta-local',
filePath,
),
});
}
},
};
};
Loading