Skip to content

Commit bcc2a5b

Browse files
authored
✨ 实现 window.close / window.focus (#383)
1 parent 20eba92 commit bcc2a5b

5 files changed

Lines changed: 52 additions & 21 deletions

File tree

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "scriptcat",
3-
"version": "0.17.0-alpha.4",
3+
"version": "0.17.0-alpha.5",
44
"description": "脚本猫,一个可以执行用户脚本的浏览器扩展,万物皆可脚本化,让你的浏览器可以做更多的事情!",
55
"author": "CodFrm",
66
"license": "GPLv3",
@@ -83,4 +83,4 @@
8383
"vitest": "^2.1.4"
8484
},
8585
"packageManager": "pnpm@10.8.0"
86-
}
86+
}

src/app/service/content/gm_api.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@ export class GMContext {
2424
public static API(param: ApiParam = {}) {
2525
return (target: any, propertyName: string, descriptor: PropertyDescriptor) => {
2626
const key = propertyName;
27-
if (key === "GMDotGetResourceUrl") {
28-
GMContext.apis.set("GM.getResourceUrl", {
29-
api: descriptor.value,
30-
param,
31-
});
27+
if (/^(GM|window)Dot/.test(key)) {
28+
GMContext.apis.set(
29+
key.replace(/^(GM|window)Dot(.)/, (_, a, b) => `${a}.${b.toLowerCase()}`),
30+
{
31+
api: descriptor.value,
32+
param,
33+
}
34+
);
3235
return;
3336
}
3437
GMContext.apis.set(key, {
@@ -823,4 +826,14 @@ export default class GMApi {
823826
}
824827
return Promise.resolve(undefined);
825828
}
829+
830+
@GMContext.API()
831+
windowDotClose() {
832+
return this.sendMessage("windowDotClose", []);
833+
}
834+
835+
@GMContext.API()
836+
windowDotFocus() {
837+
return this.sendMessage("windowDotFocus", []);
838+
}
826839
}

src/app/service/content/utils.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,17 @@ export function createContext(scriptRes: ScriptRunResouce, GMInfo: any, envPrefi
7070
EE: new EventEmitter(),
7171
GM: { Info: GMInfo },
7272
GM_info: GMInfo,
73+
window: {},
7374
};
7475
if (scriptRes.metadata.grant) {
7576
scriptRes.metadata.grant.forEach((val) => {
7677
const api = GMContext.apis.get(val);
7778
if (!api) {
7879
return;
7980
}
80-
if (val.startsWith("GM.")) {
81-
const [, t] = val.split(".");
82-
(<{ [key: string]: any }>context.GM)[t] = api.api.bind(context);
81+
if (/^(GM|window)\./.test(val)) {
82+
const [n, t] = val.split(".");
83+
(<{ [key: string]: any }>context[n])[t] = api.api.bind(context);
8384
} else if (val === "GM_cookie") {
8485
// 特殊处理GM_cookie.list之类
8586
context[val] = api.api.bind(context);
@@ -200,6 +201,11 @@ export function proxyContext(global: any, context: any, thisContext?: { [key: st
200201
return special.global || proxy;
201202
}
202203
return global.top;
204+
case "close":
205+
case "focus":
206+
if (context["window"][name]) {
207+
return context["window"][name];
208+
}
203209
default:
204210
break;
205211
}

src/app/service/service_worker/gm_api.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,24 @@ export default class GMApi {
890890
await sendMessage(this.send, "offscreen/gmApi/setClipboard", { data, type });
891891
}
892892

893+
@PermissionVerify.API({ alias: ["window.close"] })
894+
async windowDotClose(request: Request, sender: GetSender) {
895+
/*
896+
* Note: for security reasons it is not allowed to close the last tab of a window.
897+
* https://www.tampermonkey.net/documentation.php#api:window.close
898+
* 暂不清楚安全原因具体指什么
899+
* 原生window.close也可能关闭最后一个标签,暂不做限制
900+
*/
901+
await chrome.tabs.remove(sender.getSender().tab?.id as number);
902+
}
903+
904+
@PermissionVerify.API({ alias: ["window.focus"] })
905+
async windowDotFocus(request: Request, sender: GetSender) {
906+
await chrome.tabs.update(sender.getSender().tab?.id as number, {
907+
active: true,
908+
});
909+
}
910+
893911
handlerNotification() {
894912
const send = async (event: string, notificationId: string, params?: any) => {
895913
const ret = (await Cache.getInstance().get(`GM_notification:${notificationId}`)) as NotificationData;

src/manifest.json

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "__MSG_scriptcat__",
4-
"version": "0.17.0.1005",
4+
"version": "0.17.0.1006",
55
"author": "CodFrm",
66
"description": "__MSG_scriptcat_description__",
77
"options_ui": {
@@ -10,9 +10,7 @@
1010
},
1111
"background": {
1212
"service_worker": "src/service_worker.js",
13-
"scripts": [
14-
"src/service_worker.js"
15-
]
13+
"scripts": ["src/service_worker.js"]
1614
},
1715
"action": {
1816
"default_popup": "src/popup.html",
@@ -41,12 +39,8 @@
4139
"unlimitedStorage",
4240
"declarativeNetRequest"
4341
],
44-
"host_permissions": [
45-
"<all_urls>"
46-
],
42+
"host_permissions": ["<all_urls>"],
4743
"sandbox": {
48-
"pages": [
49-
"src/sandbox.html"
50-
]
44+
"pages": ["src/sandbox.html"]
5145
}
52-
}
46+
}

0 commit comments

Comments
 (0)