4
4
// Local js definitions:
5
5
/* global addClass, getCurrentValue, hasClass */
6
6
/* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */
7
+ /* global hideThemeButtonState, showThemeButtonState */
7
8
8
9
if ( ! String . prototype . startsWith ) {
9
10
String . prototype . startsWith = function ( searchString , position ) {
@@ -47,6 +48,14 @@ function getSearchElement() {
47
48
return document . getElementById ( "search" ) ;
48
49
}
49
50
51
+ function getThemesElement ( ) {
52
+ return document . getElementById ( "theme-choices" ) ;
53
+ }
54
+
55
+ function getThemePickerElement ( ) {
56
+ return document . getElementById ( "theme-picker" ) ;
57
+ }
58
+
50
59
// Sets the focus on the search bar at the top of the page
51
60
function focusSearchBar ( ) {
52
61
getSearchInput ( ) . focus ( ) ;
@@ -137,10 +146,6 @@ function defocusSearchBar() {
137
146
sidebar . appendChild ( div ) ;
138
147
}
139
148
}
140
- var themePickers = document . getElementsByClassName ( "theme-picker" ) ;
141
- if ( themePickers && themePickers . length > 0 ) {
142
- themePickers [ 0 ] . style . display = "none" ;
143
- }
144
149
}
145
150
146
151
function hideSidebar ( ) {
@@ -155,10 +160,6 @@ function defocusSearchBar() {
155
160
filler . remove ( ) ;
156
161
}
157
162
document . getElementsByTagName ( "body" ) [ 0 ] . style . marginTop = "" ;
158
- var themePickers = document . getElementsByClassName ( "theme-picker" ) ;
159
- if ( themePickers && themePickers . length > 0 ) {
160
- themePickers [ 0 ] . style . display = null ;
161
- }
162
163
}
163
164
164
165
function showSearchResults ( search ) {
@@ -376,6 +377,7 @@ function defocusSearchBar() {
376
377
document . title = titleBeforeSearch ;
377
378
}
378
379
defocusSearchBar ( ) ;
380
+ hideThemeButtonState ( ) ;
379
381
}
380
382
381
383
function handleShortcut ( ev ) {
@@ -412,7 +414,57 @@ function defocusSearchBar() {
412
414
case "?" :
413
415
displayHelp ( true , ev ) ;
414
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 ( ) ;
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 ( ) ;
415
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
416
468
}
417
469
}
418
470
0 commit comments