diff --git a/src/app/service/content/script_executor.ts b/src/app/service/content/script_executor.ts index 1c9626269..3631d1478 100644 --- a/src/app/service/content/script_executor.ts +++ b/src/app/service/content/script_executor.ts @@ -17,22 +17,15 @@ export type ExecScriptEntry = { scriptFunc: any; }; -export let initEnvInfo: GMInfoEnv; - -try { - initEnvInfo = { - userAgentData: UserAgentData, // 从全局变量获取 - sandboxMode: "raw", // 预留字段,当前固定为 raw - isIncognito: false, // inject 环境下无法判断,固定为 false - }; -} catch { - // 如果 UserAgentData 不存在,可能是在非inject/content环境下运行 - initEnvInfo = { - userAgentData: {}, - sandboxMode: "raw", - isIncognito: false, - }; -} +export const initEnvInfo = { + /** userAgentData - 从全局变量获取 */ + userAgentData: typeof UserAgentData === "object" ? UserAgentData : {}, + /** sandboxMode - 预留字段,当前固定为 raw */ + sandboxMode: "raw", + /** isIncognito - inject/content 环境下无法判断,固定为 false */ + /** 使用者可透过 「 await navigator.storage.persisted() 」来判断,但ScriptCat不会主动执行此代码来判断 */ + isIncognito: false, +} satisfies GMInfoEnv; // 脚本执行器 export class ScriptExecutor { diff --git a/src/app/service/service_worker/runtime.ts b/src/app/service/service_worker/runtime.ts index f48768340..8ecdebeca 100644 --- a/src/app/service/service_worker/runtime.ts +++ b/src/app/service/service_worker/runtime.ts @@ -825,16 +825,9 @@ export class RuntimeService { } let retContent: chrome.scripting.RegisteredContentScript[] = []; - let retInject: chrome.userScripts.RegisteredUserScript[] = []; - // inject.js - const injectJs = await this.getInjectJsCode(); - if (injectJs) { - // 构建inject.js的脚本注册信息 - retInject = this.compileInjectUserScript(injectJs, { - excludeMatches, - excludeGlobs, - }); - } + const retInject: chrome.userScripts.RegisteredUserScript[] = []; + + // ------ scripting.js ------ // Note: Chrome does not support file.js?query // 注意:Chrome 不支持 file.js?query retContent = [ @@ -848,20 +841,41 @@ export class RuntimeService { } satisfies chrome.scripting.RegisteredContentScript, ]; + // ------ inject.js & content.js ------ + const jsonUAD = JSON.stringify(this.userAgentData); + const injectJs = await this.getInjectJsCode(); + if (injectJs) { + // 构建inject.js的脚本注册信息 + const codeBody = `(function (UserAgentData) {\n${injectJs}\n})(${jsonUAD})`; + const code = `${codeBody}${sourceMapTo("scriptcat-inject.js")}\n`; + const script = { + id: "scriptcat-inject", + js: [{ code }], + matches: [""], + allFrames: true, + runAt: "document_start", + excludeMatches: excludeMatches, + excludeGlobs: excludeGlobs, + world: "MAIN", + } satisfies chrome.userScripts.RegisteredUserScript; + retInject.push(script); + } const contentJs = await this.getContentJsCode(); if (contentJs) { - const codeBody = `(function () {\n${contentJs}\n})()`; + // 构建 content.js 的脚本注册信息 + const codeBody = `(function (UserAgentData) {\n${contentJs}\n})(${jsonUAD})`; const code = `${codeBody}${sourceMapTo("scriptcat-content.js")}\n`; - retInject.push({ + const script = { id: "scriptcat-content", js: [{ code }], matches: [""], allFrames: true, runAt: "document_start", - world: "USER_SCRIPT", excludeMatches, excludeGlobs, - } satisfies chrome.userScripts.RegisteredUserScript); + world: "USER_SCRIPT", + } satisfies chrome.userScripts.RegisteredUserScript; + retInject.push(script); } return { content: retContent, inject: retInject }; @@ -1305,27 +1319,6 @@ export class RuntimeService { return await runScript(this.msgSender, res); } - compileInjectUserScript( - injectJs: string, - { excludeMatches, excludeGlobs }: { excludeMatches: string[] | undefined; excludeGlobs: string[] | undefined } - ) { - // 构建inject.js的脚本注册信息 - const codeBody = `(function (UserAgentData) {\n${injectJs}\n})(${JSON.stringify(this.userAgentData)})`; - const code = `${codeBody}${sourceMapTo("scriptcat-inject.js")}\n`; - const script: chrome.userScripts.RegisteredUserScript = { - id: "scriptcat-inject", - js: [{ code }], - matches: [""], - allFrames: true, - world: "MAIN", - runAt: "document_start", - excludeMatches: excludeMatches, - excludeGlobs: excludeGlobs, - }; - - return [script] as chrome.userScripts.RegisteredUserScript[]; - } - scriptMatchEntry( scriptRes: ScriptRunResource, o: { diff --git a/src/types/main.d.ts b/src/types/main.d.ts index f04a13904..545e0ac8b 100644 --- a/src/types/main.d.ts +++ b/src/types/main.d.ts @@ -28,10 +28,10 @@ interface FileSystemObserverInstance { observe(handle: FileSystemFileHandle | FileSystemDirectoryHandle | FileSystemSyncAccessHandle): Promise; } -declare const UserAgentData: typeof GM_info.userAgentData; +declare const UserAgentData: typeof GM_info.userAgentData | undefined; // 可以让content与inject环境交换携带dom的对象 -declare let cloneInto: ((detail: any, view: any) => any) | undefined; +declare let cloneInto: ((obj: object, targetScope: object, options?: object) => object) | undefined; declare namespace GMSend { interface XHRDetails {