Skip to content

Commit 2e9e3aa

Browse files
committed
wip
1 parent 4919988 commit 2e9e3aa

File tree

4 files changed

+109
-100
lines changed

4 files changed

+109
-100
lines changed

src/librustdoc/html/static/js/main.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Local js definitions:
22
/* global addClass, getSettingValue, hasClass, searchState */
33
/* global onEach, onEachLazy, removeClass */
4-
/* global switchTheme, useSystemTheme */
4+
/* global useSystemTheme */
55

66
if (!String.prototype.startsWith) {
77
String.prototype.startsWith = function(searchString, position) {
@@ -60,6 +60,7 @@ function resourcePath(basename, extension) {
6060
window.currentCrate = getVar("current-crate");
6161
window.searchJS = resourcePath("search", ".js");
6262
window.searchIndexJS = resourcePath("search-index", ".js");
63+
window.availableThemes = getVar("themes").split(",");
6364
var sidebarVars = document.getElementById("sidebar-vars");
6465
if (sidebarVars) {
6566
window.sidebarCurrent = {
@@ -130,7 +131,6 @@ function hideThemeButtonState() {
130131
(function () {
131132
var themeChoices = getThemesElement();
132133
var themePicker = getThemePickerElement();
133-
var availableThemes = getVar("themes").split(",");
134134

135135
function switchThemeButtonState() {
136136
if (themeChoices.style.display === "block") {
@@ -155,12 +155,12 @@ function hideThemeButtonState() {
155155

156156
themePicker.onclick = switchThemeButtonState;
157157
themePicker.onblur = handleThemeButtonsBlur;
158-
availableThemes.forEach(function(item) {
158+
window.availableThemes.forEach(function(item) {
159159
var but = document.createElement("button");
160160
but.textContent = item;
161161
but.onclick = function() {
162-
switchTheme(window.currentTheme, window.mainTheme, item, true);
163-
useSystemTheme(false);
162+
useOneTheme(item);
163+
applyThemeUpdate();
164164
};
165165
but.onblur = handleThemeButtonsBlur;
166166
themeChoices.appendChild(but);

src/librustdoc/html/static/js/settings.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Local js definitions:
2-
/* global getSettingValue, getVirtualKey, onEachLazy, updateLocalStorage, updateSystemTheme */
2+
/* global getSettingValue, getVirtualKey, onEachLazy, updateLocalStorage, applyThemeUpdate */
33

44
(function () {
55
function changeSetting(settingName, value) {
@@ -9,7 +9,7 @@
99
case "preferred-dark-theme":
1010
case "preferred-light-theme":
1111
case "use-system-theme":
12-
updateSystemTheme();
12+
applyThemeUpdate();
1313
break;
1414
}
1515
}

src/librustdoc/html/static/js/storage.js

Lines changed: 94 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
var darkThemes = ["dark", "ayu"];
2-
window.currentTheme = document.getElementById("themeStyle");
3-
window.mainTheme = document.getElementById("mainThemeStyle");
42

53
var settingsDataset = (function () {
64
var settingsElement = document.getElementById("default-settings");
@@ -30,10 +28,6 @@ function getSettingValue(settingName) {
3028
return null;
3129
}
3230

33-
var localStoredTheme = getSettingValue("theme");
34-
35-
var savedHref = [];
36-
3731
// eslint-disable-next-line no-unused-vars
3832
function hasClass(elem, className) {
3933
return elem && elem.classList && elem.classList.contains(className);
@@ -104,35 +98,15 @@ function getCurrentValue(name) {
10498
}
10599
}
106100

107-
function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
108-
var newHref = mainStyleElem.href.replace(
109-
/\/rustdoc([^/]*)\.css/, "/" + newTheme + "$1" + ".css");
110-
111-
// If this new value comes from a system setting or from the previously
112-
// saved theme, no need to save it.
113-
if (saveTheme) {
114-
updateLocalStorage("rustdoc-theme", newTheme);
115-
}
116-
117-
if (styleElem.href === newHref) {
118-
return;
119-
}
101+
function themeURL(themeName) {
102+
var mainThemeURL = document.getElementById("mainThemeStyle").href;
103+
return mainThemeURL.replace(/rustdoc([^/]*)\.css/, themeName + "$1.css");
104+
}
120105

121-
var found = false;
122-
if (savedHref.length === 0) {
123-
onEachLazy(document.getElementsByTagName("link"), function(el) {
124-
savedHref.push(el.href);
125-
});
126-
}
127-
onEach(savedHref, function(el) {
128-
if (el === newHref) {
129-
found = true;
130-
return true;
131-
}
132-
});
133-
if (found) {
134-
styleElem.href = newHref;
135-
}
106+
function useOneTheme(value) {
107+
updateLocalStorage("rustdoc-theme", value);
108+
useSystemTheme(false);
109+
applyThemeUpdate();
136110
}
137111

138112
// This function is called from "main.js".
@@ -151,68 +125,105 @@ function useSystemTheme(value) {
151125
}
152126
}
153127

154-
var updateSystemTheme = (function() {
128+
// Returns "light" or "dark" depending on the user's browser preferences
129+
// (that is, independent of any rustdoc settings).
130+
function getSystemTheme() {
155131
if (!window.matchMedia) {
156-
// fallback to the CSS computed value
157-
return function() {
158-
var cssTheme = getComputedStyle(document.documentElement)
159-
.getPropertyValue('content');
160-
161-
switchTheme(
162-
window.currentTheme,
163-
window.mainTheme,
164-
JSON.parse(cssTheme) || "light",
165-
true
166-
);
167-
};
132+
// In rustdoc.css we have:
133+
// @media (prefers-color-scheme: light) {
134+
// html {
135+
// content: "light";
136+
// }
137+
// }
138+
// @media (prefers-color-scheme: dark) {
139+
// html {
140+
// content: "dark";
141+
// }
142+
// }
143+
144+
return getComputedStyle(document.documentElement)
145+
.getPropertyValue('content') || "light";
146+
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
147+
return "dark";
148+
} else {
149+
return "light";
168150
}
151+
}
169152

170-
// only listen to (prefers-color-scheme: dark) because light is the default
171-
var mql = window.matchMedia("(prefers-color-scheme: dark)");
172-
173-
function handlePreferenceChange(mql) {
174-
// maybe the user has disabled the setting in the meantime!
175-
if (getSettingValue("use-system-theme") !== "false") {
176-
var lightTheme = getSettingValue("preferred-light-theme") || "light";
177-
var darkTheme = getSettingValue("preferred-dark-theme") || "dark";
178-
179-
if (mql.matches) {
180-
// prefers a dark theme
181-
switchTheme(window.currentTheme, window.mainTheme, darkTheme, true);
182-
} else {
183-
// prefers a light theme, or has no preference
184-
switchTheme(window.currentTheme, window.mainTheme, lightTheme, true);
185-
}
186-
187-
// note: we save the theme so that it doesn't suddenly change when
188-
// the user disables "use-system-theme" and reloads the page or
189-
// navigates to another page
153+
// If there is a specific theme selected, or if "Use System Theme" is selected
154+
// and there is a specific theme for the current light or dark mode, return
155+
// the appropriate theme's name. Otherwise, return null.
156+
function getThemeOverride() {
157+
if (getSettingValue("use-system-theme") !== "false") {
158+
var lightOverride = getSettingValue("preferred-light-theme");
159+
var darkOverride = getSettingValue("preferred-dark-theme");
160+
161+
var preferred = getSystemTheme();
162+
if (preferred == "light" && lightOverride && lightOverride != "light") {
163+
console.log("lightoverride ", lightOverride);
164+
return lightOverride;
165+
} else if (preferred == "dark" && darkOverride && darkOverride != "dark") {
166+
console.log("darkoverride ", darkOverride)
167+
return darkOverride;
168+
} else {
169+
console.log("use default");
170+
return null;
190171
}
172+
} else {
173+
console.log("getsettingvalue ", getSettingValue("theme"));
174+
return getSettingValue("theme") || null;
191175
}
176+
}
192177

193-
mql.addListener(handlePreferenceChange);
194-
195-
return function() {
196-
handlePreferenceChange(mql);
197-
};
198-
})();
178+
const nonDefaultThemeID = "nonDefaultThemeStyle";
179+
180+
function applyThemeUpdate() {
181+
var lightOverride = getSettingValue("preferred-light-theme");
182+
var darkOverride = getSettingValue("preferred-dark-theme");
183+
var allOverride = getSettingValue("theme");
184+
if (allOverride) {
185+
document.getElementById(nonDefaultThemeID).href = themeURL(allOverride);
186+
} else {
187+
if (lightOverride) {
188+
document.getElementById("lightThemeStyle").href = themeURL(lightOverride);
189+
}
190+
if (darkOverride) {
191+
document.getElementById("darkThemeStyle").href = themeURL(darkOverride);
192+
}
193+
document.getElementById(nonDefaultThemeID).href = "";
194+
}
195+
}
199196

200-
if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
197+
function updatePreferredDarkTheme() {
201198
// update the preferred dark theme if the user is already using a dark theme
202199
// See https://github.com/rust-lang/rust/pull/77809#issuecomment-707875732
200+
var localStoredTheme = getSettingValue("theme");
203201
if (getSettingValue("use-system-theme") === null
204202
&& getSettingValue("preferred-dark-theme") === null
205203
&& darkThemes.indexOf(localStoredTheme) >= 0) {
206204
updateLocalStorage("rustdoc-preferred-dark-theme", localStoredTheme);
207205
}
206+
}
208207

209-
// call the function to initialize the theme at least once!
210-
updateSystemTheme();
211-
} else {
212-
switchTheme(
213-
window.currentTheme,
214-
window.mainTheme,
215-
getSettingValue("theme") || "light",
216-
false
217-
);
208+
// If there's a theme override that's not covered by one of the default
209+
// dark / light themes, we write it to the document head. We use
210+
// document.write rather than appendChild intentionally. Stylesheets added
211+
// with document.write are render-blocking, while those added with appendChild
212+
// are not. We want render blocking behavior to avoid a flash of unstyled
213+
// content.
214+
function applyThemeOverride() {
215+
var override = getThemeOverride();
216+
if (override) {
217+
document.write('<link rel="stylesheet" type="text/css" id="' + nonDefaultThemeID +
218+
'" href="' + themeURL(override) + '">');
219+
} else {
220+
document.write('<link rel="stylesheet" type="text/css" id="' + nonDefaultThemeID + '">');
221+
}
222+
}
223+
224+
updatePreferredDarkTheme();
225+
applyThemeOverride();
226+
if (window.matchMedia) {
227+
var mql = window.matchMedia("(prefers-color-scheme: dark)");
228+
mql.addEventListener('change', applyThemeUpdate);
218229
}

src/librustdoc/html/templates/page.html

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,14 @@
1212
<link rel="stylesheet" type="text/css" {# -#}
1313
href="{{static_root_path | safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
1414
id="mainThemeStyle"> {#- -#}
15-
{%- for theme in themes -%}
16-
<link rel="stylesheet" type="text/css" {# -#}
17-
href="{{static_root_path | safe}}{{theme}}{{page.resource_suffix}}.css" {#- -#}
18-
{%- if theme == "light" -%}
19-
id="themeStyle"
20-
{%- else -%}
21-
disabled
22-
{%- endif -%}
23-
>
24-
{%- endfor -%}
15+
<link rel="stylesheet" type="text/css" {# -#}
16+
href="{{static_root_path | safe}}light{{page.resource_suffix}}.css" {# -#}
17+
media="(prefers-color-scheme: light)" {# -#}
18+
id="lightThemeStyle"> {#- -#}
19+
<link rel="stylesheet" type="text/css" {# -#}
20+
href="{{static_root_path | safe}}dark{{page.resource_suffix}}.css" {# -#}
21+
media="(prefers-color-scheme: dark)" {# -#}
22+
id="darkThemeStyle"> {#- -#}
2523
<script id="default-settings" {# -#}
2624
{% for k, v in layout.default_settings %}
2725
data-{{k}}="{{v}}"

0 commit comments

Comments
 (0)