-
Notifications
You must be signed in to change notification settings - Fork 0
/
background.ts
106 lines (91 loc) · 2.32 KB
/
background.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import Sval from "sval";
import * as acorn from "acorn";
let program: acorn.Program | undefined;
async function onScriptChanged() {
program = undefined;
const { script } = await browser.storage.local.get("script");
if (!script) {
return;
}
program = acorn.parse(`exports.end = (() => { ${script} })()`, {
ecmaVersion: "latest",
sourceType: "script",
});
}
onScriptChanged();
browser.storage.local.onChanged.addListener(onScriptChanged);
interface ContainerInfo {
name: string;
icon?: string;
color?: string;
}
function toContainerInfo(value: any): ContainerInfo | undefined {
if (!value) {
return undefined;
}
if (typeof value === "string") {
return { name: value };
}
if (typeof value === "object") {
if (value.name && typeof value.name === "string") {
return value;
}
}
return undefined;
}
async function onBeforeRequest(
request: browser.webRequest._OnBeforeRequestDetails,
): Promise<browser.webRequest.BlockingResponse> {
if (!program) {
return {};
}
const interpreter = new Sval({
ecmaVer: "latest",
sourceType: "script",
sandBox: true,
});
interpreter.import({ url: new URL(request.url) });
interpreter.run(program);
const info = toContainerInfo(interpreter.exports.end);
if (!info) {
return {};
}
// Get or create the container
const containers = await browser.contextualIdentities.query({
name: info.name,
});
const container =
containers[0] ??
(await browser.contextualIdentities.create({
name: info.name,
color: info.color ?? "blue",
icon: info.icon ?? "fingerprint",
}));
// Check if it's already in the correct container
const tab = await browser.tabs.get(request.tabId);
if (tab.cookieStoreId === container.cookieStoreId) {
return {};
}
// Create new tab in container
await browser.tabs.create({
url: request.url,
cookieStoreId: container.cookieStoreId,
});
// Close the old tab
await browser.tabs.remove(request.tabId);
return { cancel: true };
}
// Listen for web requests
browser.webRequest.onBeforeRequest.addListener(
onBeforeRequest,
{
urls: ["<all_urls>"],
types: ["main_frame"],
},
["blocking"],
);
browser.browserAction.onClicked.addListener(async () => {
await browser.tabs.create({
url: browser.runtime.getURL("ui.html"),
});
});