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