-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathcommon.js
119 lines (106 loc) · 2.91 KB
/
common.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
119
// inline 'export' keyword is used since everything in this module is expected to be exported
import {compressToUTF16, decompressFromUTF16} from './lz-string.js';
export const RETRY_TIMEOUT = 2;
export const NOP = () => {};
export const inBG = new Proxy({}, {
get: (_, action) => (...data) => chrome.runtime.sendMessage({action, data}),
});
const STATUS_STYLE = `
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 24px;
border: none;
opacity: .7;
z-index: 1000;
margin: 0;
padding: 0;
color: white;
font: bold 12px/24px sans-serif;
text-align: center;
transition: opacity 1s;
`.replace(/\n\s+/g, '\n').trim();
/** @namespace Settings */
export const DEFAULTS = Object.freeze({
showStatus: true,
darkTheme: false,
enabled: true,
/** seconds */
requestInterval: 2,
/** minutes */
unloadAfter: 1,
rules: [],
genericRulesEnabled: false,
genericSites: ['*'],
exclusions: [],
/** pixels */
pageHeightThreshold: 400,
statusStyle: STATUS_STYLE + '\nbackground: black;',
statusStyleError: STATUS_STYLE + '\nbackground: maroon;',
});
export const getActiveTab = async () =>
(await chrome.tabs.query({active: true, currentWindow: true}))[0];
for (const ns of ['runtime', 'tabs']) {
const obj = chrome[ns];
const fn = obj.sendMessage;
obj.sendMessage = async (...args) => {
const {stack} = new Error();
try {
return await fn.apply(obj, args);
} catch (err) {
err.stack += '\nPrior to sendMessage:\n' + stack;
throw err;
}
};
}
/**
* @param {string|string[]} key
* @return {Promise<Settings>}
*/
export async function loadSettings(key = Object.keys(DEFAULTS)) {
const res = await chrome.storage.sync.get(key);
const isKeyArray = Array.isArray(key);
for (const k of isKeyArray ? key : [key]) {
let v = res[k];
if (v == null)
res[k] = DEFAULTS[k];
else if (v && (v = getLZ(k, v, false)))
res[k] = v;
}
return isKeyArray ? res : res[key];
}
export function getLZ(key, val, write) {
if (!val) return val;
let json;
const d = DEFAULTS[key];
if (typeof d === 'string' || (json = Array.isArray(d))) {
try {
val = write ? compressToUTF16(json ? JSON.stringify(val) : val)
: json ? JSON.parse(decompressFromUTF16(val)) :
decompressFromUTF16(val);
} catch (err) {
console.warn(err, key, val);
}
}
return val;
}
export function isGenericUrl(url) {
return url === '^https?://.' ||
url === '^https?://..' ||
url === '^https?://.+';
}
export function ignoreLastError() {
chrome.runtime.lastError; // eslint-disable-line no-unused-expressions
}
export function arrayOrDummy(v) {
return Array.isArray(v) ? v : [];
}
export function doDelay(seconds) {
const pr = Promise.withResolvers();
setTimeout(pr.resolve, seconds * 1000);
return pr.promise;
}
export function tabSend(tabId, msg) {
return chrome.tabs.sendMessage(tabId, msg, {frameId: 0}).catch(NOP);
}