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