]>
git.proxmox.com Git - rustc.git/blob - src/librustdoc/html/static/js/settings.js
1 // Local js definitions:
2 /* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */
3 /* global addClass, removeClass, onEach, onEachLazy, blurHandler, elemIsInParent */
4 /* global MAIN_ID, getVar, getSettingsButton */
9 const isSettingsPage
= window
.location
.pathname
.endsWith("/settings.html");
11 function changeSetting(settingName
, value
) {
12 updateLocalStorage(settingName
, value
);
14 switch (settingName
) {
16 case "preferred-dark-theme":
17 case "preferred-light-theme":
18 case "use-system-theme":
25 function handleKey(ev
) {
26 // Don't interfere with browser shortcuts
27 if (ev
.ctrlKey
|| ev
.altKey
|| ev
.metaKey
) {
30 switch (getVirtualKey(ev
)) {
34 ev
.target
.checked
= !ev
.target
.checked
;
40 function showLightAndDark() {
41 addClass(document
.getElementById("theme").parentElement
, "hidden");
42 removeClass(document
.getElementById("preferred-light-theme").parentElement
, "hidden");
43 removeClass(document
.getElementById("preferred-dark-theme").parentElement
, "hidden");
46 function hideLightAndDark() {
47 addClass(document
.getElementById("preferred-light-theme").parentElement
, "hidden");
48 addClass(document
.getElementById("preferred-dark-theme").parentElement
, "hidden");
49 removeClass(document
.getElementById("theme").parentElement
, "hidden");
52 function updateLightAndDark() {
53 if (getSettingValue("use-system-theme") !== "false") {
60 function setEvents(settingsElement
) {
62 onEachLazy(settingsElement
.getElementsByClassName("slider"), elem
=> {
63 const toggle
= elem
.previousElementSibling
;
64 const settingId
= toggle
.id
;
65 const settingValue
= getSettingValue(settingId
);
66 if (settingValue
!== null) {
67 toggle
.checked
= settingValue
=== "true";
69 toggle
.onchange = function() {
70 changeSetting(this.id
, this.checked
);
72 toggle
.onkeyup
= handleKey
;
73 toggle
.onkeyrelease
= handleKey
;
75 onEachLazy(settingsElement
.getElementsByClassName("select-wrapper"), elem
=> {
76 const select
= elem
.getElementsByTagName("select")[0];
77 const settingId
= select
.id
;
78 const settingValue
= getSettingValue(settingId
);
79 if (settingValue
!== null) {
80 select
.value
= settingValue
;
82 select
.onchange = function() {
83 changeSetting(this.id
, this.value
);
86 onEachLazy(settingsElement
.querySelectorAll("input[type=\"radio\"]"), elem
=> {
87 const settingId
= elem
.name
;
88 const settingValue
= getSettingValue(settingId
);
89 if (settingValue
!== null && settingValue
!== "null") {
90 elem
.checked
= settingValue
=== elem
.value
;
92 elem
.addEventListener("change", ev
=> {
93 changeSetting(ev
.target
.name
, ev
.target
.value
);
99 * This function builds the sections inside the "settings page". It takes a `settings` list
100 * as argument which describes each setting and how to render it. It returns a string
101 * representing the raw HTML.
103 * @param {Array<Object>} settings
107 function buildSettingsPageSections(settings
) {
110 for (const setting
of settings
) {
111 output
+= "<div class=\"setting-line\">";
112 const js_data_name
= setting
["js_name"];
113 const setting_name
= setting
["name"];
115 if (setting
["options"] !== undefined) {
116 // This is a select setting.
117 output
+= `<div class="radio-line" id="${js_data_name}">\
118 <span class="setting-name">${setting_name}</span>\
119 <div class="choices">`;
120 onEach(setting
["options"], option
=> {
121 const checked
= option
=== setting
["default"] ? " checked" : "";
123 output
+= `<label for="${js_data_name}-${option}" class="choice">\
124 <input type="radio" name="${js_data_name}" \
125 id="${js_data_name}-${option}" value="${option}"${checked}>\
126 <span>${option}</span>\
129 output
+= "</div></div>";
132 const checked
= setting
["default"] === true ? " checked" : "";
133 output
+= `<label class="toggle">\
134 <input type="checkbox" id="${js_data_name}"${checked}>\
135 <span class="slider"></span>\
136 <span class="label">${setting_name}</span>\
145 * This function builds the "settings page" and returns the generated HTML element.
147 * @return {HTMLElement}
149 function buildSettingsPage() {
150 const themes
= getVar("themes").split(",");
153 "name": "Use system theme",
154 "js_name": "use-system-theme",
164 "name": "Preferred light theme",
165 "js_name": "preferred-light-theme",
170 "name": "Preferred dark theme",
171 "js_name": "preferred-dark-theme",
176 "name": "Auto-hide item contents for large items",
177 "js_name": "auto-hide-large-items",
181 "name": "Auto-hide item methods' documentation",
182 "js_name": "auto-hide-method-docs",
186 "name": "Auto-hide trait implementation documentation",
187 "js_name": "auto-hide-trait-implementations",
191 "name": "Directly go to item in search if there is only one result",
192 "js_name": "go-to-only-result",
196 "name": "Show line numbers on code examples",
197 "js_name": "line-numbers",
201 "name": "Disable keyboard shortcuts",
202 "js_name": "disable-shortcuts",
207 // Then we build the DOM.
208 const elementKind
= isSettingsPage
? "section" : "div";
209 const innerHTML
= `<div class="settings">${buildSettingsPageSections(settings)}</div>`;
210 const el
= document
.createElement(elementKind
);
212 el
.className
= "popover";
213 el
.innerHTML
= innerHTML
;
215 if (isSettingsPage
) {
216 document
.getElementById(MAIN_ID
).appendChild(el
);
218 el
.setAttribute("tabindex", "-1");
219 getSettingsButton().appendChild(el
);
224 const settingsMenu
= buildSettingsPage();
226 function displaySettings() {
227 settingsMenu
.style
.display
= "";
230 function settingsBlurHandler(event
) {
231 blurHandler(event
, getSettingsButton(), window
.hidePopoverMenus
);
234 if (isSettingsPage
) {
235 // We replace the existing "onclick" callback to do nothing if clicked.
236 getSettingsButton().onclick = function(event
) {
237 event
.preventDefault();
240 // We replace the existing "onclick" callback.
241 const settingsButton
= getSettingsButton();
242 const settingsMenu
= document
.getElementById("settings");
243 settingsButton
.onclick = function(event
) {
244 if (elemIsInParent(event
.target
, settingsMenu
)) {
247 event
.preventDefault();
248 const shouldDisplaySettings
= settingsMenu
.style
.display
=== "none";
250 window
.hidePopoverMenus();
251 if (shouldDisplaySettings
) {
255 settingsButton
.onblur
= settingsBlurHandler
;
256 settingsButton
.querySelector("a").onblur
= settingsBlurHandler
;
257 onEachLazy(settingsMenu
.querySelectorAll("input"), el
=> {
258 el
.onblur
= settingsBlurHandler
;
260 settingsMenu
.onblur
= settingsBlurHandler
;
263 // We now wait a bit for the web browser to end re-computing the DOM...
265 setEvents(settingsMenu
);
266 // The setting menu is already displayed if we're on the settings page.
267 if (!isSettingsPage
) {
270 removeClass(getSettingsButton(), "rotate");