-
Notifications
You must be signed in to change notification settings - Fork 315
[v1.3] 重构 GM Api 代码设计 #1212
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
base: release/v1.3
Are you sure you want to change the base?
[v1.3] 重构 GM Api 代码设计 #1212
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
这个 PR 对 GM API 的代码设计进行了重大重构,目的是简化代码结构,消除繁琐的 bind 操作和复杂的依赖别名(depend alias)系统。新的实现直接基于脚本的 grant 权限生成所需的 API,然后将其注入到 sandbox context 中。
Changes:
- 将基于类和装饰器的 GM API 设计重构为工厂函数模式
- 使用
createGMApis函数根据 grant 动态生成 API 集合 - 简化了 API 注入逻辑,移除了复杂的依赖管理系统
- 更新了所有相关测试以适配新的 API 结构
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/app/service/content/gm_api/gm_api.ts | 核心重构:将 GMApi 类转换为 createGMApis 工厂函数,GM_Base 类现在被导出,API 通过条件展开运算符基于 grant 动态生成 |
| src/app/service/content/gm_api/gm_xhr.ts | 类型导入更新:从 GMApi 改为 GM_Base |
| src/app/service/content/create_context.ts | 上下文创建逻辑更新:使用新的 createGMBase 和 createGMApis 函数,简化了 API 注入流程 |
| tests/runtime/gm_api.test.ts | 测试更新:使用新的工厂函数创建测试实例 |
| src/app/service/content/gm_api/gm_api.test.ts | 测试断言更新:函数名从 "bound X" 改为 "X",添加 metadata 克隆以确保测试隔离 |
| ret.abort = abort; | ||
| return ret; | ||
| } | ||
| ...(hasGrant(scriptGrants, "GM_xmlhttpRequest", "GM.xmlHttpRequest", "GM_xmlHttpRequest", "GM.xmlhttpRequest") && { |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hasGrant 检查中存在重复的 grant 名称:"GM_xmlhttpRequest" 出现了两次。这会导致逻辑错误,因为 hasGrant 使用 some() 检查,重复的名称没有意义。应该检查 "GM_xmlhttpRequest" 和 "GM.xmlHttpRequest" (注意大小写差异),或者移除重复项。
| }, | ||
| }), | ||
|
|
||
| ...(hasGrant(scriptGrants, "GM_getResourceURL", "GM.getResourceUrl", "GM_getResourceUrl", "GM.getResourceURL") && { |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hasGrant 检查中存在重复的 grant 名称:"GM_getResourceUrl" 和 "GM.getResourceURL" 出现了两次(注意大小写不同,但应该只需要检查一次)。这会导致冗余的检查。建议仅保留必要的变体。
| ...(hasGrant(scriptGrants, "GM_getResourceURL", "GM.getResourceUrl", "GM_getResourceUrl", "GM.getResourceURL") && { | |
| ...(hasGrant(scriptGrants, "GM_getResourceURL", "GM.getResourceUrl") && { |
| switch (resp.action) { | ||
| case "onload": { | ||
| if (action === "download") { | ||
| // 读取blob |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CAT_fileStorage 中的 download 操作在第 860 行直接调用 gtx.sendMessage("CAT_fetchBlob", [resp.data]),但没有检查 CAT_fetchBlob 是否已授权。如果脚本只授予 CAT_fileStorage 而未授予 CAT_fetchBlob,这个调用可能会失败。建议检查 CAT_fetchBlob 是否在 grant 中,或者在文档中说明 CAT_fileStorage 依赖 CAT_fetchBlob。
| // 读取blob | |
| // 读取blob,需要 CAT_fetchBlob 授权 | |
| if (!hasGrant(scriptGrants, "CAT_fetchBlob")) { | |
| details.onerror && | |
| details.onerror({ | |
| code: -1, | |
| message: "CAT_fileStorage download 需要 CAT_fetchBlob 授权", | |
| }); | |
| break; | |
| } |
| } | ||
|
|
||
| for (const [key, value] of Object.entries(gmApis)) { | ||
| (gmApis as any)[key] = undefined; // 释放不需要的函数 |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在第 49 行,代码尝试通过将 gmApis 的属性设置为 undefined 来"释放不需要的函数"。但这是有问题的,因为:
- gmApis 被声明为
as const,试图修改它的属性可能会导致 TypeScript 错误 - 将对象属性设置为 undefined 并不会真正释放内存,只有移除对对象的引用才能让垃圾回收器回收内存
- 如果目的是避免暴露内部函数(以 "_" 开头的),应该在构建 grantedAPIs 时过滤,而不是修改 gmApis
建议删除这一行,或使用其他方式实现意图的功能。
| (gmApis as any)[key] = undefined; // 释放不需要的函数 |
| gtx.setInvalidContext = () => { | ||
| if (invalid) return; | ||
| invalid = true; | ||
| gtx.valueChangeListener?.clear(); | ||
| gtx.EE?.removeAllListeners(); | ||
| // 释放记忆 | ||
| gtx.message = null; | ||
| gtx.scriptRes = null; | ||
| gtx.valueChangeListener = null; | ||
| gtx.EE = null; | ||
| }; |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在 createGMApis 的 setInvalidContext 实现中(第 218-228 行),缺少对 runFlag 的更新。原始实现在 create_context.ts 中包含 this.runFlag = \${uuidv4()}(invalid)`来防止 runFlag 相关操作。新的实现中缺少这一行,可能导致在上下文失效后,某些依赖 runFlag 的操作仍然可以执行。建议添加gtx.runFlag = `${gtx.runFlag}(invalid)`` 或类似的逻辑。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
呀。 copilot 有提到
gtx.runFlag = `${gtx.runFlag}(invalid)`我也是这样想
|
装饰器模式本来是一个好的模式。。。。。现在这样。。。为了不bind,改的什么去了,自制装饰器,改回去吧 至于 depend alias,后续其实都不用了的,之前是为了给 |
刚有找到更好的做法。。能保留装饰器又不用 bind 确定能用。 |
不用再 bind 来 bind 去
一堆麻烦的代码写法 ( depend alias ) 全部都不用
直接按照 grant 生成需要的 API
然后注入 sandbox context