Skip to content

Commit b4e08a8

Browse files
authored
🐛 处理early中的UserAgentData (#1045)
* 错误的提示 * 处理early中的UserAgentData * 处理初始化gmInfoEnv * 错误处理
1 parent 7f30198 commit b4e08a8

10 files changed

Lines changed: 49 additions & 37 deletions

File tree

src/app/service/content/content.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { forwardMessage, type Server } from "@Packages/message/server";
44
import type { MessageSend } from "@Packages/message/types";
55
import type { ScriptExecutor } from "./script_executor";
66
import { RuntimeClient } from "../service_worker/client";
7+
import type { GMInfoEnv } from "./types";
78

89
// content页的处理
910
export default class ContentRuntime {
@@ -123,8 +124,8 @@ export default class ContentRuntime {
123124
);
124125
}
125126

126-
pageLoad(messageFlag: string) {
127-
this.scriptExecutor.checkEarlyStartScript("content", messageFlag);
127+
pageLoad(messageFlag: string, envInfo: GMInfoEnv) {
128+
this.scriptExecutor.checkEarlyStartScript("content", messageFlag, envInfo);
128129
const client = new RuntimeClient(this.senderToExt);
129130
// 向service_worker请求脚本列表及环境信息
130131
client.pageLoad().then((o) => {
@@ -138,10 +139,8 @@ export default class ContentRuntime {
138139
for (const script of contentScriptList) {
139140
this.contentScriptSet.add(script.uuid);
140141
}
141-
// 监听事件
142-
this.scriptExecutor.setEnvInfo(envInfo);
143142
// 启动脚本
144-
this.scriptExecutor.startScripts(contentScriptList);
143+
this.scriptExecutor.startScripts(contentScriptList, envInfo);
145144
});
146145
}
147146
}

src/app/service/content/inject.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ export class InjectRuntime {
2424
});
2525
}
2626

27-
setEnvInfo(envInfo: GMInfoEnv) {
28-
this.scriptExecutor.setEnvInfo(envInfo);
29-
}
30-
31-
startScripts(injectScriptList: TScriptInfo[]) {
32-
this.scriptExecutor.startScripts(injectScriptList);
27+
startScripts(injectScriptList: TScriptInfo[], envInfo: GMInfoEnv) {
28+
this.scriptExecutor.startScripts(injectScriptList, envInfo);
3329
}
3430

3531
onInjectPageLoaded() {

src/app/service/content/script_executor.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,30 @@ export type ExecScriptEntry = {
1414
scriptFunc: any;
1515
};
1616

17+
export let initEnvInfo: GMInfoEnv;
18+
19+
try {
20+
initEnvInfo = {
21+
userAgentData: UserAgentData, // 从全局变量获取
22+
sandboxMode: "raw", // 预留字段,当前固定为 raw
23+
isIncognito: false, // inject 环境下无法判断,固定为 false
24+
};
25+
} catch {
26+
// 如果 UserAgentData 不存在,可能是在非inject/content环境下运行
27+
initEnvInfo = {
28+
userAgentData: {},
29+
sandboxMode: "raw",
30+
isIncognito: false,
31+
};
32+
}
33+
1734
// 脚本执行器
1835
export class ScriptExecutor {
1936
earlyScriptFlag: Set<string> = new Set();
2037
execMap: Map<string, ExecScript> = new Map();
2138

22-
envInfo: GMInfoEnv | undefined;
23-
2439
constructor(private msg: Message) {}
2540

26-
setEnvInfo(envInfo: GMInfoEnv) {
27-
this.envInfo = envInfo;
28-
}
29-
3041
emitEvent(data: EmitEventRequest) {
3142
// 转发给脚本
3243
const exec = this.execMap.get(data.uuid);
@@ -44,13 +55,13 @@ export class ScriptExecutor {
4455
}
4556
}
4657

47-
startScripts(scripts: TScriptInfo[]) {
58+
startScripts(scripts: TScriptInfo[], envInfo: GMInfoEnv) {
4859
const loadExec = (script: TScriptInfo, scriptFunc: any) => {
4960
this.execScriptEntry({
5061
scriptLoadInfo: script,
5162
scriptFlag: script.flag,
5263
scriptFunc,
53-
envInfo: this.envInfo!,
64+
envInfo: envInfo,
5465
});
5566
};
5667
// 监听脚本加载
@@ -61,7 +72,7 @@ export class ScriptExecutor {
6172
for (const val of this.execMap.values()) {
6273
if (val.scriptRes.flag === flag) {
6374
// 处理早期脚本的沙盒环境
64-
val.updateEarlyScriptGMInfo(this.envInfo!);
75+
val.updateEarlyScriptGMInfo(envInfo);
6576
return;
6677
}
6778
}
@@ -72,7 +83,7 @@ export class ScriptExecutor {
7283
});
7384
}
7485

75-
checkEarlyStartScript(env: "content" | "inject", messageFlag: string) {
86+
checkEarlyStartScript(env: "content" | "inject", messageFlag: string, envInfo: GMInfoEnv) {
7687
const isContent = env === "content";
7788
const eventNamePrefix = `evt${messageFlag}${isContent ? DefinedFlags.contentFlag : DefinedFlags.injectFlag}`;
7889
const scriptLoadCompleteEvtName = `${eventNamePrefix}${DefinedFlags.scriptLoadComplete}`;
@@ -84,7 +95,7 @@ export class ScriptExecutor {
8495
const scriptFlag = detail?.scriptFlag;
8596
if (typeof scriptFlag === "string") {
8697
ev.preventDefault(); // dispatchEvent 会回传 false -> 分离环境也能得知环境加载代码已执行
87-
this.execEarlyScript(scriptFlag, detail.scriptInfo);
98+
this.execEarlyScript(scriptFlag, detail.scriptInfo, envInfo);
8899
}
89100
});
90101
// 通知 环境 加载完成
@@ -93,13 +104,13 @@ export class ScriptExecutor {
93104
window.dispatchEvent(ev);
94105
}
95106

96-
execEarlyScript(flag: string, scriptInfo: TScriptInfo) {
107+
execEarlyScript(flag: string, scriptInfo: TScriptInfo, envInfo: GMInfoEnv) {
97108
const scriptFunc = (window as any)[flag] as ScriptFunc;
98109
this.execScriptEntry({
99110
scriptLoadInfo: scriptInfo,
100111
scriptFunc: scriptFunc,
101112
scriptFlag: flag,
102-
envInfo: {},
113+
envInfo: envInfo,
103114
});
104115
this.earlyScriptFlag.add(flag);
105116
}

src/app/service/content/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ export interface ApiValue {
4747

4848
export interface GMInfoEnv {
4949
userAgentData: typeof GM_info.userAgentData;
50-
sandboxMode: typeof GM_info.sandboxMode;
50+
sandboxMode: typeof GM_info.sandboxMode; // 目前固定为 "raw",预留
5151
isIncognito: typeof GM_info.isIncognito;
5252
}

src/app/service/service_worker/runtime.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ import { scriptToMenu, type TPopupPageLoadInfo } from "./popup_scriptmenu";
5353

5454
// 避免使用版本号控制导致代码理解混乱
5555
// 用来清除 UserScript API 里的旧缓存
56-
const USERSCRIPTS_REGISTER_CONTROL = "0f5b5b01-eef8-4505-9a8e-b2fc416b2f63";
56+
const USERSCRIPTS_REGISTER_CONTROL = "92292a62-4e81-4dc3-87d0-cb0f0cb9883d";
5757

5858
const ORIGINAL_URLMATCH_SUFFIX = "{ORIGINAL}"; // 用于标记原始URLPatterns的后缀
5959

@@ -808,7 +808,11 @@ export class RuntimeService {
808808
if (contentJs) {
809809
retScript.push({
810810
id: "scriptcat-content",
811-
js: [{ code: `(function (MessageFlag) {\n${contentJs}\n})('${messageFlag}')` }],
811+
js: [
812+
{
813+
code: `(function (MessageFlag,UserAgentData) {\n${contentJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData)})`,
814+
},
815+
],
812816
matches: ["<all_urls>"],
813817
allFrames: true,
814818
runAt: "document_start",
@@ -1267,7 +1271,7 @@ export class RuntimeService {
12671271
{ excludeMatches, excludeGlobs }: { excludeMatches: string[] | undefined; excludeGlobs: string[] | undefined }
12681272
) {
12691273
// 构建inject.js的脚本注册信息
1270-
const code = `(function (MessageFlag) {\n${injectJs}\n})('${messageFlag}')`;
1274+
const code = `(function (MessageFlag,UserAgentData) {\n${injectJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData)})`;
12711275
const script: chrome.userScripts.RegisteredUserScript = {
12721276
id: "scriptcat-inject",
12731277
js: [{ code }],

src/content.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ExtensionMessage } from "@Packages/message/extension_message";
44
import { CustomEventMessage } from "@Packages/message/custom_event_message";
55
import { Server } from "@Packages/message/server";
66
import ContentRuntime from "./app/service/content/content";
7-
import { ScriptExecutor } from "./app/service/content/script_executor";
7+
import { initEnvInfo, ScriptExecutor } from "./app/service/content/script_executor";
88
import { randomMessageFlag } from "./pkg/utils/utils";
99
import type { Message } from "@Packages/message/types";
1010

@@ -41,5 +41,5 @@ if (typeof chrome?.runtime?.onMessage?.addListener !== "function") {
4141
const runtime = new ContentRuntime(extServer, server, extMsgComm, msgInject, scriptExecutorMsg, scriptExecutor);
4242
runtime.init();
4343
// 页面加载,注入脚本
44-
runtime.pageLoad(MessageFlag);
44+
runtime.pageLoad(MessageFlag, initEnvInfo);
4545
}

src/inject.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { Server } from "@Packages/message/server";
55
import type { TScriptInfo } from "./app/repo/scripts";
66
import type { GMInfoEnv } from "./app/service/content/types";
77
import { InjectRuntime } from "./app/service/content/inject";
8-
import { ScriptExecutor } from "./app/service/content/script_executor";
8+
import { initEnvInfo, ScriptExecutor } from "./app/service/content/script_executor";
99
import type { Message } from "@Packages/message/types";
1010

11-
/* global MessageFlag */
11+
/* global MessageFlag */
1212

1313
const msg: Message = new CustomEventMessage(MessageFlag, false);
1414

@@ -22,13 +22,13 @@ const server = new Server("inject", msg);
2222
const scriptExecutor = new ScriptExecutor(msg);
2323
const runtime = new InjectRuntime(server, msg, scriptExecutor);
2424
runtime.init();
25+
2526
// 检查early-start的脚本
26-
scriptExecutor.checkEarlyStartScript("inject", MessageFlag);
27+
scriptExecutor.checkEarlyStartScript("inject", MessageFlag, initEnvInfo);
2728

2829
server.on("pageLoad", (data: { injectScriptList: TScriptInfo[]; envInfo: GMInfoEnv }) => {
2930
logger.logger().debug("inject start");
3031
// 监听事件
31-
runtime.setEnvInfo(data.envInfo);
32-
runtime.startScripts(data.injectScriptList);
32+
runtime.startScripts(data.injectScriptList, data.envInfo);
3333
runtime.onInjectPageLoaded();
3434
});

src/template/scriptcat.d.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ declare const CAT_unregisterMenuInput: typeof GM_unregisterMenuCommand;
160160
/**
161161
* 当使用 @early-start 时,可以使用此函数来等待脚本完全加载完成
162162
*/
163-
declare function CAT_ScriptLoaded(): Promise<void>;
163+
declare function CAT_scriptLoaded(): Promise<void>;
164164

165165
declare function GM_openInTab(url: string, options: GMTypes.OpenTabOptions): GMTypes.Tab | undefined;
166166
declare function GM_openInTab(url: string, loadInBackground: boolean): GMTypes.Tab | undefined;

src/types/main.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ interface FileSystemObserverInstance {
2929

3030
declare const MessageFlag: string;
3131

32+
declare const UserAgentData: typeof GM_info.userAgentData;
33+
3234
// 可以让content与inject环境交换携带dom的对象
3335
declare let cloneInto: ((detail: any, view: any) => any) | undefined;
3436

src/types/scriptcat.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ declare const CAT_unregisterMenuInput: typeof GM_unregisterMenuCommand;
160160
/**
161161
* 当使用 @early-start 时,可以使用此函数来等待脚本完全加载完成
162162
*/
163-
declare function CAT_ScriptLoaded(): Promise<void>;
163+
declare function CAT_scriptLoaded(): Promise<void>;
164164

165165
declare function GM_openInTab(url: string, options: GMTypes.OpenTabOptions): GMTypes.Tab | undefined;
166166
declare function GM_openInTab(url: string, loadInBackground: boolean): GMTypes.Tab | undefined;

0 commit comments

Comments
 (0)