Skip to content

Commit ac0d7de

Browse files
cyfung1031CodFrm
authored andcommitted
🎨 增强 chrome.tabs.create 兼容性 (#639)
1 parent bba12d2 commit ac0d7de

3 files changed

Lines changed: 51 additions & 45 deletions

File tree

src/app/service/service_worker/gm_api.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import PermissionVerify, { PermissionVerifyApiGet } from "./permission_verify";
1212
import Cache, { incr } from "@App/app/cache";
1313
import EventEmitter from "eventemitter3";
1414
import { type RuntimeService } from "./runtime";
15-
import { getIcon, isFirefox } from "@App/pkg/utils/utils";
15+
import { getIcon, isFirefox, getCurrentTab, openInCurrentTab } from "@App/pkg/utils/utils";
1616
import { type SystemConfig } from "@App/pkg/config/config";
1717
import i18next, { i18nName } from "@App/locales/locales";
1818
import FileSystemFactory from "@Packages/filesystem/factory";
@@ -310,13 +310,8 @@ export default class GMApi {
310310
}
311311

312312
@PermissionVerify.API()
313-
CAT_userConfig(request: Request, sender: GetSender): void {
314-
const tabId = sender.getExtMessageSender().tabId;
315-
chrome.tabs.create({
316-
url: `/src/options.html#/?userConfig=${request.uuid}`,
317-
active: true,
318-
openerTabId: tabId === -1 ? undefined : tabId,
319-
});
313+
CAT_userConfig(request: Request): void {
314+
openInCurrentTab(`/src/options.html#/?userConfig=${request.uuid}`);
320315
}
321316

322317
@PermissionVerify.API({

src/app/service/service_worker/permission_verify.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import Cache from "@App/app/cache";
99
import CacheKey from "@App/app/cache_key";
1010
import { v4 as uuidv4 } from "uuid";
1111
import Queue from "@App/pkg/utils/queue";
12-
import { subscribeScriptDelete } from "../queue";
12+
import { type TDeleteScript } from "../queue";
13+
import { openInCurrentTab } from "@App/pkg/utils/utils";
1314

1415
export interface ConfirmParam {
1516
// 权限名
@@ -150,7 +151,7 @@ export default class PermissionVerify {
150151
return;
151152
}
152153
try {
153-
const ret = await this.confirm(data.request, data.confirm, data.sender);
154+
const ret = await this.confirm(data.request, data.confirm);
154155
data.resolve(ret);
155156
} catch (e) {
156157
data.reject(e);
@@ -169,7 +170,7 @@ export default class PermissionVerify {
169170
});
170171
}
171172

172-
async confirm(request: Request, confirm: boolean | ConfirmParam, sender: GetSender): Promise<boolean> {
173+
async confirm(request: Request, confirm: boolean | ConfirmParam): Promise<boolean> {
173174
if (typeof confirm === "boolean") {
174175
return confirm;
175176
}
@@ -194,7 +195,7 @@ export default class PermissionVerify {
194195
throw new Error("permission denied");
195196
}
196197
// 没有权限,则弹出页面让用户进行确认
197-
const userConfirm = await this.confirmWindow(request.script, confirm, sender);
198+
const userConfirm = await this.confirmWindow(request.script, confirm);
198199
// 成功存入数据库
199200
const model: Permission = {
200201
uuid: request.uuid,
@@ -250,7 +251,7 @@ export default class PermissionVerify {
250251
> = new Map();
251252

252253
// 弹出窗口让用户进行确认
253-
async confirmWindow(script: Script, confirm: ConfirmParam, sender: GetSender): Promise<UserConfirm> {
254+
async confirmWindow(script: Script, confirm: ConfirmParam): Promise<UserConfirm> {
254255
return new Promise((resolve, reject) => {
255256
const uuid = uuidv4();
256257
// 超时处理
@@ -269,11 +270,7 @@ export default class PermissionVerify {
269270
reject,
270271
});
271272
// 打开窗口
272-
const tabId = sender.getExtMessageSender().tabId;
273-
chrome.tabs.create({
274-
url: chrome.runtime.getURL(`src/confirm.html?uuid=${uuid}`),
275-
openerTabId: tabId === -1 ? undefined : tabId, // 如果是后台脚本,则不设置openerTabId
276-
});
273+
openInCurrentTab(`src/confirm.html?uuid=${uuid}`);
277274
});
278275
}
279276

src/pkg/utils/utils.ts

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,37 +87,17 @@ export function parseStorageValue(str: string): unknown {
8787
}
8888
}
8989

90-
// 在当前页后打开一个新页面
91-
export function openInCurrentTab(url: string) {
92-
chrome.tabs.query(
93-
{
94-
active: true,
95-
},
96-
(tabs) => {
97-
if (chrome.runtime.lastError) {
98-
console.error("chrome.runtime.lastError in chrome.tabs.query:", chrome.runtime.lastError);
99-
// 因为API报错,我们不应无视并尝试强行打开新页面
100-
return;
101-
}
102-
if (tabs.length) {
103-
chrome.tabs.create({
104-
url,
105-
openerTabId: tabs[0].id,
106-
index: tabs[0].index + 1,
107-
});
108-
} else {
109-
chrome.tabs.create({
110-
url,
111-
});
112-
}
113-
}
114-
);
115-
}
116-
11790
export function isDebug() {
11891
return process.env.NODE_ENV === "development";
11992
}
12093

94+
// https://developer.chrome.com/docs/extensions/reference/api/tabs?hl=en#get_the_current_tab
95+
export async function getCurrentTab() {
96+
// `tab` will either be a `tabs.Tab` instance or `undefined`.
97+
const [tab] = await chrome.tabs.query({ active: true, lastFocusedWindow: true });
98+
return tab;
99+
}
100+
121101
// 检查订阅规则是否改变,是否能够静默更新
122102
export function checkSilenceUpdate(oldMeta: Metadata, newMeta: Metadata): boolean {
123103
// 判断connect是否改变
@@ -165,6 +145,40 @@ export function getIcon(script: Script): string | undefined {
165145
);
166146
}
167147

148+
// 在当前页后打开一个新页面
149+
export async function openInCurrentTab(url: string) {
150+
const tab = await getCurrentTab();
151+
const createProperties: chrome.tabs.CreateProperties = { url };
152+
if (tab) {
153+
// 添加 openerTabId 有可能出现 Error "Tab opener must be in the same window as the updated tab."
154+
if (tab.id! >= 0) {
155+
// 如 Tab API 有提供 tab.id, 則指定 tab.id
156+
createProperties.openerTabId = tab.id;
157+
if (tab.windowId! >= 0) {
158+
// 如 Tab API 有提供 tab.windowId, 則指定 tab.windowId
159+
createProperties.windowId = tab.windowId;
160+
}
161+
}
162+
createProperties.index = tab.index + 1;
163+
}
164+
// 先嘗試以 openerTabId 和 windowId 打開
165+
try {
166+
await chrome.tabs.create(createProperties);
167+
return;
168+
} catch {
169+
// do nothing
170+
}
171+
// 失敗的話,刪去 openerTabId 和 windowId ,再次嘗試打開
172+
delete createProperties.openerTabId;
173+
delete createProperties.windowId;
174+
try {
175+
await chrome.tabs.create(createProperties);
176+
return;
177+
} catch {
178+
// do nothing
179+
}
180+
}
181+
168182
export function errorMsg(e: any): string {
169183
if (typeof e === "string") {
170184
return e;

0 commit comments

Comments
 (0)