-
-
Notifications
You must be signed in to change notification settings - Fork 201
/
theme.js
64 lines (54 loc) · 1.86 KB
/
theme.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
import { set, observer } from "@ember/object";
import { default as Service, inject as service } from "@ember/service";
import { themes as themesConfig } from "config";
const { themes, system: systemThemes, prefix } = themesConfig;
export default Service.extend({
document: service( "-document" ),
settings: service(),
systemTheme: null,
initialize() {
// calling this in `init` won't trigger the observer of systemTheme when it gets set
this._checkSystemColorScheme();
},
/**
* Query registered color schemes until one matches and update the systemTheme property.
* Add listener to matching query which re-checks color schemes once it doesn't match anymore.
*/
_checkSystemColorScheme() {
const window = this.document.defaultView;
for ( const [ scheme, theme ] of Object.entries( systemThemes ) ) {
let mql = window.matchMedia( `(prefers-color-scheme: ${scheme})` );
if ( !mql.matches ) { continue; }
let listener = e => {
if ( e.matches ) { return; }
mql.removeEventListener( "change", listener );
mql = listener = null;
this._checkSystemColorScheme();
};
mql.addEventListener( "change", listener );
set( this, "systemTheme", theme );
return;
}
// use the default theme if none actually matches (probably unnecessary)
set( this, "systemTheme", systemThemes[ "no-preference" ] );
},
/**
* Apply theme class name to the documentElement
*/
_applyTheme: observer( "settings.content.gui.theme", "systemTheme", function() {
let theme = this.settings.content.gui.theme;
if ( !theme || !themes.includes( theme ) ) {
theme = "system";
}
if ( theme === "system" ) {
theme = this.systemTheme;
}
const classList = this.document.documentElement.classList;
classList.forEach( name => {
if ( name.startsWith( prefix ) ) {
classList.remove( name );
}
});
classList.add( `${prefix}${theme}` );
})
});