From 17b8ca952baf5d32ef6e9653b0eda6516386400c Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 30 Oct 2020 14:27:00 -0700 Subject: [PATCH] Pull theme picker keyboard code into main.js Most of the code in mod.rs should be code that really needs to have the list of available themes inlined into it. --- src/librustdoc/html/render/mod.rs | 50 ------------------------- src/librustdoc/html/static/main.js | 60 +++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 51 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index bbcf3ce97e1..5ac0ffcfbf1 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -807,58 +807,8 @@ function handleThemeButtonsBlur(e) {{ }} }} -function handleThemeKeyDown(e) {{ - if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {{ return; }} - if (!themePicker.parentNode.contains(e.target)) {{ return; }} - var active = document.activeElement; - switch (e.key) {{ - case "ArrowUp": - e.preventDefault(); - if (active.previousElementSibling && e.target.id !== "theme-picker") {{ - active.previousElementSibling.focus(); - }} else {{ - showThemeButtonState(); - themes.lastElementChild.focus(); - }} - break; - case "ArrowDown": - e.preventDefault(); - if (active.nextElementSibling && e.target.id !== "theme-picker") {{ - active.nextElementSibling.focus(); - }} else {{ - showThemeButtonState(); - themes.firstElementChild.focus(); - }} - break; - case "Enter": - case "Return": - case "Space": - if (e.target.id === "theme-picker" && themes.style.display === "none") {{ - e.preventDefault(); - showThemeButtonState(); - themes.firstElementChild.focus(); - }} - break; - case "Home": - e.preventDefault(); - themes.firstElementChild.focus(); - break; - case "End": - e.preventDefault(); - themes.lastElementChild.focus(); - break; - // The escape key is handled in main.js, instead of here, for two reasons: - // - // 1 Escape should close the menu, even if it's not focused. - // 2 The escape event handler is bound to both keydown and keypress, to work - // around browser inconsistencies. That sort of logic doesn't apply to the - // rest of these keybindings. - }} -}}; - themePicker.onclick = switchThemeButtonState; themePicker.onblur = handleThemeButtonsBlur; -document.addEventListener("keydown", handleThemeKeyDown); {}.forEach(function(item) {{ var but = document.createElement("button"); but.textContent = item; diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 69873524bd7..de4792a5bd2 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -4,7 +4,7 @@ // Local js definitions: /* global addClass, getCurrentValue, hasClass */ /* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ -/* global hideThemeButtonState */ +/* global hideThemeButtonState, showThemeButtonState */ if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { @@ -48,6 +48,14 @@ function getSearchElement() { return document.getElementById("search"); } +function getThemesElement() { + return document.getElementById("theme-choices"); +} + +function getThemePickerElement() { + return document.getElementById("theme-picker"); +} + // Sets the focus on the search bar at the top of the page function focusSearchBar() { getSearchInput().focus(); @@ -406,10 +414,60 @@ function defocusSearchBar() { case "?": displayHelp(true, ev); break; + + default: + var themePicker = getThemePickerElement(); + if (themePicker.parentNode.contains(ev.target)) { + handleThemeKeyDown(ev); + } } } } + function handleThemeKeyDown(ev) { + var active = document.activeElement; + var themes = getThemesElement(); + switch (getVirtualKey(ev)) { + case "ArrowUp": + ev.preventDefault(); + if (active.previousElementSibling && ev.target.id !== "theme-picker") { + active.previousElementSibling.focus(); + } else { + showThemeButtonState(); + themes.lastElementChild.focus(); + } + break; + case "ArrowDown": + ev.preventDefault(); + if (active.nextElementSibling && ev.target.id !== "theme-picker") { + active.nextElementSibling.focus(); + } else { + showThemeButtonState(); + themes.firstElementChild.focus(); + } + break; + case "Enter": + case "Return": + case "Space": + if (ev.target.id === "theme-picker" && themes.style.display === "none") { + ev.preventDefault(); + showThemeButtonState(); + themes.firstElementChild.focus(); + } + break; + case "Home": + ev.preventDefault(); + themes.firstElementChild.focus(); + break; + case "End": + ev.preventDefault(); + themes.lastElementChild.focus(); + break; + // The escape key is handled in handleEscape, not here, + // so that pressing escape will close the menu even if it isn't focused + } + } + function findParentElement(elem, tagName) { do { if (elem && elem.tagName === tagName) {