Conversation
|
对这个PR没什么意见 这样改动是很大,不过下一个版本你可以考虑一下 |
There was a problem hiding this comment.
Pull request overview
这个 PR 旨在解决 early-start 脚本中 UserAgentData 的处理问题(修复 #1037),同时将 API 名称从 CAT_ScriptLoaded 更正为 CAT_scriptLoaded(驼峰命名)。
主要变更包括:
- 在 inject 和 content 环境中通过全局变量传递 UserAgentData,使 early-start 脚本能够立即访问 userAgentData
- 重构了 ScriptExecutor 类,移除了实例级别的 envInfo 存储,改为通过参数传递
- 修正了 API 命名规范,将
CAT_ScriptLoaded改为CAT_scriptLoaded
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/types/scriptcat.d.ts |
修正 API 名称:CAT_ScriptLoaded → CAT_scriptLoaded |
src/types/main.d.ts |
添加全局变量声明 UserAgentData |
src/template/scriptcat.d.tpl |
模板文件中同步修正 API 名称 |
src/inject.ts |
导入 initEnvInfo 并传递给 checkEarlyStartScript 和 startScripts |
src/content.ts |
导入 initEnvInfo 并传递给相关方法 |
src/app/service/service_worker/runtime.ts |
在 inject 和 content 脚本注入时通过 IIFE 参数传递 UserAgentData;更新 USERSCRIPTS_REGISTER_CONTROL 以强制重新注册 |
src/app/service/content/types.ts |
为 sandboxMode 字段添加注释说明其为预留字段 |
src/app/service/content/script_executor.ts |
添加 initEnvInfo 导出,在模块加载时从全局变量初始化;移除实例级 envInfo 存储,改为参数传递 |
src/app/service/content/inject.ts |
移除 setEnvInfo 方法,startScripts 方法直接接收 envInfo 参数 |
src/app/service/content/content.ts |
pageLoad 和 startScripts 方法接收并传递 envInfo 参数 |
| ) { | ||
| // 构建inject.js的脚本注册信息 | ||
| const code = `(function (MessageFlag) {\n${injectJs}\n})('${messageFlag}')`; | ||
| const code = `(function (MessageFlag,UserAgentData) {\n${injectJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData)})`; |
There was a problem hiding this comment.
与 content.js 注入代码相同的问题:JSON.stringify(this.userAgentData) 可能在 userAgentData 未正确初始化时导致注入空对象,影响 inject 环境中的 early-start 脚本。建议确保在调用此方法前 userAgentData 已正确初始化。
| const code = `(function (MessageFlag,UserAgentData) {\n${injectJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData)})`; | |
| const code = `(function (MessageFlag,UserAgentData) {\n${injectJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData || {})})`; |
| import type { Message } from "@Packages/message/types"; | ||
|
|
||
| /* global MessageFlag */ | ||
| /* global MessageFlag */ |
There was a problem hiding this comment.
[nitpick] 应该添加 /* global UserAgentData */ 注释来声明全局变量 UserAgentData,与 MessageFlag 的处理方式保持一致。虽然 TypeScript 类型定义中已声明,但全局注释有助于明确该变量的来源。
| /* global MessageFlag */ | |
| /* global MessageFlag UserAgentData */ |
| import { initEnvInfo, ScriptExecutor } from "./app/service/content/script_executor"; | ||
| import { randomMessageFlag } from "./pkg/utils/utils"; | ||
| import type { Message } from "@Packages/message/types"; | ||
|
|
There was a problem hiding this comment.
[nitpick] content.ts 也使用了全局变量 UserAgentData(通过 initEnvInfo 导入),建议添加 /* global UserAgentData */ 注释来声明,与其他环境保持一致性。
| } catch { | ||
| // 如果 UserAgentData 不存在,可能是在非inject/content环境下运行 |
There was a problem hiding this comment.
使用空的 catch 块会静默捕获所有错误,包括可能的代码错误(如变量拼写错误等),这会使调试变得困难。建议:
- 至少记录错误信息用于调试:
catch (e) { console.debug("UserAgentData not available:", e); ... } - 或者使用更精确的错误检查:
typeof UserAgentData !== 'undefined' ? UserAgentData : {}
| } catch { | |
| // 如果 UserAgentData 不存在,可能是在非inject/content环境下运行 | |
| } catch (e) { | |
| // 如果 UserAgentData 不存在,可能是在非inject/content环境下运行 | |
| console.debug("UserAgentData not available:", e); |
| @@ -53,7 +53,7 @@ import { scriptToMenu, type TPopupPageLoadInfo } from "./popup_scriptmenu"; | |||
|
|
|||
| // 避免使用版本号控制导致代码理解混乱 | |||
| // 用来清除 UserScript API 里的旧缓存 | |||
There was a problem hiding this comment.
[nitpick] 更改了 USERSCRIPTS_REGISTER_CONTROL 的值,这将强制所有用户重新注册 UserScript。建议在上方添加注释说明变更原因,例如:
// 修改控制符以强制重新注册,因为需要传递 UserAgentData 到 inject/content 环境
const USERSCRIPTS_REGISTER_CONTROL = "92292a62-4e81-4dc3-87d0-cb0f0cb9883d";| // 用来清除 UserScript API 里的旧缓存 | |
| // 用来清除 UserScript API 里的旧缓存 | |
| // 修改控制符以强制重新注册,因为需要传递 UserAgentData 到 inject/content 环境 |
| js: [{ code: `(function (MessageFlag) {\n${contentJs}\n})('${messageFlag}')` }], | ||
| js: [ | ||
| { | ||
| code: `(function (MessageFlag,UserAgentData) {\n${contentJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData)})`, |
There was a problem hiding this comment.
使用 JSON.stringify(this.userAgentData) 可能导致问题:
- 如果
userAgentData包含undefined值,JSON.stringify 会将其省略,导致注入的代码不完整 - 如果
userAgentData为空对象{}(初始化时的默认值),注入的是空对象,early-start 脚本可能获取不到正确的 userAgentData
建议添加错误处理或确保 this.userAgentData 在注入前已正确初始化。可以考虑:
code: `(function (MessageFlag,UserAgentData) {\n${contentJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData || {})})`,| code: `(function (MessageFlag,UserAgentData) {\n${contentJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData)})`, | |
| code: `(function (MessageFlag,UserAgentData) {\n${contentJs}\n})('${messageFlag}', ${JSON.stringify(this.userAgentData ?? {}, (_, v) => v === undefined ? null : v)})`, |
再演进的话,感觉要变成和MV2差不多的方式了,脚本代码 发送到 content ,由 content 进行注入,这种做法兼容性广一些(不依赖 chrome.userScript了),但是 early-start 的速度达不到了,始终要获取一次代码 可以考虑做一下,我了解到iOS Edge对于 browser.userScript 的支持因为iOS政策问题,支持不了,但是browser.scripting可以,iOS Edge上架了一个Stay的扩展,似乎就是这种做法,但是我不确定,需要进行验证 |
你理解错了 我意思是, 这样吧 反正就是 self contained 的设计 注册会把 server client code 一个脚本处理好 不像现在要等 content 载入才有 pageLoad |
概述 Descriptions
fix #1037
变更内容 Changes
截图 Screenshots