Detect browser theme on Firefox (#139)

This commit is contained in:
Nils Maier 2019-10-02 14:54:51 +02:00
parent 5e323db2f0
commit 9caad6b3a5
5 changed files with 71 additions and 4 deletions

View File

@ -675,7 +675,7 @@
},
"pref_theme_default": {
"description": "option text",
"message": "System/Browser default"
"message": "System/Browser"
},
"pref_theme_light": {
"description": "option text",

View File

@ -114,5 +114,6 @@ export const {tabs} = polyfill;
export const {webNavigation} = polyfill;
export const {webRequest}: {webRequest: WebRequest} = polyfill;
export const {windows} = polyfill;
export const {theme} = polyfill;
export const CHROME = navigator.appVersion.includes("Chrome/");

View File

@ -33,6 +33,7 @@
"sessions",
"storage",
"tabs",
"theme",
"webNavigation",
"webRequest",
"webRequestBlocking"

View File

@ -27,7 +27,7 @@ LICENSED = set((".css", ".html", ".js", "*.ts"))
IGNORED = set((".DS_Store", "Thumbs.db"))
PERM_IGNORED_FX = set(("downloads.shelf", "webRequest", "webRequestBlocking"))
PERM_IGNORED_CHROME = set(("menus", "sessions"))
PERM_IGNORED_CHROME = set(("menus", "sessions", "theme"))
SCRIPTS = [
"yarn build:regexps",

View File

@ -1,7 +1,29 @@
/* eslint-disable no-magic-numbers */
"use strict";
// License: MIT
import { PrefWatcher } from "../lib/prefs";
import { theme } from "../lib/browser";
import { memoize } from "../lib/memoize";
const resolveColor = memoize(function(color) {
try {
const el = document.createElement("div");
el.style.backgroundColor = color;
el.style.display = "none";
document.body.appendChild(el);
try {
const resolved = window.getComputedStyle(el, null).backgroundColor;
return resolved;
}
finally {
document.body.removeChild(el);
}
}
catch {
return undefined;
}
}, 10, 1);
export const THEME = new class Theme extends PrefWatcher {
public systemDark: boolean;
@ -10,6 +32,10 @@ export const THEME = new class Theme extends PrefWatcher {
constructor() {
super("theme", "default");
if (theme && theme.onUpdated) {
theme.onUpdated.addListener(this.onThemeUpdated.bind(this));
theme.getCurrent().then((theme: any) => this.onThemeUpdated({theme}));
}
this.themeDark = undefined;
const query = window.matchMedia("(prefers-color-scheme: dark)");
this.systemDark = query.matches;
@ -21,7 +47,6 @@ export const THEME = new class Theme extends PrefWatcher {
}
get dark() {
console.warn("theme", this.value);
if (this.value === "dark") {
return true;
}
@ -40,8 +65,48 @@ export const THEME = new class Theme extends PrefWatcher {
return rv;
}
onThemeUpdated({theme}: {theme: any}) {
try {
if (!theme) {
this.themeDark = undefined;
return;
}
const {colors} = theme;
if (!colors) {
this.themeDark = undefined;
return;
}
const color = resolveColor(
colors.toolbar || colors.popup || colors.ntp_background);
if (!color) {
this.themeDark = undefined;
return;
}
const pieces = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);
if (!pieces) {
this.themeDark = undefined;
return;
}
const r = parseInt(pieces[1], 10);
const g = parseInt(pieces[2], 10);
const b = parseInt(pieces[3], 10);
// HSP (Highly Sensitive Poo) equation from
// http://alienryderflex.com/hsp.html
const hsp = Math.sqrt(
0.299 * (r * r) +
0.587 * (g * g) +
0.114 * (b * b)
);
this.themeDark = hsp < 128;
}
finally {
this.recalculate();
}
}
recalculate() {
console.warn("darkness", this.dark);
document.documentElement.classList[this.dark ? "add" : "remove"]("dark");
}
}();