-
Notifications
You must be signed in to change notification settings - Fork 317
[v1.3] 修复 87c0a19dea9cad2e9ebdce13bb4d998ea386ad74 重构代码时不正确的修改 #1217
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,86 @@ | ||||||
| import { ExternalWhitelist } from "@App/app/const"; | ||||||
| import { sendMessage } from "@Packages/message/client"; | ||||||
| import type { Message } from "@Packages/message/types"; | ||||||
|
|
||||||
| // ================================ | ||||||
| // 对外接口:external 注入 | ||||||
| // ================================ | ||||||
|
|
||||||
| // 判断当前 hostname 是否命中白名单(含子域名) | ||||||
| const isExternalWhitelisted = (hostname: string) => { | ||||||
| return ExternalWhitelist.some( | ||||||
| (t) => hostname.endsWith(t) && (hostname.length === t.length || hostname.endsWith(`.${t}`)) | ||||||
| ); | ||||||
| }; | ||||||
|
|
||||||
| // 生成暴露给页面的 Scriptcat 外部接口 | ||||||
| const createScriptcatExpose = (msg: Message) => { | ||||||
| const scriptExpose: App.ExternalScriptCat = { | ||||||
| isInstalled(name: string, namespace: string, callback: (res: App.IsInstalledResponse | undefined) => unknown) { | ||||||
| sendMessage<App.IsInstalledResponse>(msg, "scripting/script/isInstalled", { name, namespace }).then(callback); | ||||||
| }, | ||||||
| }; | ||||||
| return scriptExpose; | ||||||
| }; | ||||||
|
|
||||||
| // 尝试写入 external,失败则忽略 | ||||||
| const safeSetExternal = <T extends object>(external: any, key: string, value: T) => { | ||||||
| try { | ||||||
| external[key] = value; | ||||||
| return true; | ||||||
| } catch { | ||||||
| // 无法注入到 external,忽略 | ||||||
| return false; | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| // 当 TM 与 SC 同时存在时的兼容处理:TM 未安装脚本时回退查询 SC | ||||||
| const patchTampermonkeyIsInstalled = (external: any, scriptExpose: App.ExternalScriptCat) => { | ||||||
| const exposedTM = external.Tampermonkey; | ||||||
| const isInstalledTM = exposedTM?.isInstalled; | ||||||
| const isInstalledSC = scriptExpose.isInstalled; | ||||||
|
|
||||||
| // 满足这些字段时,认为是较完整的 TM 对象 | ||||||
| if (isInstalledTM && exposedTM?.getVersion && exposedTM.openOptions) { | ||||||
| try { | ||||||
| exposedTM.isInstalled = ( | ||||||
| name: string, | ||||||
| namespace: string, | ||||||
| callback: (res: App.IsInstalledResponse | undefined) => unknown | ||||||
| ) => { | ||||||
| isInstalledTM(name, namespace, (res: App.IsInstalledResponse | undefined) => { | ||||||
| if (res?.installed) callback(res); | ||||||
| else isInstalledSC(name, namespace, callback); | ||||||
| }); | ||||||
| }; | ||||||
| } catch { | ||||||
| // 忽略错误 | ||||||
| } | ||||||
| return true; | ||||||
| } | ||||||
|
|
||||||
| return false; | ||||||
| }; | ||||||
|
|
||||||
| // inject 环境 pageLoad 后执行:按白名单对页面注入 external 接口 | ||||||
|
||||||
| // inject 环境 pageLoad 后执行:按白名单对页面注入 external 接口 | |
| // inject 环境初始化时由 inject.ts 直接调用:按白名单对页面注入 external 接口(不依赖 pageLoad) |
Copilot
AI
Feb 7, 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.
onInjectPageLoaded 新增了白名单判断、external 注入、以及 Tampermonkey 兼容补丁等关键行为,但当前没有对应单元测试覆盖(例如:命中/未命中白名单时的注入行为、TM 存在时 isInstalled 回退逻辑、以及写入 external 失败时的容错)。建议补充 vitest 用例,避免后续通讯机制/注入时机调整时再次回归。
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.
isInstalled通过sendMessage(...).then(callback)触发回调,但当消息通道异常/目标 API 不存在时sendMessage会抛错并导致 Promise rejection:页面侧回调永远不会被调用,同时可能产生未处理的拒绝。建议在这里补充.catch(...),保证失败时也以callback(undefined)(或明确的失败结果)结束,并避免未处理异常外溢到页面。