|
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