Conversation
There was a problem hiding this comment.
Pull request overview
此 PR 修复了 Issue #1043,为 GM_openInTab API 添加了 useOpen 选项,允许使用 window.open 而非 chrome.tabs.create 来打开特殊协议链接(如 vscode://、m3u8dl:// 等),这些协议无法通过标准的 Chrome 扩展 API 打开。
主要变更:
- 在
OpenTabOptions类型中新增useOpen布尔选项 - 实现了通过 offscreen 页面使用
window.open的逻辑,支持 Firefox 和 Chrome/Edge - 优化了类型定义,将
ReadyState提取为独立类型,改进了onprogress回调的类型定义
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/types/scriptcat.d.ts | 为 OpenTabOptions 接口添加 useOpen 选项的类型定义 |
| src/template/scriptcat.d.tpl | 同步类型定义模板,新增 ReadyState 类型,优化 XHRResponse 和 DownloadDetails.onprogress 的类型定义 |
| src/app/service/service_worker/gm_api/gm_api.ts | 实现 GM_openInTab 的 useOpen 逻辑,处理 Firefox 和 Chrome 的不同环境,引入 nativePageWindowOpen 和 getCurrentTab 工具函数 |
| src/app/service/offscreen/gm_api.ts | 导出 nativePageWindowOpen 函数用于在 offscreen 环境调用 window.open,并注册 windowOpen 消息处理器 |
| packages/message/server.ts | 修复 ApiFunction 类型定义,允许同步返回任意类型值(不仅限于 Promise 或 void),以支持 nativePageWindowOpen 的布尔返回值 |
| // 由于window.open强制在前台打开标签,因此获取状态为 { active:true } 的标签即为新标签 | ||
| const tab = await getCurrentTab(); | ||
| return tab?.id; |
There was a problem hiding this comment.
这里的逻辑存在竞态条件问题。window.open() 打开新标签是异步的,立即调用 getCurrentTab() 可能会获取到调用前就已经激活的标签,而不是新打开的标签。
建议的解决方案:
- 在调用
window.open()之前先记录当前活动标签的 ID - 在
window.open()之后查询所有活动标签,排除之前记录的标签 ID - 或者使用
chrome.tabs.onCreated监听器配合短时间内的标签创建事件来识别新标签
另外,注释提到"由于window.open强制在前台打开标签",但实际上这取决于浏览器设置和用户权限,并不总是强制在前台打开。
There was a problem hiding this comment.
我有想过 在调用 window.open() 之前先记录当前活动标签的 ID 这些
不过老实说这个用来打开一个根本不是Tab 的东西,根本就没 tabId
There was a problem hiding this comment.
确实如此,先不管它,不过这个id返回也只是用于后续的close等操作,不用id的话,就用其它方式处理,反正在offscreen中是可以拿到window对象的
这样写不好吗 |
我觉得这个描述更清晰一些,说明了是打开的新标签,另外这样的中文更顺畅一点?
前者更像是说只能用来打开一些特殊链接,后者说明用于打开特殊链接更好 // 使用 `window.open` 打开新标签,而不是 `chrome.tabs.create`
// 在打开一些特殊协议的链接时很有用,例如 `vscode://`, `m3u8dl://` |
|
@CodFrm 还有你看一下 GM_openInTab 返回 id那个部份 现在对应 没有id 的处理好像有问题 this.sendMessage("GM_openInTab", [url, option as GMTypes.SWOpenTabOptions]).then((id) => {
if (!this.EE) return;
if (id) {
tabid = id;
this.EE.addListener("GM_openInTab:" + id, (resp: any) => {
if (!this.EE) return;
switch (resp.event) {
case "oncreate":
tabid = resp.tabId;
break;
case "onclose":
ret.onclose && ret.onclose();
ret.closed = true;
this.EE.removeAllListeners("GM_openInTab:" + id);
break;
default:
LoggerCore.logger().warn("GM_openInTab resp is error", {
resp,
});
break;
}
});
} else {
ret.onclose && ret.onclose();
ret.closed = true;
}
}); |
打开 特殊链接 不会新建一个 Tab 这样写讲得像这个参数有其他用途 |
但是他也可以用来打开正常的url呀,只是说在打开 特殊链接 时,这个参数才更有意义 |
会有什么问题呢?没有id就认为关闭了,调用一次onclose,并标记closed为true,这个逻辑似乎也没毛病 |
|
好吧 |
* fix #1043 * mExtScheme * vitest * 还是用 useOpen 了 * Update gm_api.ts * 修改注释说明 * 修改注释说明 * 修改注释说明 * 修改注释说明 * 修改注释说明 * Update gm_api.ts * 修改注释 * Update gm_api.ts * typescript fix * 根据copilot意见修改 * Update gm_api.ts --------- Co-authored-by: 王一之 <[email protected]>
概述 Descriptions
fix #1043
变更内容 Changes
截图 Screenshots