]> git.proxmox.com Git - rustc.git/blob - src/librustdoc/html/static/js/storage.js
New upstream version 1.55.0+dfsg1
[rustc.git] / src / librustdoc / html / static / js / storage.js
1 // From rust:
2 /* global resourcesSuffix */
3 var darkThemes = ["dark", "ayu"];
4 window.currentTheme = document.getElementById("themeStyle");
5 window.mainTheme = document.getElementById("mainThemeStyle");
6
7 var settingsDataset = (function () {
8 var settingsElement = document.getElementById("default-settings");
9 if (settingsElement === null) {
10 return null;
11 }
12 var dataset = settingsElement.dataset;
13 if (dataset === undefined) {
14 return null;
15 }
16 return dataset;
17 })();
18
19 function getSettingValue(settingName) {
20 var current = getCurrentValue('rustdoc-' + settingName);
21 if (current !== null) {
22 return current;
23 }
24 if (settingsDataset !== null) {
25 // See the comment for `default_settings.into_iter()` etc. in
26 // `Options::from_matches` in `librustdoc/config.rs`.
27 var def = settingsDataset[settingName.replace(/-/g,'_')];
28 if (def !== undefined) {
29 return def;
30 }
31 }
32 return null;
33 }
34
35 var localStoredTheme = getSettingValue("theme");
36
37 var savedHref = [];
38
39 // eslint-disable-next-line no-unused-vars
40 function hasClass(elem, className) {
41 return elem && elem.classList && elem.classList.contains(className);
42 }
43
44 // eslint-disable-next-line no-unused-vars
45 function addClass(elem, className) {
46 if (!elem || !elem.classList) {
47 return;
48 }
49 elem.classList.add(className);
50 }
51
52 // eslint-disable-next-line no-unused-vars
53 function removeClass(elem, className) {
54 if (!elem || !elem.classList) {
55 return;
56 }
57 elem.classList.remove(className);
58 }
59
60 function onEach(arr, func, reversed) {
61 if (arr && arr.length > 0 && func) {
62 var length = arr.length;
63 var i;
64 if (reversed) {
65 for (i = length - 1; i >= 0; --i) {
66 if (func(arr[i])) {
67 return true;
68 }
69 }
70 } else {
71 for (i = 0; i < length; ++i) {
72 if (func(arr[i])) {
73 return true;
74 }
75 }
76 }
77 }
78 return false;
79 }
80
81 function onEachLazy(lazyArray, func, reversed) {
82 return onEach(
83 Array.prototype.slice.call(lazyArray),
84 func,
85 reversed);
86 }
87
88 // eslint-disable-next-line no-unused-vars
89 function hasOwnPropertyRustdoc(obj, property) {
90 return Object.prototype.hasOwnProperty.call(obj, property);
91 }
92
93 function updateLocalStorage(name, value) {
94 try {
95 window.localStorage.setItem(name, value);
96 } catch(e) {
97 // localStorage is not accessible, do nothing
98 }
99 }
100
101 function getCurrentValue(name) {
102 try {
103 return window.localStorage.getItem(name);
104 } catch(e) {
105 return null;
106 }
107 }
108
109 function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
110 var fullBasicCss = "rustdoc" + resourcesSuffix + ".css";
111 var fullNewTheme = newTheme + resourcesSuffix + ".css";
112 var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme);
113
114 // If this new value comes from a system setting or from the previously
115 // saved theme, no need to save it.
116 if (saveTheme) {
117 updateLocalStorage("rustdoc-theme", newTheme);
118 }
119
120 if (styleElem.href === newHref) {
121 return;
122 }
123
124 var found = false;
125 if (savedHref.length === 0) {
126 onEachLazy(document.getElementsByTagName("link"), function(el) {
127 savedHref.push(el.href);
128 });
129 }
130 onEach(savedHref, function(el) {
131 if (el === newHref) {
132 found = true;
133 return true;
134 }
135 });
136 if (found) {
137 styleElem.href = newHref;
138 }
139 }
140
141 // This function is called from "main.js".
142 // eslint-disable-next-line no-unused-vars
143 function useSystemTheme(value) {
144 if (value === undefined) {
145 value = true;
146 }
147
148 updateLocalStorage("rustdoc-use-system-theme", value);
149
150 // update the toggle if we're on the settings page
151 var toggle = document.getElementById("use-system-theme");
152 if (toggle && toggle instanceof HTMLInputElement) {
153 toggle.checked = value;
154 }
155 }
156
157 var updateSystemTheme = (function() {
158 if (!window.matchMedia) {
159 // fallback to the CSS computed value
160 return function() {
161 var cssTheme = getComputedStyle(document.documentElement)
162 .getPropertyValue('content');
163
164 switchTheme(
165 window.currentTheme,
166 window.mainTheme,
167 JSON.parse(cssTheme) || "light",
168 true
169 );
170 };
171 }
172
173 // only listen to (prefers-color-scheme: dark) because light is the default
174 var mql = window.matchMedia("(prefers-color-scheme: dark)");
175
176 function handlePreferenceChange(mql) {
177 // maybe the user has disabled the setting in the meantime!
178 if (getSettingValue("use-system-theme") !== "false") {
179 var lightTheme = getSettingValue("preferred-light-theme") || "light";
180 var darkTheme = getSettingValue("preferred-dark-theme") || "dark";
181
182 if (mql.matches) {
183 // prefers a dark theme
184 switchTheme(window.currentTheme, window.mainTheme, darkTheme, true);
185 } else {
186 // prefers a light theme, or has no preference
187 switchTheme(window.currentTheme, window.mainTheme, lightTheme, true);
188 }
189
190 // note: we save the theme so that it doesn't suddenly change when
191 // the user disables "use-system-theme" and reloads the page or
192 // navigates to another page
193 }
194 }
195
196 mql.addListener(handlePreferenceChange);
197
198 return function() {
199 handlePreferenceChange(mql);
200 };
201 })();
202
203 if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
204 // update the preferred dark theme if the user is already using a dark theme
205 // See https://github.com/rust-lang/rust/pull/77809#issuecomment-707875732
206 if (getSettingValue("use-system-theme") === null
207 && getSettingValue("preferred-dark-theme") === null
208 && darkThemes.indexOf(localStoredTheme) >= 0) {
209 updateLocalStorage("rustdoc-preferred-dark-theme", localStoredTheme);
210 }
211
212 // call the function to initialize the theme at least once!
213 updateSystemTheme();
214 } else {
215 switchTheme(
216 window.currentTheme,
217 window.mainTheme,
218 getSettingValue("theme") || "light",
219 false
220 );
221 }