Conversation
There was a problem hiding this comment.
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") && { |
There was a problem hiding this comment.
hasGrant 检查中存在重复的 grant 名称:"GM_xmlhttpRequest" 出现了两次。这会导致逻辑错误,因为 hasGrant 使用 some() 检查,重复的名称没有意义。应该检查 "GM_xmlhttpRequest" 和 "GM.xmlHttpRequest" (注意大小写差异),或者移除重复项。
| }, | ||
| }), | ||
|
|
||
| ...(hasGrant(scriptGrants, "GM_getResourceURL", "GM.getResourceUrl", "GM_getResourceUrl", "GM.getResourceURL") && { |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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; // 释放不需要的函数 |
There was a problem hiding this comment.
在第 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; | ||
| }; |
There was a problem hiding this comment.
在 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.
呀。 copilot 有提到
gtx.runFlag = `${gtx.runFlag}(invalid)`我也是这样想
|
装饰器模式本来是一个好的模式。。。。。现在这样。。。为了不bind,改的什么去了,自制装饰器,改回去吧 至于 depend alias,后续其实都不用了的,之前是为了给 |
刚有找到更好的做法。。能保留装饰器又不用 bind 确定能用。 |
不用再 bind 来 bind 去
一堆麻烦的代码写法 ( depend alias ) 全部都不用
直接按照 grant 生成需要的 API
然后注入 sandbox context