@@ -51,9 +51,9 @@ function printTab(nb) {
51
51
} ) ;
52
52
onEachLazy ( document . getElementById ( "results" ) . childNodes , function ( elem ) {
53
53
if ( nb === 0 ) {
54
- elem . style . display = "" ;
54
+ addClass ( elem , "active" ) ;
55
55
} else {
56
- elem . style . display = "none" ;
56
+ removeClass ( elem , "active" ) ;
57
57
}
58
58
nb -= 1 ;
59
59
} ) ;
@@ -878,106 +878,22 @@ window.initSearch = function(rawSearchIndex) {
878
878
} ;
879
879
}
880
880
881
- function initSearchNav ( ) {
882
- var hoverTimeout ;
883
-
884
- var click_func = function ( e ) {
885
- var el = e . target ;
886
- // to retrieve the real "owner" of the event.
887
- while ( el . tagName !== "TR" ) {
888
- el = el . parentNode ;
889
- }
890
- var dst = e . target . getElementsByTagName ( "a" ) ;
891
- if ( dst . length < 1 ) {
892
- return ;
893
- }
894
- dst = dst [ 0 ] ;
895
- if ( window . location . pathname === dst . pathname ) {
896
- searchState . hideResults ( ) ;
897
- document . location . href = dst . href ;
898
- }
899
- } ;
900
- var mouseover_func = function ( e ) {
901
- if ( searchState . mouseMovedAfterSearch ) {
902
- var el = e . target ;
903
- // to retrieve the real "owner" of the event.
904
- while ( el . tagName !== "TR" ) {
905
- el = el . parentNode ;
906
- }
907
- clearTimeout ( hoverTimeout ) ;
908
- hoverTimeout = setTimeout ( function ( ) {
909
- onEachLazy ( document . getElementsByClassName ( "search-results" ) , function ( e ) {
910
- onEachLazy ( e . getElementsByClassName ( "result" ) , function ( i_e ) {
911
- removeClass ( i_e , "highlighted" ) ;
912
- } ) ;
913
- } ) ;
914
- addClass ( el , "highlighted" ) ;
915
- } , 20 ) ;
916
- }
917
- } ;
918
- onEachLazy ( document . getElementsByClassName ( "search-results" ) , function ( e ) {
919
- onEachLazy ( e . getElementsByClassName ( "result" ) , function ( i_e ) {
920
- i_e . onclick = click_func ;
921
- i_e . onmouseover = mouseover_func ;
922
- } ) ;
923
- } ) ;
924
-
925
- searchState . input . onkeydown = function ( e ) {
926
- // "actives" references the currently highlighted item in each search tab.
927
- // Each array in "actives" represents a tab.
928
- var actives = [ [ ] , [ ] , [ ] ] ;
929
- // "current" is used to know which tab we're looking into.
930
- var current = 0 ;
931
- onEachLazy ( document . getElementById ( "results" ) . childNodes , function ( e ) {
932
- onEachLazy ( e . getElementsByClassName ( "highlighted" ) , function ( h_e ) {
933
- actives [ current ] . push ( h_e ) ;
934
- } ) ;
935
- current += 1 ;
936
- } ) ;
937
- var SHIFT = 16 ;
938
- var CTRL = 17 ;
939
- var ALT = 18 ;
881
+ function nextTab ( direction ) {
882
+ var next = ( searchState . currentTab + direction + 3 ) % searchState . focusedByTab . length ;
883
+ searchState . focusedByTab [ searchState . currentTab ] = document . activeElement ;
884
+ printTab ( next ) ;
885
+ focusSearchResult ( ) ;
886
+ }
940
887
941
- var currentTab = searchState . currentTab ;
942
- if ( e . which === 38 ) { // up
943
- if ( e . ctrlKey ) { // Going through result tabs.
944
- printTab ( currentTab > 0 ? currentTab - 1 : 2 ) ;
945
- } else {
946
- if ( ! actives [ currentTab ] . length ||
947
- ! actives [ currentTab ] [ 0 ] . previousElementSibling ) {
948
- return ;
949
- }
950
- addClass ( actives [ currentTab ] [ 0 ] . previousElementSibling , "highlighted" ) ;
951
- removeClass ( actives [ currentTab ] [ 0 ] , "highlighted" ) ;
952
- }
953
- e . preventDefault ( ) ;
954
- } else if ( e . which === 40 ) { // down
955
- if ( e . ctrlKey ) { // Going through result tabs.
956
- printTab ( currentTab > 1 ? 0 : currentTab + 1 ) ;
957
- } else if ( ! actives [ currentTab ] . length ) {
958
- var results = document . getElementById ( "results" ) . childNodes ;
959
- if ( results . length > 0 ) {
960
- var res = results [ currentTab ] . getElementsByClassName ( "result" ) ;
961
- if ( res . length > 0 ) {
962
- addClass ( res [ 0 ] , "highlighted" ) ;
963
- }
964
- }
965
- } else if ( actives [ currentTab ] [ 0 ] . nextElementSibling ) {
966
- addClass ( actives [ currentTab ] [ 0 ] . nextElementSibling , "highlighted" ) ;
967
- removeClass ( actives [ currentTab ] [ 0 ] , "highlighted" ) ;
968
- }
969
- e . preventDefault ( ) ;
970
- } else if ( e . which === 13 ) { // return
971
- if ( actives [ currentTab ] . length ) {
972
- var elem = actives [ currentTab ] [ 0 ] . getElementsByTagName ( "a" ) [ 0 ] ;
973
- document . location . href = elem . href ;
974
- }
975
- } else if ( [ SHIFT , CTRL , ALT ] . indexOf ( e . which ) !== - 1 ) {
976
- // Does nothing, it's just to avoid losing "focus" on the highlighted element.
977
- } else if ( actives [ currentTab ] . length > 0 ) {
978
- removeClass ( actives [ currentTab ] [ 0 ] , "highlighted" ) ;
979
- }
980
- } ;
888
+ // focus the first search result on the active tab, or the result that
889
+ // was focused last time this tab was active.
890
+ function focusSearchResult ( ) {
891
+ var target = searchState . focusedByTab [ searchState . currentTab ] ||
892
+ document . querySelectorAll ( ".search-results.active a" ) . item ( 0 ) ||
893
+ document . querySelectorAll ( "#titles > button" ) . item ( searchState . currentTab ) ;
894
+ if ( target ) {
895
+ target . focus ( ) ;
896
+ }
981
897
}
982
898
983
899
function buildHrefAndPath ( item ) {
@@ -1047,16 +963,16 @@ window.initSearch = function(rawSearchIndex) {
1047
963
}
1048
964
1049
965
function addTab ( array , query , display ) {
1050
- var extraStyle = "" ;
1051
- if ( display === false ) {
1052
- extraStyle = " style=\"display: none;\" " ;
966
+ var extraClass = "" ;
967
+ if ( display === true ) {
968
+ extraClass = " active " ;
1053
969
}
1054
970
1055
971
var output = "" ;
1056
972
var duplicates = { } ;
1057
973
var length = 0 ;
1058
974
if ( array . length > 0 ) {
1059
- output = "<table class=\"search-results\"" + extraStyle + ">" ;
975
+ output = "<div class=\"search-results " + extraClass + "\ ">";
1060
976
1061
977
array . forEach ( function ( item ) {
1062
978
var name , type ;
@@ -1072,20 +988,19 @@ window.initSearch = function(rawSearchIndex) {
1072
988
}
1073
989
length += 1 ;
1074
990
1075
- output += "<tr class=\"" + type + " result\"><td >" +
1076
- "<a href =\"" + item . href + " \">" +
991
+ output += "<a class=\"result- " + type + "\" href=\"" + item . href + "\" >" +
992
+ "<div><div class =\"result-name \">" +
1077
993
( item . is_alias === true ?
1078
994
( "<span class=\"alias\"><b>" + item . alias + " </b></span><span " +
1079
995
"class=\"grey\"><i> - see </i></span>" ) : "" ) +
1080
996
item . displayPath + "<span class=\"" + type + "\">" +
1081
- name + "</span></a></td><td>" +
1082
- "<a href=\"" + item . href + "\">" +
997
+ name + "</span></div><div>" +
1083
998
"<span class=\"desc\">" + item . desc +
1084
- " </span></a ></td ></tr >" ;
999
+ " </span></div ></div ></a >" ;
1085
1000
} ) ;
1086
- output += "</table >" ;
1001
+ output += "</div >" ;
1087
1002
} else {
1088
- output = "<div class=\"search-failed\"" + extraStyle + ">No results :(<br/>" +
1003
+ output = "<div class=\"search-failed\"" + extraClass + ">No results :(<br/>" +
1089
1004
"Try on <a href=\"https://duckduckgo.com/?q=" +
1090
1005
encodeURIComponent ( "rust " + query . query ) +
1091
1006
"\">DuckDuckGo</a>?<br/><br/>" +
@@ -1121,7 +1036,7 @@ window.initSearch = function(rawSearchIndex) {
1121
1036
{
1122
1037
var elem = document . createElement ( "a" ) ;
1123
1038
elem . href = results . others [ 0 ] . href ;
1124
- elem . style . display = "none" ;
1039
+ removeClass ( elem , "active" ) ;
1125
1040
// For firefox, we need the element to be in the DOM so it can be clicked.
1126
1041
document . body . appendChild ( elem ) ;
1127
1042
elem . click ( ) ;
@@ -1162,7 +1077,6 @@ window.initSearch = function(rawSearchIndex) {
1162
1077
1163
1078
search . innerHTML = output ;
1164
1079
searchState . showResults ( search ) ;
1165
- initSearchNav ( ) ;
1166
1080
var elems = document . getElementById ( "titles" ) . childNodes ;
1167
1081
elems [ 0 ] . onclick = function ( ) { printTab ( 0 ) ; } ;
1168
1082
elems [ 1 ] . onclick = function ( ) { printTab ( 1 ) ; } ;
@@ -1440,6 +1354,50 @@ window.initSearch = function(rawSearchIndex) {
1440
1354
} ;
1441
1355
searchState . input . onpaste = searchState . input . onchange ;
1442
1356
1357
+ searchState . outputElement ( ) . addEventListener ( "keydown" , function ( e ) {
1358
+ // We only handle unmodified keystrokes here. We don't want to interfere with,
1359
+ // for instance, alt-left and alt-right for history navigation.
1360
+ if ( e . altKey || e . ctrlKey || e . shiftKey || e . metaKey ) {
1361
+ return ;
1362
+ }
1363
+ // up and down arrow select next/previous search result, or the
1364
+ // search box if we're already at the top.
1365
+ if ( e . which === 38 ) { // up
1366
+ var previous = document . activeElement . previousElementSibling ;
1367
+ if ( previous ) {
1368
+ console . log ( "previousElementSibling" , previous ) ;
1369
+ previous . focus ( ) ;
1370
+ } else {
1371
+ searchState . focus ( ) ;
1372
+ }
1373
+ e . preventDefault ( ) ;
1374
+ } else if ( e . which === 40 ) { // down
1375
+ var next = document . activeElement . nextElementSibling ;
1376
+ if ( next ) {
1377
+ next . focus ( ) ;
1378
+ }
1379
+ var rect = document . activeElement . getBoundingClientRect ( ) ;
1380
+ if ( window . innerHeight - rect . bottom < rect . height ) {
1381
+ window . scrollBy ( 0 , rect . height ) ;
1382
+ }
1383
+ e . preventDefault ( ) ;
1384
+ } else if ( e . which === 37 ) { // left
1385
+ nextTab ( - 1 ) ;
1386
+ e . preventDefault ( ) ;
1387
+ } else if ( e . which === 39 ) { // right
1388
+ nextTab ( 1 ) ;
1389
+ e . preventDefault ( ) ;
1390
+ }
1391
+ } ) ;
1392
+
1393
+ searchState . input . addEventListener ( "keydown" , function ( e ) {
1394
+ if ( e . which === 40 ) { // down
1395
+ focusSearchResult ( ) ;
1396
+ e . preventDefault ( ) ;
1397
+ }
1398
+ } ) ;
1399
+
1400
+
1443
1401
var selectCrate = document . getElementById ( "crate-search" ) ;
1444
1402
if ( selectCrate ) {
1445
1403
selectCrate . onchange = function ( ) {
0 commit comments