-
Notifications
You must be signed in to change notification settings - Fork 0
/
background.js
118 lines (110 loc) · 3.51 KB
/
background.js
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
107
108
109
110
111
112
113
114
115
116
117
118
// https://stackoverflow.com/a/62364519
function base64ToBytesArr(str) {
const abc = [
...'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
]; // base64 alphabet
let result = [];
for (let i = 0; i < str.length / 4; i++) {
let chunk = [...str.slice(4 * i, 4 * i + 4)];
let bin = chunk
.map((x) => abc.indexOf(x).toString(2).padStart(6, 0))
.join('');
let bytes = bin.match(/.{1,8}/g).map((x) => +('0b' + x));
result.push(
...bytes.slice(0, 3 - (str[4 * i + 2] == '=') - (str[4 * i + 3] == '='))
);
}
return result;
}
globalThis.name = chrome.runtime.getManifest().short_name;
globalThis.externallyConnectablePort = null;
globalThis.nativeMessagingPort = null;
chrome.runtime.onConnectExternal.addListener((port) => {
globalThis.externallyConnectablePort = port;
globalThis.externallyConnectablePort.onMessage.addListener((message) => {
if (message === 'disconnect') {
globalThis.nativeMessagingPort.disconnect();
globalThis.externallyConnectablePort.disconnect();
}
if (!globalThis.nativeMessagingPort) {
globalThis.nativeMessagingPort = chrome.runtime.connectNative(globalThis.name);
globalThis.nativeMessagingPort.onMessage.addListener((nativeMessage) => {
const {
done,
value
} = nativeMessage;
if (!done) {
nativeMessage.value = base64ToBytesArr(nativeMessage.value);
}
globalThis.externallyConnectablePort.postMessage(nativeMessage)
if (done) {
globalThis.nativeMessagingPort.disconnect();
}
});
globalThis.nativeMessagingPort.postMessage(message);
}
});
globalThis.externallyConnectablePort.onDisconnect.addListener((_) => {
console.log('Disconnected');
globalThis.externallyConnectablePort = null;
globalThis.nativeMessagingPort = null;
if (chrome.runtime.lastError) {
console.warn(chrome.runtime.lastError);
}
});
});
chrome.runtime.onInstalled.addListener((reason) => {
console.log(reason);
});
// Dynamically set "externally_connectable" and "web_accessible_resources"
chrome.action.onClicked.addListener(async (tab) => {
const url = new URL(tab.url);
const manifest = chrome.runtime.getManifest();
manifest.externally_connectable.matches = [
...new Set([`${url.origin}/*`, ...manifest.externally_connectable.matches]),
];
manifest.web_accessible_resources[0].matches = [
...new Set([`${url.origin}/*`, ...manifest.web_accessible_resources[0].matches]),
];
try {
const [{
result
}] = await chrome.scripting.executeScript({
target: {
tabId: tab.id
},
world: 'MAIN',
args: [
[...new TextEncoder().encode(JSON.stringify(manifest, null, 2))]
],
func: async (manifest) => {
try {
const dir = await showDirectoryPicker({
mode: 'readwrite',
id: 'update'
});
const handle = await dir.getFileHandle('manifest.json', {
create: false
});
await new Blob([new Uint8Array(manifest)], {
type: 'application/json'
})
.stream()
.pipeTo(
await handle.createWritable()
);
console.log(`${handle.name} updated`);
return `${handle.name} updated`;
} catch (e) {
console.warn(e);
throw e;
}
}
});
if (result == 'manifest.json updated') {
chrome.runtime.reload();
};
} catch (e) {
console.warn(e);
}
});