|
1 | 1 | // Local js definitions:
|
2 | 2 | /* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */
|
3 |
| -/* global addClass, removeClass, onEach, onEachLazy, NOT_DISPLAYED_ID */ |
4 |
| -/* global MAIN_ID, getVar, getSettingsButton, switchDisplayedElement, getNotDisplayedElem */ |
| 3 | +/* global addClass, removeClass, onEach, onEachLazy */ |
| 4 | +/* global MAIN_ID, getVar, getSettingsButton */ |
5 | 5 |
|
6 | 6 | "use strict";
|
7 | 7 |
|
|
206 | 206 | ];
|
207 | 207 |
|
208 | 208 | // Then we build the DOM.
|
209 |
| - const el = document.createElement("section"); |
210 |
| - el.id = "settings"; |
211 |
| - let innerHTML = ` |
212 |
| - <div class="main-heading"> |
| 209 | + let innerHTML = ""; |
| 210 | + let elementKind = "div"; |
| 211 | + |
| 212 | + if (isSettingsPage) { |
| 213 | + elementKind = "section"; |
| 214 | + innerHTML = `<div class="main-heading"> |
213 | 215 | <h1 class="fqn">
|
214 | 216 | <span class="in-band">Rustdoc settings</span>
|
215 | 217 | </h1>
|
216 |
| - <span class="out-of-band">`; |
217 |
| - |
218 |
| - if (isSettingsPage) { |
219 |
| - innerHTML += |
220 |
| - "<a id=\"back\" href=\"javascript:void(0)\" onclick=\"history.back();\">Back</a>"; |
221 |
| - } else { |
222 |
| - innerHTML += "<a id=\"back\" href=\"javascript:void(0)\" " + |
223 |
| - "onclick=\"switchDisplayedElement(null);\">Back</a>"; |
| 218 | + <span class="out-of-band"> |
| 219 | + <a id="back" href="javascript:void(0)" onclick="history.back();">Back</a> |
| 220 | + </span> |
| 221 | + </div>`; |
224 | 222 | }
|
225 |
| - innerHTML += `</span> |
226 |
| - </div> |
227 |
| - <div class="settings">${buildSettingsPageSections(settings)}</div>`; |
| 223 | + innerHTML += `<div class="settings">${buildSettingsPageSections(settings)}</div>`; |
228 | 224 |
|
| 225 | + const el = document.createElement(elementKind); |
| 226 | + el.id = "settings"; |
229 | 227 | el.innerHTML = innerHTML;
|
230 | 228 |
|
231 | 229 | if (isSettingsPage) {
|
232 | 230 | document.getElementById(MAIN_ID).appendChild(el);
|
233 | 231 | } else {
|
234 |
| - getNotDisplayedElem().appendChild(el); |
| 232 | + el.setAttribute("tabindex", "-1"); |
| 233 | + getSettingsButton().appendChild(el); |
235 | 234 | }
|
236 | 235 | return el;
|
237 | 236 | }
|
238 | 237 |
|
239 | 238 | const settingsMenu = buildSettingsPage();
|
240 | 239 |
|
| 240 | + function displaySettings() { |
| 241 | + settingsMenu.style.display = ""; |
| 242 | + } |
| 243 | + |
| 244 | + function elemIsInParent(elem, parent) { |
| 245 | + while (elem && elem !== document.body) { |
| 246 | + if (elem === parent) { |
| 247 | + return true; |
| 248 | + } |
| 249 | + elem = elem.parentElement; |
| 250 | + } |
| 251 | + return false; |
| 252 | + } |
| 253 | + |
| 254 | + function blurHandler(event) { |
| 255 | + const settingsButton = getSettingsButton(); |
| 256 | + if (!elemIsInParent(document.activeElement, settingsButton) && |
| 257 | + !elemIsInParent(event.relatedTarget, settingsButton)) |
| 258 | + { |
| 259 | + window.hideSettings(); |
| 260 | + } |
| 261 | + } |
| 262 | + |
241 | 263 | if (isSettingsPage) {
|
242 | 264 | // We replace the existing "onclick" callback to do nothing if clicked.
|
243 | 265 | getSettingsButton().onclick = function(event) {
|
|
246 | 268 | } else {
|
247 | 269 | // We replace the existing "onclick" callback.
|
248 | 270 | const settingsButton = getSettingsButton();
|
| 271 | + const settingsMenu = document.getElementById("settings"); |
| 272 | + window.hideSettings = function() { |
| 273 | + settingsMenu.style.display = "none"; |
| 274 | + }; |
249 | 275 | settingsButton.onclick = function(event) {
|
| 276 | + if (elemIsInParent(event.target, settingsMenu)) { |
| 277 | + return; |
| 278 | + } |
250 | 279 | event.preventDefault();
|
251 |
| - if (settingsMenu.parentElement.id === NOT_DISPLAYED_ID) { |
252 |
| - switchDisplayedElement(settingsMenu); |
253 |
| - } else { |
| 280 | + if (settingsMenu.style.display !== "none") { |
254 | 281 | window.hideSettings();
|
| 282 | + } else { |
| 283 | + displaySettings(); |
255 | 284 | }
|
256 | 285 | };
|
257 |
| - window.hideSettings = function() { |
258 |
| - switchDisplayedElement(null); |
259 |
| - }; |
| 286 | + settingsButton.onblur = blurHandler; |
| 287 | + settingsButton.querySelector("a").onblur = blurHandler; |
| 288 | + onEachLazy(settingsMenu.querySelectorAll("input"), el => { |
| 289 | + el.onblur = blurHandler; |
| 290 | + }); |
| 291 | + settingsMenu.onblur = blurHandler; |
260 | 292 | }
|
261 | 293 |
|
262 | 294 | // We now wait a bit for the web browser to end re-computing the DOM...
|
263 | 295 | setTimeout(() => {
|
264 | 296 | setEvents(settingsMenu);
|
265 | 297 | // The setting menu is already displayed if we're on the settings page.
|
266 | 298 | if (!isSettingsPage) {
|
267 |
| - switchDisplayedElement(settingsMenu); |
| 299 | + displaySettings(); |
268 | 300 | }
|
269 | 301 | removeClass(getSettingsButton(), "rotate");
|
270 | 302 | }, 0);
|
|
0 commit comments