| 
4 | 4 | // Local js definitions:  | 
5 | 5 | /* global addClass, getCurrentValue, hasClass */  | 
6 | 6 | /* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */  | 
7 |  | -/* global hideThemeButtonState */  | 
 | 7 | +/* global hideThemeButtonState, showThemeButtonState */  | 
8 | 8 | 
 
  | 
9 | 9 | if (!String.prototype.startsWith) {  | 
10 | 10 |     String.prototype.startsWith = function(searchString, position) {  | 
@@ -48,6 +48,14 @@ function getSearchElement() {  | 
48 | 48 |     return document.getElementById("search");  | 
49 | 49 | }  | 
50 | 50 | 
 
  | 
 | 51 | +function getThemesElement() {  | 
 | 52 | +    return document.getElementById("theme-choices");  | 
 | 53 | +}  | 
 | 54 | + | 
 | 55 | +function getThemePickerElement() {  | 
 | 56 | +    return document.getElementById("theme-picker");  | 
 | 57 | +}  | 
 | 58 | + | 
51 | 59 | // Sets the focus on the search bar at the top of the page  | 
52 | 60 | function focusSearchBar() {  | 
53 | 61 |     getSearchInput().focus();  | 
@@ -406,7 +414,57 @@ function defocusSearchBar() {  | 
406 | 414 |             case "?":  | 
407 | 415 |                 displayHelp(true, ev);  | 
408 | 416 |                 break;  | 
 | 417 | + | 
 | 418 | +            default:  | 
 | 419 | +                var themePicker = getThemePickerElement();  | 
 | 420 | +                if (themePicker.parentNode.contains(ev.target)) {  | 
 | 421 | +                    handleThemeKeyDown(ev);  | 
 | 422 | +                }  | 
 | 423 | +            }  | 
 | 424 | +        }  | 
 | 425 | +    }  | 
 | 426 | + | 
 | 427 | +    function handleThemeKeyDown(ev) {  | 
 | 428 | +        var active = document.activeElement;  | 
 | 429 | +        var themes = getThemesElement();  | 
 | 430 | +        switch (getVirtualKey(ev)) {  | 
 | 431 | +        case "ArrowUp":  | 
 | 432 | +            ev.preventDefault();  | 
 | 433 | +            if (active.previousElementSibling && ev.target.id !== "theme-picker") {  | 
 | 434 | +                active.previousElementSibling.focus();  | 
 | 435 | +            } else {  | 
 | 436 | +                showThemeButtonState();  | 
 | 437 | +                themes.lastElementChild.focus();  | 
409 | 438 |             }  | 
 | 439 | +            break;  | 
 | 440 | +        case "ArrowDown":  | 
 | 441 | +            ev.preventDefault();  | 
 | 442 | +            if (active.nextElementSibling && ev.target.id !== "theme-picker") {  | 
 | 443 | +                active.nextElementSibling.focus();  | 
 | 444 | +            } else {  | 
 | 445 | +                showThemeButtonState();  | 
 | 446 | +                themes.firstElementChild.focus();  | 
 | 447 | +            }  | 
 | 448 | +            break;  | 
 | 449 | +        case "Enter":  | 
 | 450 | +        case "Return":  | 
 | 451 | +        case "Space":  | 
 | 452 | +            if (ev.target.id === "theme-picker" && themes.style.display === "none") {  | 
 | 453 | +                ev.preventDefault();  | 
 | 454 | +                showThemeButtonState();  | 
 | 455 | +                themes.firstElementChild.focus();  | 
 | 456 | +            }  | 
 | 457 | +            break;  | 
 | 458 | +        case "Home":  | 
 | 459 | +            ev.preventDefault();  | 
 | 460 | +            themes.firstElementChild.focus();  | 
 | 461 | +            break;  | 
 | 462 | +        case "End":  | 
 | 463 | +            ev.preventDefault();  | 
 | 464 | +            themes.lastElementChild.focus();  | 
 | 465 | +            break;  | 
 | 466 | +        // The escape key is handled in handleEscape, not here,  | 
 | 467 | +        // so that pressing escape will close the menu even if it isn't focused  | 
410 | 468 |         }  | 
411 | 469 |     }  | 
412 | 470 | 
 
  | 
 | 
0 commit comments