From 6b0c163897aa90ee2cc48dc7712031f9075e6f30 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 1 Oct 2025 21:45:38 +0900 Subject: [PATCH 1/6] GM_openInTab --- src/app/service/content/gm_api.ts | 34 +++++---- src/app/service/service_worker/gm_api.ts | 90 +++++++++++++++++------- src/template/scriptcat.d.tpl | 9 ++- src/types/scriptcat.d.ts | 9 ++- 4 files changed, 97 insertions(+), 45 deletions(-) diff --git a/src/app/service/content/gm_api.ts b/src/app/service/content/gm_api.ts index 2f7211447..71c345084 100644 --- a/src/app/service/content/gm_api.ts +++ b/src/app/service/content/gm_api.ts @@ -19,7 +19,7 @@ export interface IGM_Base { emitEvent(event: string, eventId: string, data: any): void; } -const integrity = {}; // 僅防止非法实例化 +const integrity = {}; // 仅防止非法实例化 // GM_Base 定义内部用变量和函数。均使用@protected // 暂不考虑 Object.getOwnPropertyNames(GM_Base.prototype) 和 ts-morph 脚本生成 @@ -1026,17 +1026,25 @@ export default class GMApi extends GM_Base { } @GMContext.API({ depend: ["GM_closeInTab"], alias: "GM.openInTab" }) - public GM_openInTab(url: string, options?: GMTypes.OpenTabOptions | boolean): GMTypes.Tab { - let option: GMTypes.OpenTabOptions = {}; - if (arguments.length === 1) { - option.active = true; - } else if (typeof options === "boolean") { - option.active = !options; - } else { - option = options; + public GM_openInTab(url: string, param?: GMTypes.OpenTabOptions | boolean): GMTypes.Tab { + let option = {} as GMTypes.OpenTabOptions; + if (typeof param === "boolean") { + option.active = !param; // Greasemonkey 3.x loadInBackground + } else if (param) { + option = { ...param } as GMTypes.OpenTabOptions; + } + if (typeof option.active !== "boolean" && typeof option.loadInBackground === "boolean") { + // TM 同时兼容 active 和 loadInBackground ( active 优先 ) + option.active = !option.loadInBackground; + } else if (option.active === undefined) { + option.active = true; // TM 预设 active: false;VM 预设 active: true;旧SC 预设 active: true;GM 依从 浏览器 + } + if (option.insert === undefined) { + option.insert = true; // TM 预设 insert: true;VM 预设 active: true;旧SC 无此设计 (false) } - if (option.active === undefined) { - option.active = true; + if (option.setParent === undefined) { + option.setParent = true; // TM 预设 setParent: false; 旧SC 预设 setParent: true; + // SC 预设 setParent: true 以避免不可预计的问题 } let tabid: any; @@ -1213,8 +1221,8 @@ export default class GMApi extends GM_Base { } } -// 從 GM_Base 對象中解構出 createGMBase 函数並導出(可供其他模塊使用) +// 从 GM_Base 对象中解构出 createGMBase 函数并导出(可供其他模块使用) export const { createGMBase } = GM_Base; -// 從 GMApi 對象中解構出內部函數,用於後續本地使用,不導出 +// 从 GMApi 对象中解构出内部函数,用于后续本地使用,不导出 const { _GM_getValue, _GM_cookie, _GM_setValue, _GM_xmlhttpRequest } = GMApi; diff --git a/src/app/service/service_worker/gm_api.ts b/src/app/service/service_worker/gm_api.ts index 7e0213a0b..0ea123d3b 100644 --- a/src/app/service/service_worker/gm_api.ts +++ b/src/app/service/service_worker/gm_api.ts @@ -809,38 +809,76 @@ export default class GMApi { @PermissionVerify.API({}) async GM_openInTab(request: Request, sender: IGetSender) { - const url = request.params[0]; - const options = request.params[1] || {}; - if (options.useOpen === true) { - // 发送给offscreen页面处理 - const ok = await sendMessage(this.msgSender, "offscreen/gmApi/openInTab", { url }); - if (ok) { - // 由于window.open强制在前台打开标签,因此获取状态为{ active:true }的标签即为新标签 - const tab = await getCurrentTab(); - await cacheInstance.set(`GM_openInTab:${tab.id}`, { - uuid: request.uuid, - sender: sender.getExtMessageSender(), - }); - return tab.id; + const url = request.params[0] as string; + const options = (request.params[1] || {}) as GMTypes.OpenTabOptions; + const getNewTabId = async () => { + if (options.useOpen === true) { + // 发送给offscreen页面处理 (使用window.open) + const ok = await sendMessage(this.msgSender, "offscreen/gmApi/openInTab", { url }); + if (ok) { + // 由于window.open强制在前台打开标签,因此获取状态为{ active:true }的标签即为新标签 + const tab = await getCurrentTab(); + return tab.id; + } else { + // 当新tab被浏览器阻止时window.open()会返回null 视为已经关闭 + // 似乎在Firefox中禁止在background页面使用window.open(),强制返回null + return false; + } } else { - // 当新tab被浏览器阻止时window.open()会返回null 视为已经关闭 - // 似乎在Firefox中禁止在background页面使用window.open(),强制返回null - return false; + const { tabId, windowId } = sender.getExtMessageSender(); + const active = options.active; + const currentTab = await chrome.tabs.get(tabId); + let newTabIndex = -1; + if (options.incognito && !currentTab.incognito) { + // incognito: "split" 在 normal 里不会看到 incognito + // 只能创建新 incognito window + // pinned 无效 + // insert 不重要 + await chrome.windows.create({ + url, + incognito: true, + focused: active, + }); + return 0; + } + if ((typeof options.insert === "number" || options.insert === true) && currentTab && currentTab.index >= 0) { + // insert 为 boolean 时,插入至当前Tab下一格 (TM行为) + // insert 为 number 时,插入至相对位置 (SC独自) + const insert = +options.insert; + newTabIndex = currentTab.index + insert; + if (newTabIndex < 0) newTabIndex = 0; + } + const createProperties = { + url, + active: active, + } as chrome.tabs.CreateProperties; + if (options.setParent) { + // SC 预设 setParent: true 以避免不可预计的问题 + createProperties.openerTabId = tabId === -1 ? undefined : tabId; + createProperties.windowId = windowId === -1 ? undefined : windowId; + } + if (options.pinned) { + // VM/FM行为 + createProperties.pinned = true; + } else if (newTabIndex >= 0) { + // insert option; pinned 情况下无效 + createProperties.index = newTabIndex; + } + const tab = await chrome.tabs.create(createProperties); + return tab.id; } - } else { - const { tabId, windowId } = sender.getExtMessageSender(); - const tab = await chrome.tabs.create({ - url, - active: options.active, - openerTabId: tabId === -1 ? undefined : tabId, - windowId: windowId === -1 ? undefined : windowId, - }); - await cacheInstance.set(`GM_openInTab:${tab.id}`, { + }; + const tabId = await getNewTabId(); + if (tabId) { + // 有 tab 创建的话 + await cacheInstance.set(`GM_openInTab:${tabId}`, { uuid: request.uuid, sender: sender.getExtMessageSender(), }); - return tab.id; + return tabId; } + // 创建失败时返回 0 + return 0; } @PermissionVerify.API({ diff --git a/src/template/scriptcat.d.tpl b/src/template/scriptcat.d.tpl index 7a997fa6a..0715cfe85 100644 --- a/src/template/scriptcat.d.tpl +++ b/src/template/scriptcat.d.tpl @@ -383,9 +383,12 @@ declare namespace GMTypes { ) => unknown; interface OpenTabOptions { - active?: boolean; - insert?: boolean; - setParent?: boolean; + active?: boolean; // FM & TM & VM; TM default false + insert?: boolean; // FM & TM & VM; TM default true + setParent?: boolean; // FM & TM + incognito?: boolean; // FM & TM + loadInBackground?: boolean; // TM - A boolean value has the opposite meaning of active (just for TM. Not Recommended) + pinned?: boolean; // FM & VM useOpen?: boolean; // 这是一个实验性/不兼容其他管理器/不兼容Firefox的功能 表示使用window.open打开新窗口 #178 } diff --git a/src/types/scriptcat.d.ts b/src/types/scriptcat.d.ts index 7a997fa6a..0715cfe85 100644 --- a/src/types/scriptcat.d.ts +++ b/src/types/scriptcat.d.ts @@ -383,9 +383,12 @@ declare namespace GMTypes { ) => unknown; interface OpenTabOptions { - active?: boolean; - insert?: boolean; - setParent?: boolean; + active?: boolean; // FM & TM & VM; TM default false + insert?: boolean; // FM & TM & VM; TM default true + setParent?: boolean; // FM & TM + incognito?: boolean; // FM & TM + loadInBackground?: boolean; // TM - A boolean value has the opposite meaning of active (just for TM. Not Recommended) + pinned?: boolean; // FM & VM useOpen?: boolean; // 这是一个实验性/不兼容其他管理器/不兼容Firefox的功能 表示使用window.open打开新窗口 #178 } From 70e5bc48197d6b381c931386567ee46ffbbbb81b Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 1 Oct 2025 23:39:18 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9B=B4=E8=AF=A6?= =?UTF-8?q?=E7=BB=86=E7=9A=84=E5=8F=82=E6=95=B0=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/template/scriptcat.d.tpl | 88 +++++++++++++++++++++++++++++++++--- src/types/scriptcat.d.ts | 88 +++++++++++++++++++++++++++++++++--- 2 files changed, 162 insertions(+), 14 deletions(-) diff --git a/src/template/scriptcat.d.tpl b/src/template/scriptcat.d.tpl index 0715cfe85..c22c43f8c 100644 --- a/src/template/scriptcat.d.tpl +++ b/src/template/scriptcat.d.tpl @@ -383,13 +383,87 @@ declare namespace GMTypes { ) => unknown; interface OpenTabOptions { - active?: boolean; // FM & TM & VM; TM default false - insert?: boolean; // FM & TM & VM; TM default true - setParent?: boolean; // FM & TM - incognito?: boolean; // FM & TM - loadInBackground?: boolean; // TM - A boolean value has the opposite meaning of active (just for TM. Not Recommended) - pinned?: boolean; // FM & VM - useOpen?: boolean; // 这是一个实验性/不兼容其他管理器/不兼容Firefox的功能 表示使用window.open打开新窗口 #178 + /** + * 决定新标签页是否在打开时获得焦点。 + * + * - `true` → 新标签页会立即切换到前台。 + * - `false` → 新标签页在后台打开,不会打断当前页面的焦点。 + * + * 支持环境:FM、TM、VM + * 默认值:TM = false,SC/VM = true + */ + active?: boolean; + + /** + * 决定新标签页插入位置。 + * + * - 如果是 `boolean`: + * - `true` → 插入在当前标签页之后。 + * - `false` → 插入到窗口末尾。 + * - 如果是 `number`(仅 ScriptCat 扩展): + * - `0` → 插入到当前标签前一格。 + * - `1` → 插入到当前标签后一格。 + * + * 支持环境:FM、TM、VM + * 默认值:TM = true + */ + insert?: boolean | number; + + /** + * 决定是否设置父标签页(即 `openerTabId`)。 + * + * - `true` → 浏览器能追踪由哪个标签打开的子标签, + * 有助于某些扩展(如标签树管理器)识别父子关系。 + * + * 支持环境:FM、TM + * 默认值:TM = false,SC = true(因兼容性问题) + */ + setParent?: boolean; + + /** + * 是否在隐私窗口(无痕模式)中打开标签页。 + * + * 注意:ScriptCat 的 manifest.json 配置了 `"incognito": "split"`, + * 在 normal window 中执行时,tabId/windowId 将不可用, + * 只能执行「打开新标签页」动作。 + * + * 支持环境:FM、TM + */ + incognito?: boolean; + + /** + * 历史兼容字段,仅 TM 支持。 + * 语义与 `active` **相反**: + * + * - `true` → 等价于 `active = false`(后台加载)。 + * - `false` → 等价于 `active = true`(前台加载)。 + * + * ⚠️ 不推荐使用:与 `active` 功能重复且容易混淆。 + * + * 支持环境:TM + */ + loadInBackground?: boolean; + + /** + * 是否将新标签页固定(pin)在浏览器标签栏左侧。 + * + * - `true` → 新标签页为固定状态。 + * - `false` → 普通标签页。 + * + * 支持环境:FM、VM + */ + pinned?: boolean; + + /** + * 实验性功能,仅 ScriptCat 支持。 + * + * 使用 `window.open` 打开新窗口,而不是浏览器 API。 + * - 优点:在部分受限环境下依然可用。 + * - 缺点:不兼容 Firefox,也可能与其他脚本管理器不兼容。 + * + * 相关:#178 + */ + useOpen?: boolean; } interface XHRResponse { diff --git a/src/types/scriptcat.d.ts b/src/types/scriptcat.d.ts index 0715cfe85..c22c43f8c 100644 --- a/src/types/scriptcat.d.ts +++ b/src/types/scriptcat.d.ts @@ -383,13 +383,87 @@ declare namespace GMTypes { ) => unknown; interface OpenTabOptions { - active?: boolean; // FM & TM & VM; TM default false - insert?: boolean; // FM & TM & VM; TM default true - setParent?: boolean; // FM & TM - incognito?: boolean; // FM & TM - loadInBackground?: boolean; // TM - A boolean value has the opposite meaning of active (just for TM. Not Recommended) - pinned?: boolean; // FM & VM - useOpen?: boolean; // 这是一个实验性/不兼容其他管理器/不兼容Firefox的功能 表示使用window.open打开新窗口 #178 + /** + * 决定新标签页是否在打开时获得焦点。 + * + * - `true` → 新标签页会立即切换到前台。 + * - `false` → 新标签页在后台打开,不会打断当前页面的焦点。 + * + * 支持环境:FM、TM、VM + * 默认值:TM = false,SC/VM = true + */ + active?: boolean; + + /** + * 决定新标签页插入位置。 + * + * - 如果是 `boolean`: + * - `true` → 插入在当前标签页之后。 + * - `false` → 插入到窗口末尾。 + * - 如果是 `number`(仅 ScriptCat 扩展): + * - `0` → 插入到当前标签前一格。 + * - `1` → 插入到当前标签后一格。 + * + * 支持环境:FM、TM、VM + * 默认值:TM = true + */ + insert?: boolean | number; + + /** + * 决定是否设置父标签页(即 `openerTabId`)。 + * + * - `true` → 浏览器能追踪由哪个标签打开的子标签, + * 有助于某些扩展(如标签树管理器)识别父子关系。 + * + * 支持环境:FM、TM + * 默认值:TM = false,SC = true(因兼容性问题) + */ + setParent?: boolean; + + /** + * 是否在隐私窗口(无痕模式)中打开标签页。 + * + * 注意:ScriptCat 的 manifest.json 配置了 `"incognito": "split"`, + * 在 normal window 中执行时,tabId/windowId 将不可用, + * 只能执行「打开新标签页」动作。 + * + * 支持环境:FM、TM + */ + incognito?: boolean; + + /** + * 历史兼容字段,仅 TM 支持。 + * 语义与 `active` **相反**: + * + * - `true` → 等价于 `active = false`(后台加载)。 + * - `false` → 等价于 `active = true`(前台加载)。 + * + * ⚠️ 不推荐使用:与 `active` 功能重复且容易混淆。 + * + * 支持环境:TM + */ + loadInBackground?: boolean; + + /** + * 是否将新标签页固定(pin)在浏览器标签栏左侧。 + * + * - `true` → 新标签页为固定状态。 + * - `false` → 普通标签页。 + * + * 支持环境:FM、VM + */ + pinned?: boolean; + + /** + * 实验性功能,仅 ScriptCat 支持。 + * + * 使用 `window.open` 打开新窗口,而不是浏览器 API。 + * - 优点:在部分受限环境下依然可用。 + * - 缺点:不兼容 Firefox,也可能与其他脚本管理器不兼容。 + * + * 相关:#178 + */ + useOpen?: boolean; } interface XHRResponse { From 993efb50e4250c571d07e098261cb6c3f1538c83 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Fri, 3 Oct 2025 19:25:26 +0900 Subject: [PATCH 3/6] =?UTF-8?q?Copilot=E8=AF=B4=E5=BE=97=E5=AF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/app/service/content/gm_api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/service/content/gm_api.ts b/src/app/service/content/gm_api.ts index 71c345084..99c2dafbd 100644 --- a/src/app/service/content/gm_api.ts +++ b/src/app/service/content/gm_api.ts @@ -1040,7 +1040,7 @@ export default class GMApi extends GM_Base { option.active = true; // TM 预设 active: false;VM 预设 active: true;旧SC 预设 active: true;GM 依从 浏览器 } if (option.insert === undefined) { - option.insert = true; // TM 预设 insert: true;VM 预设 active: true;旧SC 无此设计 (false) + option.insert = true; // TM 预设 insert: true;VM 预设 insert: true;旧SC 无此设计 (false) } if (option.setParent === undefined) { option.setParent = true; // TM 预设 setParent: false; 旧SC 预设 setParent: true; From 0192500f9ac70dc31d0e46fdbde2ab55b6a7b66e Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Fri, 3 Oct 2025 19:29:10 +0900 Subject: [PATCH 4/6] TypeScript --- src/app/service/service_worker/gm_api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/service/service_worker/gm_api.ts b/src/app/service/service_worker/gm_api.ts index 0ea123d3b..72d1c1499 100644 --- a/src/app/service/service_worker/gm_api.ts +++ b/src/app/service/service_worker/gm_api.ts @@ -810,7 +810,7 @@ export default class GMApi { @PermissionVerify.API({}) async GM_openInTab(request: Request, sender: IGetSender) { const url = request.params[0] as string; - const options = (request.params[1] || {}) as GMTypes.OpenTabOptions; + const options = (request.params[1] || {}) as GMTypes.OpenTabOptions & { active: boolean }; const getNewTabId = async () => { if (options.useOpen === true) { // 发送给offscreen页面处理 (使用window.open) From 2b05fa3b3f85fe4f164f9c7431b2b31551e6b874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Sat, 4 Oct 2025 17:20:12 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E8=B0=83=E6=95=B4d.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/service/service_worker/gm_api.ts | 2 +- src/template/scriptcat.d.tpl | 26 ++++++++++-------------- src/types/scriptcat.d.ts | 26 ++++++++++-------------- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/app/service/service_worker/gm_api.ts b/src/app/service/service_worker/gm_api.ts index 72d1c1499..0ea123d3b 100644 --- a/src/app/service/service_worker/gm_api.ts +++ b/src/app/service/service_worker/gm_api.ts @@ -810,7 +810,7 @@ export default class GMApi { @PermissionVerify.API({}) async GM_openInTab(request: Request, sender: IGetSender) { const url = request.params[0] as string; - const options = (request.params[1] || {}) as GMTypes.OpenTabOptions & { active: boolean }; + const options = (request.params[1] || {}) as GMTypes.OpenTabOptions; const getNewTabId = async () => { if (options.useOpen === true) { // 发送给offscreen页面处理 (使用window.open) diff --git a/src/template/scriptcat.d.tpl b/src/template/scriptcat.d.tpl index c22c43f8c..b29342ccc 100644 --- a/src/template/scriptcat.d.tpl +++ b/src/template/scriptcat.d.tpl @@ -389,8 +389,7 @@ declare namespace GMTypes { * - `true` → 新标签页会立即切换到前台。 * - `false` → 新标签页在后台打开,不会打断当前页面的焦点。 * - * 支持环境:FM、TM、VM - * 默认值:TM = false,SC/VM = true + * 默认值:true */ active?: boolean; @@ -400,12 +399,11 @@ declare namespace GMTypes { * - 如果是 `boolean`: * - `true` → 插入在当前标签页之后。 * - `false` → 插入到窗口末尾。 - * - 如果是 `number`(仅 ScriptCat 扩展): + * - 如果是 `number`: * - `0` → 插入到当前标签前一格。 * - `1` → 插入到当前标签后一格。 * - * 支持环境:FM、TM、VM - * 默认值:TM = true + * 默认值:true */ insert?: boolean | number; @@ -415,8 +413,7 @@ declare namespace GMTypes { * - `true` → 浏览器能追踪由哪个标签打开的子标签, * 有助于某些扩展(如标签树管理器)识别父子关系。 * - * 支持环境:FM、TM - * 默认值:TM = false,SC = true(因兼容性问题) + * 默认值:true */ setParent?: boolean; @@ -427,7 +424,7 @@ declare namespace GMTypes { * 在 normal window 中执行时,tabId/windowId 将不可用, * 只能执行「打开新标签页」动作。 * - * 支持环境:FM、TM + * 默认值:false */ incognito?: boolean; @@ -440,7 +437,8 @@ declare namespace GMTypes { * * ⚠️ 不推荐使用:与 `active` 功能重复且容易混淆。 * - * 支持环境:TM + * 默认值:false + * @deprecated 请使用 `active` 替代 */ loadInBackground?: boolean; @@ -450,18 +448,16 @@ declare namespace GMTypes { * - `true` → 新标签页为固定状态。 * - `false` → 普通标签页。 * - * 支持环境:FM、VM + * 默认值:false */ pinned?: boolean; /** - * 实验性功能,仅 ScriptCat 支持。 - * * 使用 `window.open` 打开新窗口,而不是浏览器 API。 - * - 优点:在部分受限环境下依然可用。 - * - 缺点:不兼容 Firefox,也可能与其他脚本管理器不兼容。 + * 可以打开某些特殊的链接 * - * 相关:#178 + * 相关:Issue #178 + * 默认值:false */ useOpen?: boolean; } diff --git a/src/types/scriptcat.d.ts b/src/types/scriptcat.d.ts index c22c43f8c..b29342ccc 100644 --- a/src/types/scriptcat.d.ts +++ b/src/types/scriptcat.d.ts @@ -389,8 +389,7 @@ declare namespace GMTypes { * - `true` → 新标签页会立即切换到前台。 * - `false` → 新标签页在后台打开,不会打断当前页面的焦点。 * - * 支持环境:FM、TM、VM - * 默认值:TM = false,SC/VM = true + * 默认值:true */ active?: boolean; @@ -400,12 +399,11 @@ declare namespace GMTypes { * - 如果是 `boolean`: * - `true` → 插入在当前标签页之后。 * - `false` → 插入到窗口末尾。 - * - 如果是 `number`(仅 ScriptCat 扩展): + * - 如果是 `number`: * - `0` → 插入到当前标签前一格。 * - `1` → 插入到当前标签后一格。 * - * 支持环境:FM、TM、VM - * 默认值:TM = true + * 默认值:true */ insert?: boolean | number; @@ -415,8 +413,7 @@ declare namespace GMTypes { * - `true` → 浏览器能追踪由哪个标签打开的子标签, * 有助于某些扩展(如标签树管理器)识别父子关系。 * - * 支持环境:FM、TM - * 默认值:TM = false,SC = true(因兼容性问题) + * 默认值:true */ setParent?: boolean; @@ -427,7 +424,7 @@ declare namespace GMTypes { * 在 normal window 中执行时,tabId/windowId 将不可用, * 只能执行「打开新标签页」动作。 * - * 支持环境:FM、TM + * 默认值:false */ incognito?: boolean; @@ -440,7 +437,8 @@ declare namespace GMTypes { * * ⚠️ 不推荐使用:与 `active` 功能重复且容易混淆。 * - * 支持环境:TM + * 默认值:false + * @deprecated 请使用 `active` 替代 */ loadInBackground?: boolean; @@ -450,18 +448,16 @@ declare namespace GMTypes { * - `true` → 新标签页为固定状态。 * - `false` → 普通标签页。 * - * 支持环境:FM、VM + * 默认值:false */ pinned?: boolean; /** - * 实验性功能,仅 ScriptCat 支持。 - * * 使用 `window.open` 打开新窗口,而不是浏览器 API。 - * - 优点:在部分受限环境下依然可用。 - * - 缺点:不兼容 Firefox,也可能与其他脚本管理器不兼容。 + * 可以打开某些特殊的链接 * - * 相关:#178 + * 相关:Issue #178 + * 默认值:false */ useOpen?: boolean; } From 96d37d3df150767fbbe24192e8bb8ae0e6228d33 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sat, 4 Oct 2025 19:39:23 +0900 Subject: [PATCH 6/6] =?UTF-8?q?service=5Fworker=20=E9=82=A3=E8=BE=B9?= =?UTF-8?q?=E7=9A=84=20options.active=20=E4=B8=8D=E4=BC=9A=E5=87=BA?= =?UTF-8?q?=E7=8E=B0undefined?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/service/service_worker/gm_api.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/service/service_worker/gm_api.ts b/src/app/service/service_worker/gm_api.ts index 0ea123d3b..a2489c40a 100644 --- a/src/app/service/service_worker/gm_api.ts +++ b/src/app/service/service_worker/gm_api.ts @@ -810,7 +810,8 @@ export default class GMApi { @PermissionVerify.API({}) async GM_openInTab(request: Request, sender: IGetSender) { const url = request.params[0] as string; - const options = (request.params[1] || {}) as GMTypes.OpenTabOptions; + const options = (request.params[1] || {}) as GMTypes.OpenTabOptions & + Required>; const getNewTabId = async () => { if (options.useOpen === true) { // 发送给offscreen页面处理 (使用window.open)