]>
git.proxmox.com Git - rustc.git/blob - src/librustdoc/html/static/js/storage.js
21de7d77d64e7f60a3b449051e1758539d64e337
3 const darkThemes
= ["dark", "ayu"];
4 window
.currentTheme
= document
.getElementById("themeStyle");
5 window
.mainTheme
= document
.getElementById("mainThemeStyle");
7 const settingsDataset
= (function () {
8 const settingsElement
= document
.getElementById("default-settings");
9 if (settingsElement
=== null) {
12 const dataset
= settingsElement
.dataset
;
13 if (dataset
=== undefined) {
19 function getSettingValue(settingName
) {
20 const current
= getCurrentValue(settingName
);
21 if (current
!== null) {
24 if (settingsDataset
!== null) {
25 // See the comment for `default_settings.into_iter()` etc. in
26 // `Options::from_matches` in `librustdoc/config.rs`.
27 const def
= settingsDataset
[settingName
.replace(/-/g
,"_")];
28 if (def
!== undefined) {
35 const localStoredTheme
= getSettingValue("theme");
39 // eslint-disable-next-line no-unused-vars
40 function hasClass(elem
, className
) {
41 return elem
&& elem
.classList
&& elem
.classList
.contains(className
);
44 // eslint-disable-next-line no-unused-vars
45 function addClass(elem
, className
) {
46 if (!elem
|| !elem
.classList
) {
49 elem
.classList
.add(className
);
52 // eslint-disable-next-line no-unused-vars
53 function removeClass(elem
, className
) {
54 if (!elem
|| !elem
.classList
) {
57 elem
.classList
.remove(className
);
61 * Run a callback for every element of an Array.
62 * @param {Array<?>} arr - The array to iterate over
63 * @param {function(?)} func - The callback
64 * @param {boolean} [reversed] - Whether to iterate in reverse
66 function onEach(arr
, func
, reversed
) {
67 if (arr
&& arr
.length
> 0 && func
) {
69 const length
= arr
.length
;
70 for (let i
= length
- 1; i
>= 0; --i
) {
76 for (const elem
of arr
) {
87 * Turn an HTMLCollection or a NodeList into an Array, then run a callback
88 * for every element. This is useful because iterating over an HTMLCollection
89 * or a "live" NodeList while modifying it can be very slow.
90 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
91 * https://developer.mozilla.org/en-US/docs/Web/API/NodeList
92 * @param {NodeList<?>|HTMLCollection<?>} lazyArray - An array to iterate over
93 * @param {function(?)} func - The callback
94 * @param {boolean} [reversed] - Whether to iterate in reverse
96 function onEachLazy(lazyArray
, func
, reversed
) {
98 Array
.prototype.slice
.call(lazyArray
),
103 // eslint-disable-next-line no-unused-vars
104 function hasOwnPropertyRustdoc(obj
, property
) {
105 return Object
.prototype.hasOwnProperty
.call(obj
, property
);
108 function updateLocalStorage(name
, value
) {
110 window
.localStorage
.setItem("rustdoc-" + name
, value
);
112 // localStorage is not accessible, do nothing
116 function getCurrentValue(name
) {
118 return window
.localStorage
.getItem("rustdoc-" + name
);
124 function switchTheme(styleElem
, mainStyleElem
, newTheme
, saveTheme
) {
125 const newHref
= mainStyleElem
.href
.replace(
126 /\/rustdoc([^/]*)\.css
/, "/" + newTheme + "$1" + ".css
");
128 // If this new value comes from a system setting or from the previously
129 // saved theme, no need to save it.
131 updateLocalStorage("theme
", newTheme);
134 if (styleElem.href === newHref) {
139 if (savedHref.length === 0) {
140 onEachLazy(document.getElementsByTagName("link
"), el => {
141 savedHref.push(el.href);
144 onEach(savedHref, el => {
145 if (el === newHref) {
151 styleElem.href = newHref;
155 // This function is called from "main
.js
".
156 // eslint-disable-next-line no-unused-vars
157 function useSystemTheme(value) {
158 if (value === undefined) {
162 updateLocalStorage("use-system
-theme
", value);
164 // update the toggle if we're on the settings page
165 const toggle = document.getElementById("use-system
-theme
");
166 if (toggle && toggle instanceof HTMLInputElement) {
167 toggle.checked = value;
171 const updateSystemTheme = (function () {
172 if (!window.matchMedia) {
173 // fallback to the CSS computed value
175 const cssTheme = getComputedStyle(document.documentElement)
176 .getPropertyValue("content
");
181 JSON.parse(cssTheme) || "light
",
187 // only listen to (prefers-color-scheme: dark) because light is the default
188 const mql = window.matchMedia("(prefers
-color
-scheme
: dark
)");
190 function handlePreferenceChange(mql) {
191 const use = theme => {
192 switchTheme(window.currentTheme, window.mainTheme, theme, true);
194 // maybe the user has disabled the setting in the meantime!
195 if (getSettingValue("use-system
-theme
") !== "false") {
196 const lightTheme = getSettingValue("preferred
-light
-theme
") || "light
";
197 const darkTheme = getSettingValue("preferred
-dark
-theme
") || "dark
";
202 // prefers a light theme, or has no preference
205 // note: we save the theme so that it doesn't suddenly change when
206 // the user disables "use-system
-theme
" and reloads the page or
207 // navigates to another page
209 use(getSettingValue("theme
"));
213 mql.addListener(handlePreferenceChange);
216 handlePreferenceChange(mql);
220 function switchToSavedTheme() {
224 getSettingValue("theme
") || "light
",
229 if (getSettingValue("use-system
-theme
") !== "false" && window.matchMedia) {
230 // update the preferred dark theme if the user is already using a dark theme
231 // See https://github.com/rust-lang/rust/pull/77809#issuecomment-707875732
232 if (getSettingValue("use-system
-theme
") === null
233 && getSettingValue("preferred
-dark
-theme
") === null
234 && darkThemes.indexOf(localStoredTheme) >= 0) {
235 updateLocalStorage("preferred
-dark
-theme
", localStoredTheme);
238 // call the function to initialize the theme at least once!
241 switchToSavedTheme();
244 // If we navigate away (for example to a settings page), and then use the back or
245 // forward button to get back to a page, the theme may have changed in the meantime.
246 // But scripts may not be re-loaded in such a case due to the bfcache
247 // (https://web.dev/bfcache/). The "pageshow
" event triggers on such navigations.
248 // Use that opportunity to update the theme.
249 // We use a setTimeout with a 0 timeout here to put the change on the event queue.
250 // For some reason, if we try to change the theme while the `pageshow` event is
251 // running, it sometimes fails to take effect. The problem manifests on Chrome,
252 // specifically when talking to a remote website with no caching.
253 window.addEventListener("pageshow
", ev => {
255 setTimeout(switchToSavedTheme, 0);