]>
git.proxmox.com Git - rustc.git/blob - src/librustdoc/html/static/js/settings.js
1 // Local js definitions:
2 /* global getSettingValue, updateLocalStorage, updateTheme */
3 /* global addClass, removeClass, onEach, onEachLazy, blurHandler */
4 /* global MAIN_ID, getVar, getSettingsButton */
9 const isSettingsPage
= window
.location
.pathname
.endsWith("/settings.html");
11 function changeSetting(settingName
, value
) {
12 if (settingName
=== "theme") {
13 const useSystem
= value
=== "system preference" ? "true" : "false";
14 updateLocalStorage("use-system-theme", useSystem
);
16 updateLocalStorage(settingName
, value
);
18 switch (settingName
) {
20 case "preferred-dark-theme":
21 case "preferred-light-theme":
27 window
.rustdoc_add_line_numbers_to_examples();
29 window
.rustdoc_remove_line_numbers_from_examples();
34 addClass(document
.documentElement
, "hide-sidebar");
36 removeClass(document
.documentElement
, "hide-sidebar");
42 function showLightAndDark() {
43 removeClass(document
.getElementById("preferred-light-theme"), "hidden");
44 removeClass(document
.getElementById("preferred-dark-theme"), "hidden");
47 function hideLightAndDark() {
48 addClass(document
.getElementById("preferred-light-theme"), "hidden");
49 addClass(document
.getElementById("preferred-dark-theme"), "hidden");
52 function updateLightAndDark() {
53 const useSystem
= getSettingValue("use-system-theme");
54 if (useSystem
=== "true" || (useSystem
=== null && getSettingValue("theme") === null)) {
61 function setEvents(settingsElement
) {
63 onEachLazy(settingsElement
.querySelectorAll("input[type=\"checkbox\"]"), toggle
=> {
64 const settingId
= toggle
.id
;
65 const settingValue
= getSettingValue(settingId
);
66 if (settingValue
!== null) {
67 toggle
.checked
= settingValue
=== "true";
69 toggle
.onchange
= () => {
70 changeSetting(toggle
.id
, toggle
.checked
);
73 onEachLazy(settingsElement
.querySelectorAll("input[type=\"radio\"]"), elem
=> {
74 const settingId
= elem
.name
;
75 let settingValue
= getSettingValue(settingId
);
76 if (settingId
=== "theme") {
77 const useSystem
= getSettingValue("use-system-theme");
78 if (useSystem
=== "true" || settingValue
=== null) {
79 // "light" is the default theme
80 settingValue
= useSystem
=== "false" ? "light" : "system preference";
83 if (settingValue
!== null && settingValue
!== "null") {
84 elem
.checked
= settingValue
=== elem
.value
;
86 elem
.addEventListener("change", ev
=> {
87 changeSetting(ev
.target
.name
, ev
.target
.value
);
93 * This function builds the sections inside the "settings page". It takes a `settings` list
94 * as argument which describes each setting and how to render it. It returns a string
95 * representing the raw HTML.
97 * @param {Array<Object>} settings
101 function buildSettingsPageSections(settings
) {
104 for (const setting
of settings
) {
105 const js_data_name
= setting
["js_name"];
106 const setting_name
= setting
["name"];
108 if (setting
["options"] !== undefined) {
109 // This is a select setting.
111 <div class="setting-line" id="${js_data_name}">
112 <div class="setting-radio-name">${setting_name}</div>
113 <div class="setting-radio-choices">`;
114 onEach(setting
["options"], option
=> {
115 const checked
= option
=== setting
["default"] ? " checked" : "";
116 const full
= `${js_data_name}-${option.replace(/ /g,"-")}`;
119 <label for="${full}" class="setting-radio">
120 <input type="radio" name="${js_data_name}"
121 id="${full}" value="${option}"${checked}>
122 <span>${option}</span>
129 // This is a checkbox toggle.
130 const checked
= setting
["default"] === true ? " checked" : "";
132 <div class="setting-line">\
133 <label class="setting-check">\
134 <input type="checkbox" id="${js_data_name}"${checked}>\
135 <span>${setting_name}</span>\
144 * This function builds the "settings page" and returns the generated HTML element.
146 * @return {HTMLElement}
148 function buildSettingsPage() {
149 const theme_names
= getVar("themes").split(",").filter(t
=> t
);
150 theme_names
.push("light", "dark", "ayu");
156 "default": "system preference",
157 "options": theme_names
.concat("system preference"),
160 "name": "Preferred light theme",
161 "js_name": "preferred-light-theme",
163 "options": theme_names
,
166 "name": "Preferred dark theme",
167 "js_name": "preferred-dark-theme",
169 "options": theme_names
,
172 "name": "Auto-hide item contents for large items",
173 "js_name": "auto-hide-large-items",
177 "name": "Auto-hide item methods' documentation",
178 "js_name": "auto-hide-method-docs",
182 "name": "Auto-hide trait implementation documentation",
183 "js_name": "auto-hide-trait-implementations",
187 "name": "Directly go to item in search if there is only one result",
188 "js_name": "go-to-only-result",
192 "name": "Show line numbers on code examples",
193 "js_name": "line-numbers",
197 "name": "Hide persistent navigation bar",
198 "js_name": "hide-sidebar",
202 "name": "Disable keyboard shortcuts",
203 "js_name": "disable-shortcuts",
208 // Then we build the DOM.
209 const elementKind
= isSettingsPage
? "section" : "div";
210 const innerHTML
= `<div class="settings">${buildSettingsPageSections(settings)}</div>`;
211 const el
= document
.createElement(elementKind
);
213 if (!isSettingsPage
) {
214 el
.className
= "popover";
216 el
.innerHTML
= innerHTML
;
218 if (isSettingsPage
) {
219 document
.getElementById(MAIN_ID
).appendChild(el
);
221 el
.setAttribute("tabindex", "-1");
222 getSettingsButton().appendChild(el
);
227 const settingsMenu
= buildSettingsPage();
229 function displaySettings() {
230 settingsMenu
.style
.display
= "";
231 onEachLazy(settingsMenu
.querySelectorAll("input[type='checkbox']"), el
=> {
232 const val
= getSettingValue(el
.id
);
233 const checked
= val
=== "true";
234 if (checked
!== el
.checked
&& val
!== null) {
235 el
.checked
= checked
;
240 function settingsBlurHandler(event
) {
241 blurHandler(event
, getSettingsButton(), window
.hidePopoverMenus
);
244 if (isSettingsPage
) {
245 // We replace the existing "onclick" callback to do nothing if clicked.
246 getSettingsButton().onclick
= event
=> {
247 event
.preventDefault();
250 // We replace the existing "onclick" callback.
251 const settingsButton
= getSettingsButton();
252 const settingsMenu
= document
.getElementById("settings");
253 settingsButton
.onclick
= event
=> {
254 if (settingsMenu
.contains(event
.target
)) {
257 event
.preventDefault();
258 const shouldDisplaySettings
= settingsMenu
.style
.display
=== "none";
260 window
.hideAllModals();
261 if (shouldDisplaySettings
) {
265 settingsButton
.onblur
= settingsBlurHandler
;
266 settingsButton
.querySelector("a").onblur
= settingsBlurHandler
;
267 onEachLazy(settingsMenu
.querySelectorAll("input"), el
=> {
268 el
.onblur
= settingsBlurHandler
;
270 settingsMenu
.onblur
= settingsBlurHandler
;
273 // We now wait a bit for the web browser to end re-computing the DOM...
275 setEvents(settingsMenu
);
276 // The setting menu is already displayed if we're on the settings page.
277 if (!isSettingsPage
) {
280 removeClass(getSettingsButton(), "rotate");