Skip to content

Commit 4946c78

Browse files
authored
Merge pull request #2576 from tmandry/default-auto-switch
Add "Auto" theme selection which switches between default light and dark theme automatically
2 parents 7a1977a + 54d8d37 commit 4946c78

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

.eslintrc.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"require": "readonly"
1111
},
1212
"parserOptions": {
13-
"ecmaVersion": 2018,
13+
"ecmaVersion": 2021,
1414
"requireConfigFile": false,
1515
"sourceType": "module"
1616
},

src/theme/book.js

+41-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
/* global default_theme, hljs, ClipboardJS */
3+
/* global default_theme, default_dark_theme, default_light_theme, hljs, ClipboardJS */
44

55
// Fix back button cache problem
66
window.onunload = function() { };
@@ -329,7 +329,13 @@ aria-label="Show hidden lines"></button>';
329329
themePopup.querySelectorAll('.theme-selected').forEach(function(el) {
330330
el.classList.remove('theme-selected');
331331
});
332-
themePopup.querySelector('button#' + get_theme()).classList.add('theme-selected');
332+
const selected = get_saved_theme() ?? 'default_theme';
333+
let element = themePopup.querySelector('button#' + selected);
334+
if (element === null) {
335+
// Fall back in case there is no "Default" item.
336+
element = themePopup.querySelector('button#' + get_theme());
337+
}
338+
element.classList.add('theme-selected');
333339
}
334340

335341
function hideThemes() {
@@ -338,20 +344,37 @@ aria-label="Show hidden lines"></button>';
338344
themeToggleButton.focus();
339345
}
340346

341-
function get_theme() {
342-
let theme;
347+
function get_saved_theme() {
348+
let theme = null;
343349
try {
344350
theme = localStorage.getItem('mdbook-theme');
345351
} catch (e) {
346352
// ignore error.
347353
}
354+
return theme;
355+
}
356+
357+
function delete_saved_theme() {
358+
localStorage.removeItem('mdbook-theme');
359+
}
360+
361+
function get_theme() {
362+
const theme = get_saved_theme();
348363
if (theme === null || theme === undefined || !themeIds.includes(theme)) {
349-
return default_theme;
364+
if (typeof default_dark_theme === 'undefined') {
365+
// A customized index.hbs might not define this, so fall back to
366+
// old behavior of determining the default on page load.
367+
return default_theme;
368+
}
369+
return window.matchMedia('(prefers-color-scheme: dark)').matches
370+
? default_dark_theme
371+
: default_light_theme;
350372
} else {
351373
return theme;
352374
}
353375
}
354376

377+
let previousTheme = default_theme;
355378
function set_theme(theme, store = true) {
356379
let ace_theme;
357380

@@ -383,8 +406,6 @@ aria-label="Show hidden lines"></button>';
383406
});
384407
}
385408

386-
const previousTheme = get_theme();
387-
388409
if (store) {
389410
try {
390411
localStorage.setItem('mdbook-theme', theme);
@@ -395,13 +416,17 @@ aria-label="Show hidden lines"></button>';
395416

396417
html.classList.remove(previousTheme);
397418
html.classList.add(theme);
419+
previousTheme = theme;
398420
updateThemeSelected();
399421
}
400422

401-
// Set theme
402-
const theme = get_theme();
423+
const query = window.matchMedia('(prefers-color-scheme: dark)');
424+
query.onchange = function() {
425+
set_theme(get_theme(), false);
426+
};
403427

404-
set_theme(theme, false);
428+
// Set theme.
429+
set_theme(get_theme(), false);
405430

406431
themeToggleButton.addEventListener('click', function() {
407432
if (themePopup.style.display === 'block') {
@@ -420,7 +445,12 @@ aria-label="Show hidden lines"></button>';
420445
} else {
421446
return;
422447
}
423-
set_theme(theme);
448+
if (theme === 'default_theme' || theme === null) {
449+
delete_saved_theme();
450+
set_theme(get_theme(), false);
451+
} else {
452+
set_theme(theme);
453+
}
424454
});
425455

426456
themePopup.addEventListener('focusout', function(e) {

src/theme/index.hbs

+5-2
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@
5353
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
5454
{{/if}}
5555

56-
<!-- Provide site root to javascript -->
56+
<!-- Provide site root and default themes to javascript -->
5757
<script>
5858
const path_to_root = "{{ path_to_root }}";
59-
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
59+
const default_light_theme = "{{ default_theme }}";
60+
const default_dark_theme = "{{ preferred_dark_theme }}";
6061
</script>
6162
<!-- Start loading toc.js asap -->
6263
<script src="{{ resource "toc.js" }}"></script>
@@ -81,6 +82,7 @@
8182

8283
<!-- Set the theme before any content is loaded, prevents flash -->
8384
<script>
85+
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
8486
let theme;
8587
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
8688
if (theme === null || theme === undefined) { theme = default_theme; }
@@ -132,6 +134,7 @@
132134
<i class="fa fa-paint-brush"></i>
133135
</button>
134136
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
137+
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
135138
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
136139
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
137140
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>

0 commit comments

Comments
 (0)