Skip to content

Commit 865e5f6

Browse files
authored
✨ 实现 @run-in / 分离隐身模式 (#384)
* 实现 @run-in / 分离隐身模式 @run-in api 显式声明脚本注入标签类型 - `normal-tabs` 注入正常标签 - `incognito-tabs` 注入隐身标签 缺省时、同时声明时,既注入正常标签又隐身标签 具体用法见新增示例 新增 `CacheStorage.prototype.clear` 清除所有缓存 同步更新`GM_info` `manifest.json`显示声明`"incognito": "split"`分离浏览器隐身模式时扩展进程及上下文 `package.json`新增`dev-noMap`方法 - 无`SourceMap`的`development`模式 (已知带`SourceMap`的`dev`模式会造成扩展的`service_work.js`无法完成注册,可能是浏览器限制或bug) * 优化 仅隐身模式第一次初始化清理session * fix * fix allFrames * 优化 run-in 实现 * 恢复逻辑 getUserScriptRegister 实际是get+set * 恢复 Promise.all
1 parent 7cd1dcd commit 865e5f6

13 files changed

Lines changed: 95 additions & 32 deletions

File tree

example/run-in/run-in_both.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// ==UserScript==
2+
// @name Test @run-in both
3+
// @namespace https://bbs.tampermonkey.net.cn/
4+
// @version 0.1.0
5+
// @description @run-in normal-tabs & @run-in incognito-tabs 既注入正常标签又注入隐身标签
6+
// @author You
7+
// @match https://bbs.tampermonkey.net.cn/*
8+
// @run-in normal-tabs
9+
// @run-in incognito-tabs
10+
// ==/UserScript==
11+
console.log(GM_info.script["run-in"]);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// ==UserScript==
2+
// @name Test @run-in incognito-tabs
3+
// @namespace https://bbs.tampermonkey.net.cn/
4+
// @version 0.1.0
5+
// @description @run-in incognito-tabs 只注入隐身标签
6+
// @author You
7+
// @match https://bbs.tampermonkey.net.cn/*
8+
// @run-in incognito-tabs
9+
// ==/UserScript==
10+
console.log(GM_info.script["run-in"]);

example/run-in/run-in_none.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// ==UserScript==
2+
// @name Test @run-in none
3+
// @namespace https://bbs.tampermonkey.net.cn/
4+
// @version 0.1.0
5+
// @description 不设置@run-in默认既注入正常标签又注入隐身标签
6+
// @author You
7+
// @match https://bbs.tampermonkey.net.cn/*
8+
// ==/UserScript==
9+
console.log(GM_info.script["run-in"]);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// ==UserScript==
2+
// @name Test @run-in normal-tabs
3+
// @namespace https://bbs.tampermonkey.net.cn/
4+
// @version 0.1.0
5+
// @description @run-in normal-tabs 只注入正常标签
6+
// @author You
7+
// @match https://bbs.tampermonkey.net.cn/*
8+
// @run-in normal-tabs
9+
// ==/UserScript==
10+
console.log(GM_info.script["run-in"]);

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"coverage": "vitest run --coverage",
1212
"build": "cross-env NODE_ENV=production rspack build",
1313
"dev": "cross-env NODE_ENV=development rspack",
14+
"dev-noMap": "cross-env NODE_ENV=development NO_MAP=true rspack",
1415
"pack": "node ./scripts/pack.js",
1516
"format": "prettier --write .",
1617
"lint": "eslint .",

rspack.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default defineConfig({
2020
? {
2121
watch: true,
2222
mode: "development",
23-
devtool: "inline-source-map",
23+
devtool: process.env.NO_MAP === "true" ? false : "inline-source-map",
2424
}
2525
: {
2626
mode: "production",

src/app/cache.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export interface CacheStorage {
44
batchSet(data: { [key: string]: any }): Promise<void>;
55
has(key: string): Promise<boolean>;
66
del(key: string): Promise<void>;
7+
clear(): Promise<void>;
78
list(): Promise<string[]>;
89
}
910

@@ -53,6 +54,14 @@ export class ExtCache implements CacheStorage {
5354
});
5455
}
5556

57+
clear(): Promise<void> {
58+
return new Promise((resolve) => {
59+
chrome.storage.session.clear(() => {
60+
resolve();
61+
});
62+
});
63+
}
64+
5665
list(): Promise<string[]> {
5766
return new Promise((resolve) => {
5867
chrome.storage.session.get(null, (value) => {
@@ -91,6 +100,13 @@ export class MapCache {
91100
});
92101
}
93102

103+
clear(): Promise<void> {
104+
return new Promise((resolve) => {
105+
this.map.clear();
106+
resolve();
107+
});
108+
}
109+
94110
list(): Promise<string[]> {
95111
return new Promise((resolve) => {
96112
resolve(Array.from(this.map.keys()));
@@ -144,6 +160,10 @@ export default class Cache {
144160
return this.storage.del(key);
145161
}
146162

163+
public clear(): Promise<void> {
164+
return this.storage.clear();
165+
}
166+
147167
public list(): Promise<string[]> {
148168
return this.storage.list();
149169
}

src/app/service/content/gm_api.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@ export default class GMApi {
113113
const metadataStr = getMetadataStr(script.code);
114114
const userConfigStr = getUserConfigStr(script.code) || "";
115115
const options = {
116-
description: (script.metadata.description && script.metadata.description[0]) || null,
116+
description: script.metadata.description?.[0] || null,
117117
matches: script.metadata.match || [],
118118
includes: script.metadata.include || [],
119-
"run-at": (script.metadata["run-at"] && script.metadata["run-at"][0]) || "document-idle",
120-
icon: (script.metadata.icon && script.metadata.icon[0]) || null,
121-
icon64: (script.metadata.icon64 && script.metadata.icon64[0]) || null,
119+
"run-at": script.metadata["run-at"]?.[0] || "document-idle",
120+
"run-in": script.metadata["run-in"] || [],
121+
icon: script.metadata.icon?.[0] || null,
122+
icon64: script.metadata.icon64?.[0] || null,
122123
header: metadataStr,
123124
grant: script.metadata.grant || [],
124125
connects: script.metadata.connect || [],
@@ -139,7 +140,7 @@ export default class GMApi {
139140
// TODO: 更多完整的信息(为了兼容Tampermonkey,后续待定)
140141
name: script.name,
141142
namespace: script.namespace,
142-
version: script.metadata.version && script.metadata.version[0],
143+
version: script.metadata.version?.[0],
143144
author: script.author,
144145
...options,
145146
},

src/app/service/service_worker/runtime.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ export class RuntimeService {
208208
// 过滤掉undefined和未开启的
209209
return res.filter((item) => item) as chrome.userScripts.RegisteredUserScript[];
210210
});
211+
211212
// 如果脚本开启, 则注册脚本
212213
if (this.isEnableDeveloperMode && this.isEnableUserscribe) {
213214
// 批量注册
@@ -313,23 +314,30 @@ export class RuntimeService {
313314
// 匹配当前页面的脚本
314315
const matchScriptUuid = await this.getPageScriptUuidByUrl(chromeSender.url!);
315316

316-
const scripts = matchScriptUuid.map((uuid) => {
317+
const enableScript = matchScriptUuid.reduce((arr, uuid) => {
317318
const scriptRes = Object.assign({}, this.scriptMatchCache?.get(uuid));
318319
// 判断脚本是否开启
319320
if (scriptRes.status === SCRIPT_STATUS_DISABLE) {
320-
return undefined;
321+
return arr;
322+
}
323+
// 判断注入页面类型
324+
if (scriptRes.metadata["run-in"]) {
325+
// 判断插件运行环境
326+
const contextType = chrome.extension.inIncognitoContext ? "incognito-tabs" : "normal-tabs";
327+
if (!scriptRes.metadata["run-in"].includes(contextType)) {
328+
return arr;
329+
}
321330
}
322331
// 如果是iframe,判断是否允许在iframe里运行
323332
if (chromeSender.frameId) {
324333
if (scriptRes.metadata.noframes) {
325-
return undefined;
334+
return arr;
326335
}
327336
}
328337
// 获取value
329-
return scriptRes;
330-
});
331-
332-
const enableScript = scripts.filter((item) => item) as ScriptMatchInfo[];
338+
arr.push(scriptRes);
339+
return arr;
340+
}, [] as ScriptMatchInfo[]);
333341

334342
await Promise.all([
335343
// 加载value
@@ -533,6 +541,7 @@ export class RuntimeService {
533541
id: scriptRes.uuid,
534542
js: [{ code: scriptRes.code }],
535543
matches: patternMatches.patternResult,
544+
allFrames: !scriptRes.metadata["noframes"],
536545
world: "MAIN",
537546
};
538547

@@ -563,12 +572,6 @@ export class RuntimeService {
563572
// 将脚本match信息放入缓存中
564573
this.addScriptMatch(scriptMatchInfo);
565574

566-
// 注册脚本信息
567-
if (scriptRes.metadata["noframes"]) {
568-
registerScript.allFrames = false;
569-
} else {
570-
registerScript.allFrames = true;
571-
}
572575
if (scriptRes.metadata["run-at"]) {
573576
registerScript.runAt = getRunAt(scriptRes.metadata["run-at"]);
574577
}

src/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
"open_in_tab": true
1010
},
1111
"background": {
12-
"service_worker": "src/service_worker.js",
13-
"scripts": ["src/service_worker.js"]
12+
"service_worker": "src/service_worker.js"
1413
},
14+
"incognito": "split",
1515
"action": {
1616
"default_popup": "src/popup.html",
1717
"default_icon": {

0 commit comments

Comments
 (0)