diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2020-11-05 10:29:45 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-05 10:29:45 +0100 |
| commit | cbf74bc4ca3f9a3b17af672930c56fa25861b21e (patch) | |
| tree | bbbd85ea7b60b7559e4c17bbb92bd6a909c9eb18 | |
| parent | 6d7098f543f51611eab620b6d2e6f9d4167fc96e (diff) | |
| parent | 17b8ca952baf5d32ef6e9653b0eda6516386400c (diff) | |
| download | rust-cbf74bc4ca3f9a3b17af672930c56fa25861b21e.tar.gz rust-cbf74bc4ca3f9a3b17af672930c56fa25861b21e.zip | |
Rollup merge of #78584 - notriddle:master, r=GuillaumeGomez
Add keyboard handling to the theme picker menu This PR is mostly designed to bring the theme picker closer to feature parity with the menu bar from docs.rs. Though the rustdoc theme picker is technically already usable from the keyboard, it's really weird that arrow keys work on some of the menus, but not all of them, in the exact same page.
| -rw-r--r-- | src/librustdoc/html/layout.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/static/main.js | 68 |
3 files changed, 64 insertions, 12 deletions
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index b089bcb0862..db73af7ec16 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -79,12 +79,12 @@ pub fn render<T: Print, S: Print>( {sidebar}\ </nav>\ <div class=\"theme-picker\">\ - <button id=\"theme-picker\" aria-label=\"Pick another theme!\">\ + <button id=\"theme-picker\" aria-label=\"Pick another theme!\" aria-haspopup=\"menu\">\ <img src=\"{static_root_path}brush{suffix}.svg\" \ width=\"18\" \ alt=\"Pick another theme!\">\ </button>\ - <div id=\"theme-choices\"></div>\ + <div id=\"theme-choices\" role=\"menu\"></div>\ </div>\ <script src=\"{static_root_path}theme{suffix}.js\"></script>\ <nav class=\"sub\">\ diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 0621eafd913..5ac0ffcfbf1 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -798,10 +798,10 @@ function handleThemeButtonsBlur(e) {{ var active = document.activeElement; var related = e.relatedTarget; - if (active.id !== "themePicker" && + if (active.id !== "theme-picker" && (!active.parentNode || active.parentNode.id !== "theme-choices") && (!related || - (related.id !== "themePicker" && + (related.id !== "theme-picker" && (!related.parentNode || related.parentNode.id !== "theme-choices")))) {{ hideThemeButtonState(); }} diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 28bd1ba5247..de4792a5bd2 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -4,6 +4,7 @@ // Local js definitions: /* global addClass, getCurrentValue, hasClass */ /* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ +/* global hideThemeButtonState, showThemeButtonState */ if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { @@ -47,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(); @@ -137,10 +146,6 @@ function defocusSearchBar() { sidebar.appendChild(div); } } - var themePickers = document.getElementsByClassName("theme-picker"); - if (themePickers && themePickers.length > 0) { - themePickers[0].style.display = "none"; - } } function hideSidebar() { @@ -155,10 +160,6 @@ function defocusSearchBar() { filler.remove(); } document.getElementsByTagName("body")[0].style.marginTop = ""; - var themePickers = document.getElementsByClassName("theme-picker"); - if (themePickers && themePickers.length > 0) { - themePickers[0].style.display = null; - } } function showSearchResults(search) { @@ -376,6 +377,7 @@ function defocusSearchBar() { document.title = titleBeforeSearch; } defocusSearchBar(); + hideThemeButtonState(); } function handleShortcut(ev) { @@ -412,7 +414,57 @@ 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 } } |
