-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathdarkmode.js
More file actions
76 lines (71 loc) · 2.63 KB
/
darkmode.js
File metadata and controls
76 lines (71 loc) · 2.63 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
(() => {
const STYLE_ID = "superlevels-darkmode";
// CSS approach: invert the whole page, then re-invert media so images/videos look normal
function buildCSS(brightness) {
const b = brightness / 100;
return `
html.superlevels-dark {
filter: invert(1) hue-rotate(180deg) brightness(${b}) !important;
background: #fff !important;
}
html.superlevels-dark img,
html.superlevels-dark video,
html.superlevels-dark canvas,
html.superlevels-dark svg image,
html.superlevels-dark picture,
html.superlevels-dark [style*="background-image"],
html.superlevels-dark iframe {
filter: invert(1) hue-rotate(180deg) !important;
}
/* Don't double-invert nested media inside iframes - handled by iframe's own injection */
/* Fix common elements that break */
html.superlevels-dark input,
html.superlevels-dark textarea,
html.superlevels-dark select {
background-color: inherit !important;
color: inherit !important;
}
`;
}
function applyDarkMode(enabled, brightness) {
let style = document.getElementById(STYLE_ID);
if (enabled) {
if (!style) {
style = document.createElement("style");
style.id = STYLE_ID;
(document.head || document.documentElement).appendChild(style);
}
style.textContent = buildCSS(brightness);
document.documentElement.classList.add("superlevels-dark");
} else {
document.documentElement.classList.remove("superlevels-dark");
if (style) style.remove();
}
}
// Get hostname for per-site storage
const host = location.hostname;
const storageKey = "darkmode_" + host;
const globalKey = "darkmode_global";
// Load state as early as possible to prevent flash
chrome.storage.local.get([storageKey, globalKey, "darkmode_brightness"], (data) => {
// Per-site overrides global. If per-site is undefined, fall back to global.
const siteState = data[storageKey];
const globalState = data[globalKey];
const enabled = siteState !== undefined ? siteState : (globalState || false);
const brightness = data.darkmode_brightness || 100;
if (enabled) applyDarkMode(true, brightness);
});
// Listen for toggle messages from popup
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.type === "darkmode_toggle") {
applyDarkMode(msg.enabled, msg.brightness || 100);
sendResponse({ ok: true });
}
if (msg.type === "darkmode_query") {
sendResponse({
active: document.documentElement.classList.contains("superlevels-dark"),
host: host,
});
}
});
})();