blob: 8786253a8edeac461aec07645a262e43e912a0a0 (
plain) (
blame)
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
|
/* global chrome */
import 'content-scripts-register-polyfill';
import 'webext-permissions-events-polyfill';
const registeredScripts = new Map<
string,
Promise<browser.contentScripts.RegisteredContentScript>
>();
// In Firefox, paths in the manifest are converted to full URLs under `moz-extension://` but browser.contentScripts expects exclusively relative paths
function convertPath(file: string): browser.extensionTypes.ExtensionFileOrCode {
const url = new URL(file, location.origin);
return {file: url.pathname};
}
async function registerOnOrigins(origins: string[]): Promise<void> {
const manifest = browser.runtime.getManifest();
const configs = manifest.content_scripts!;
const manifestOrigins = [
...(manifest.permissions || []).filter(permission => permission.includes('://')),
...configs.flatMap(config => config.matches)
];
for (const config of configs) {
// Register one at a time to allow removing one at a time as well
for (const origin of origins) {
// This origin is already part of `manifest.json`
if (manifestOrigins.includes(origin)) {
continue;
}
const registeredScript = browser.contentScripts.register({
js: (config.js || []).map(convertPath),
css: (config.css || []).map(convertPath),
allFrames: config.all_frames,
matches: [origin],
runAt: config.run_at
});
registeredScripts.set(origin, registeredScript);
}
}
}
// Automatically register the content scripts on the new origins.
// `registerOnOrigins` already takes care of excluding origins in `manifest.json`
chrome.permissions.getAll(async ({origins}) => registerOnOrigins(origins!));
chrome.permissions.onAdded.addListener(({origins}) => {
if (!origins || origins.length === 0) {
return;
}
registerOnOrigins(origins);
});
chrome.permissions.onRemoved.addListener(async ({origins}) => {
if (!origins || origins.length === 0) {
return;
}
for (const [origin, script] of registeredScripts) {
if (origins.includes(origin)) {
// eslint-disable-next-line no-await-in-loop
(await script).unregister();
}
}
});
|