diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index b089bcb0862a5..db73af7ec1689 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -79,12 +79,12 @@ pub fn render( {sidebar}\ \ \ - \ + \ \ \ - \ + \ \ \ \ diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 0621eafd91347..5ac0ffcfbf1c2 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 28bd1ba5247d6..de4792a5bd2f7 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 } }