-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.ts
66 lines (57 loc) · 2.21 KB
/
config.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
import type { TweetAutoLinkBreakerConfigAll as ConfigAll, TweetAutoLinkBreakerConfig } from 'break-tweet-autolink';
export type ConfigName = keyof ConfigAll;
export type ElemIdGetFunc = (n: ConfigName) => string;
type EmptyObject = { [k: string]: unknown };
// prettier-ignore
export const DEFAULT_CONFIG = {
'mention': true,
'list': true,
'hashtag': true,
'cashtag': true,
'urlNoScheme': true,
'urlWithScheme': false,
};
export const DEFAULT_CONFIG_NAMES = Object.keys(DEFAULT_CONFIG) as Array<keyof typeof DEFAULT_CONFIG>;
function isEmptyObject(o: object): o is EmptyObject {
return Object.keys(o).length === 0;
}
function getElemForConfig(id: string): HTMLInputElement {
const elem = document.getElementById(id);
if (elem === null) {
throw new Error(`<input> does not exist for config '${name}'`);
}
return elem as HTMLInputElement;
}
export function setConfigToElems(config: ConfigAll | EmptyObject, id: ElemIdGetFunc): void {
// Note: The loaded object may be empty when the value is not saved yet
const c: ConfigAll = isEmptyObject(config) ? DEFAULT_CONFIG : config;
for (const k of Object.keys(config) as Array<keyof ConfigAll>) {
const v = c[k];
if (typeof v === 'boolean') {
getElemForConfig(id(k)).checked = v;
}
}
}
export function getConfigFromElems(id: ElemIdGetFunc): ConfigAll {
// Note: es2019.object.d.ts does not work with string literal types as keys of object.
// The return type of Object.fromEntries() falls back to {[k: string]: T; [k: number]: T}.
const ret: TweetAutoLinkBreakerConfig = {};
for (const name of DEFAULT_CONFIG_NAMES) {
ret[name] = getElemForConfig(id(name)).checked;
}
return ret as ConfigAll;
}
export function loadConfig(): Promise<ConfigAll> {
return new Promise<ConfigAll>(resolve => {
chrome.storage.sync.get(DEFAULT_CONFIG_NAMES, (c: ConfigAll | EmptyObject) => {
if (isEmptyObject(c)) {
resolve(DEFAULT_CONFIG);
} else {
resolve(c);
}
});
});
}
export function saveConfig(c: ConfigAll): Promise<void> {
return new Promise<void>(resolve => chrome.storage.sync.set(c, resolve));
}