web/_includes/mode-toggle.html

146 lines
3.2 KiB
HTML
Raw Normal View History

<!-- Switch the mode between dark and light. -->
<script type="text/javascript">
class ModeToggle {
static get MODE_KEY() {
return 'mode';
}
static get MODE_ATTR() {
return 'data-mode';
}
static get DARK_MODE() {
return 'dark';
}
static get LIGHT_MODE() {
return 'light';
}
static get ID() {
return 'mode-toggle';
}
constructor() {
2020-12-10 21:20:18 +03:00
if (this.hasMode) {
if (this.isDarkMode) {
2020-04-01 19:30:00 +03:00
if (!this.isSysDarkPrefer) {
2020-02-14 18:36:38 +03:00
this.setDark();
}
} else {
2020-04-01 19:30:00 +03:00
if (this.isSysDarkPrefer) {
2020-02-14 18:36:38 +03:00
this.setLight();
}
}
}
let self = this;
{%- comment -%} always follow the system prefers {%- endcomment -%}
this.sysDarkPrefers.addEventListener('change', () => {
2020-12-09 21:42:46 +03:00
if (self.hasMode) {
if (self.isDarkMode) {
2020-04-01 19:30:00 +03:00
if (!self.isSysDarkPrefer) {
2020-02-14 18:36:38 +03:00
self.setDark();
}
} else {
2020-04-01 19:30:00 +03:00
if (self.isSysDarkPrefer) {
2020-02-14 18:36:38 +03:00
self.setLight();
}
}
self.clearMode();
}
2020-12-09 21:42:46 +03:00
2021-12-12 21:37:10 +03:00
self.notify();
});
} {%- comment -%} constructor() {%- endcomment -%}
get sysDarkPrefers() {
return window.matchMedia('(prefers-color-scheme: dark)');
}
get isSysDarkPrefer() {
return this.sysDarkPrefers.matches;
}
get isDarkMode() {
return this.mode === ModeToggle.DARK_MODE;
}
2020-04-01 19:30:00 +03:00
get isLightMode() {
return this.mode === ModeToggle.LIGHT_MODE;
}
2020-04-01 19:30:00 +03:00
get hasMode() {
return this.mode != null;
}
2020-04-01 19:30:00 +03:00
get mode() {
return sessionStorage.getItem(ModeToggle.MODE_KEY);
}
{%- comment -%} get the current mode on screen {%- endcomment -%}
2020-12-09 21:42:46 +03:00
get modeStatus() {
if (this.isDarkMode || (!this.hasMode && this.isSysDarkPrefer)) {
2020-12-09 21:42:46 +03:00
return ModeToggle.DARK_MODE;
} else {
return ModeToggle.LIGHT_MODE;
}
}
setDark() {
document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.DARK_MODE);
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
}
setLight() {
document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.LIGHT_MODE);
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
}
clearMode() {
document.documentElement.removeAttribute(ModeToggle.MODE_ATTR);
sessionStorage.removeItem(ModeToggle.MODE_KEY);
}
{%- comment -%}
Notify another plugins that the theme mode has changed
{%- endcomment -%}
2021-12-12 21:37:10 +03:00
notify() {
window.postMessage(
{
direction: ModeToggle.ID,
message: this.modeStatus
},
'*'
);
2020-12-09 21:42:46 +03:00
}
flipMode() {
if (this.hasMode) {
if (this.isSysDarkPrefer) {
if (this.isLightMode) {
this.clearMode();
} else {
this.setLight();
}
2020-04-01 19:30:00 +03:00
} else {
if (this.isDarkMode) {
this.clearMode();
} else {
this.setDark();
}
2020-04-01 19:30:00 +03:00
}
} else {
if (this.isSysDarkPrefer) {
this.setLight();
2020-04-01 19:30:00 +03:00
} else {
this.setDark();
2020-04-01 19:30:00 +03:00
}
}
2020-04-01 19:30:00 +03:00
this.notify();
}
}
const modeToggle = new ModeToggle();
2020-10-23 10:42:43 +03:00
</script>