mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
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.
This commit is contained in:
commit
cbf74bc4ca
@ -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\">\
|
||||
|
@ -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();
|
||||
}}
|
||||
|
@ -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,9 +414,59 @@ 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 {
|
||||
|
Loading…
Reference in New Issue
Block a user