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