forked from darkreader/darkreader
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdynamic-theme.ts
More file actions
85 lines (76 loc) · 3.26 KB
/
Copy pathdynamic-theme.ts
File metadata and controls
85 lines (76 loc) · 3.26 KB
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
import {formatSitesFixesConfig} from './utils/format';
import {parseSitesFixesConfig, getSitesFixesFor, getDomain} from './utils/parse';
import type {SitePropsIndex} from './utils/parse';
import {formatCSS} from '../utils/css-text/format-css';
import {parseArray, formatArray} from '../utils/text';
import {compareURLPatterns} from '../utils/url';
import type {DynamicThemeFix} from '../definitions';
declare const __CHROMIUM_MV2__: boolean;
declare const __CHROMIUM_MV3__: boolean;
const dynamicThemeFixesCommands: { [key: string]: keyof DynamicThemeFix } = {
'INVERT': 'invert',
'CSS': 'css',
'IGNORE INLINE STYLE': 'ignoreInlineStyle',
'IGNORE IMAGE ANALYSIS': 'ignoreImageAnalysis',
};
export function parseDynamicThemeFixes(text: string): DynamicThemeFix[] {
return parseSitesFixesConfig<DynamicThemeFix>(text, {
commands: Object.keys(dynamicThemeFixesCommands),
getCommandPropName: (command) => dynamicThemeFixesCommands[command],
parseCommandValue: (command, value) => {
if (command === 'CSS') {
return value.trim();
}
return parseArray(value);
},
});
}
export function formatDynamicThemeFixes(dynamicThemeFixes: DynamicThemeFix[]): string {
const fixes = dynamicThemeFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));
return formatSitesFixesConfig(fixes, {
props: Object.values(dynamicThemeFixesCommands),
getPropCommandName: (prop) => Object.entries(dynamicThemeFixesCommands).find(([, p]) => p === prop)![0],
formatPropValue: (prop, value) => {
if (prop === 'css') {
return formatCSS(value as string);
}
return formatArray(value as string[]).trim();
},
shouldIgnoreProp: (prop, value) => {
if (prop === 'css') {
return !value;
}
return !(Array.isArray(value) && value.length > 0);
},
});
}
export function getDynamicThemeFixesFor(url: string, isTopFrame: boolean, text: string, index: SitePropsIndex<DynamicThemeFix>, enabledForPDF: boolean): DynamicThemeFix[] | null {
const fixes = getSitesFixesFor(url, text, index, {
commands: Object.keys(dynamicThemeFixesCommands),
getCommandPropName: (command) => dynamicThemeFixesCommands[command],
parseCommandValue: (command, value) => {
if (command === 'CSS') {
return value.trim();
}
return parseArray(value);
},
});
if (fixes.length === 0 || fixes[0].url[0] !== '*') {
return null;
}
if (enabledForPDF) {
// Copy part of fixes which will be mutated
const fixes_: DynamicThemeFix[] = [...fixes];
fixes_[0] = {...fixes_[0]};
if (__CHROMIUM_MV2__ || __CHROMIUM_MV3__) {
fixes_[0].css += '\nembed[type="application/pdf"][src="about:blank"] { filter: invert(100%) contrast(90%); }';
} else {
fixes_[0].css += '\nembed[type="application/pdf"] { filter: invert(100%) contrast(90%); }';
}
if (['drive.google.com', 'mail.google.com'].includes(getDomain(url))) {
fixes_[0].invert.push('div[role="dialog"] div[role="document"]');
}
return fixes_;
}
return fixes;
}