[兼容TM] 以 Navigation API 实现 TM 的 window.onurlchange#1315
[兼容TM] 以 Navigation API 实现 TM 的 window.onurlchange#1315cyfung1031 wants to merge 7 commits intorelease/v1.4from
Conversation
|
@CodFrm E2E test 过不了怎解决? |
我来处理,我先解决目前手头上的 |
There was a problem hiding this comment.
Pull request overview
该 PR 旨在基于 Navigation API,在内容脚本侧实现对 Tampermonkey @grant window.onurlchange 的兼容支持,通过监听导航并派发 urlchange 事件来对齐 TM 行为。
Changes:
- 新增
attachNavigateHandler:监听navigation的navigate事件并向window派发urlchange - 在
createContext中检测@grant window.onurlchange时注入兼容逻辑并安装导航监听 - 调整
createProxyContext中对context.window的类型处理与注释
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| src/app/service/content/gm_api/navigation_handle.ts | 新增 Navigation API 监听并派发 urlchange 事件的实现 |
| src/app/service/content/create_context.ts | 在沙盒上下文创建/代理阶段接入 window.onurlchange grant 的启用逻辑 |
| if (scriptGrants.has("window.onurlchange") && context.onurlchange === undefined) { | ||
| context.onurlchange = null; |
There was a problem hiding this comment.
这里把 context.onurlchange 设为 null,但 createProxyContext 里是通过 context.window.onurlchange === null 来判断是否启用(并且需要用自定义 getter/setter 去模拟 onxxx 事件属性)。目前两边字段不一致,导致 grant 生效判断失效。建议改为设置 context.window.onurlchange = null,并避免在 context 根对象上额外引入同名字段。
| if (scriptGrants.has("window.onurlchange") && context.onurlchange === undefined) { | |
| context.onurlchange = null; | |
| if ( | |
| scriptGrants.has("window.onurlchange") && | |
| context.window && | |
| context.window.onurlchange === undefined | |
| ) { | |
| context.window.onurlchange = null; |
| // 目前 TM 只支援 null | ||
| mySandbox.onurlchange = null; |
There was a problem hiding this comment.
目前只是在页面侧 dispatch 了 urlchange 事件,但沙盒里 window.onurlchange = fn 并不会像 TM 一样自动转成 addEventListener('urlchange', ...)(因为 createProxyContext 的 eventHandling 机制只覆盖原生 on*,没有为 onurlchange 定义对应的 property descriptor)。如果目标是兼容 TM 的 window.onurlchange,建议在 createProxyContext 中在 grant 开启时为 onurlchange 显式安装与其它 on* 相同的 getter/setter(绑定到 urlchange 事件)。
| // 目前 TM 只支援 null | |
| mySandbox.onurlchange = null; | |
| // 在沙盒中模拟 TM 的 window.onurlchange 行为: | |
| // - getter 返回当前处理函数 | |
| // - setter 在赋值为函数时,通过 addEventListener 绑定 "urlchange" | |
| // 在被覆盖/置为非函数或 null 时,通过 removeEventListener 解绑 | |
| let urlChangeHandler: ((ev: Event) => any) | null = null; | |
| Object.defineProperty(mySandbox, "onurlchange", { | |
| configurable: true, | |
| enumerable: true, | |
| get() { | |
| return urlChangeHandler; | |
| }, | |
| set(value) { | |
| // 先移除旧的监听器 | |
| if (urlChangeHandler && typeof (mySandbox as any).removeEventListener === "function") { | |
| (mySandbox as any).removeEventListener("urlchange", urlChangeHandler); | |
| } | |
| if (typeof value === "function") { | |
| urlChangeHandler = value; | |
| if (typeof (mySandbox as any).addEventListener === "function") { | |
| (mySandbox as any).addEventListener("urlchange", urlChangeHandler); | |
| } | |
| } else { | |
| urlChangeHandler = null; | |
| } | |
| }, | |
| }); |
| context.onurlchange = null; | ||
| attachNavigateHandler(window as any); |
There was a problem hiding this comment.
createContext 新增了 window.onurlchange 的 grant 分支并引入导航监听逻辑,但当前 create_context.test.ts 仅覆盖了 shouldFnBind,没有覆盖该行为(例如:grant 启用时是否安装 onurlchange 的 property descriptor、以及触发 urlchange 时 handler 是否会被调用)。建议补充对应的 Vitest 单测,避免后续回归。
| context.onurlchange = null; | |
| attachNavigateHandler(window as any); | |
| // 为当前脚本上下文暴露 onurlchange 属性 | |
| context.onurlchange = null; | |
| // 仅在首次为页面安装导航监听器时调用 attachNavigateHandler,避免多脚本重复注入 | |
| const winAny = window as any; | |
| if (!winAny.__scriptcatOnUrlChangeAttached__) { | |
| attachNavigateHandler(winAny); | |
| winAny.__scriptcatOnUrlChangeAttached__ = true; | |
| } |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Code reviewFound 2 issues:
scriptcat/src/app/service/content/gm_api/navigation_handle.ts Lines 14 to 18 in 6359474
scriptcat/src/app/service/content/create_context.ts Lines 195 to 200 in 6359474 scriptcat/src/app/service/content/create_context.ts Lines 404 to 410 in 6359474 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
|
有些做法我先改良一下 |
Checklist / 检查清单
Description / 描述
https://www.tampermonkey.net/documentation.php?locale=en#api:window.onurlchange
现在所有浏览器都支持 Navigation API 了
只是做一个接口把
@grant window.onurlchange跟 Navigation API 接起来只为 兼容TM
使用 navigate event 而非 navigatesucess 让 url改变能被即时捕获
// Chrome 102+, Firefox 147+
// https://developer.chrome.com/docs/web-platform/navigation-api
// https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API#browser_compatibility
Screenshots / 截图