1var keyCodeMap = { 2 48:"0", 49:"1", 50:"2", 51:"3", 52:"4", 53:"5", 54:"6", 55:"7", 56:"8", 57:"9", 59:";", 3 65:"a", 66:"b", 67:"c", 68:"d", 69:"e", 70:"f", 71:"g", 72:"h", 73:"i", 74:"j", 75:"k", 76:"l", 4 77:"m", 78:"n", 79:"o", 80:"p", 81:"q", 82:"r", 83:"s", 84:"t", 85:"u", 86:"v", 87:"w", 88:"x", 89:"y", 90:"z", 5 96:"0", 97:"1", 98:"2", 99:"3", 100:"4", 101:"5", 102:"6", 103:"7", 104:"8", 105:"9" 6} 7 8 9jQuery.fn.setup_navigation = function(settings) { 10var $ = jQuery.noConflict(); 11 settings = jQuery.extend({ 12 menuHoverClass: 'show-menu', 13 }, settings); 14 15 // Add ARIA role to menubar and menu items 16 $(this).attr('role', 'menubar').find('li').attr('role', 'menuitem'); 17 18 var top_level_links = $(this).find('> li > a'); 19 20 // Added by Terrill: (removed temporarily: doesn't fix the JAWS problem after all) 21 // Add tabindex="0" to all top-level links 22 // Without at least one of these, JAWS doesn't read widget as a menu, despite all the other ARIA 23 //$(top_level_links).attr('tabindex','0'); 24 25 // Set tabIndex to -1 so that top_level_links can't receive focus until menu is open 26 $(top_level_links).next('ul') 27 .attr('data-test','true') 28 .attr({ 'aria-hidden': 'true', 'role': 'menu' }) 29 .find('a') 30 .attr('tabIndex',-1); 31 32 // Adding aria-haspopup for appropriate items 33 $(top_level_links).each(function(){ 34 if($(this).next('ul').length > 0) 35 $(this).parent('li').attr('aria-haspopup', 'true'); 36 }); 37 38 $(top_level_links).hover(function(){ 39 $(this).closest('ul') 40 .attr('aria-hidden', 'false') 41 .find('.'+settings.menuHoverClass) 42 .attr('aria-hidden', 'true') 43 .removeClass(settings.menuHoverClass) 44 .find('a') 45 .attr('tabIndex',-1); 46 $(this).next('ul') 47 .attr('aria-hidden', 'false') 48 .addClass(settings.menuHoverClass) 49 .find('a').attr('tabIndex',0); 50 }); 51 $(top_level_links).focus(function(){ 52 $(this).closest('ul') 53 // Removed by Terrill 54 // The following was adding aria-hidden="false" to root ul since menu is never hidden 55 // and seemed to be causing flakiness in JAWS (needs more testing) 56 // .attr('aria-hidden', 'false') 57 .find('.'+settings.menuHoverClass) 58 .attr('aria-hidden', 'true') 59 .removeClass(settings.menuHoverClass) 60 .find('a') 61 .attr('tabIndex',-1); 62 $(this).next('ul') 63 .attr('aria-hidden', 'false') 64 .addClass(settings.menuHoverClass) 65 .find('a').attr('tabIndex',0); 66 }); 67 68 // Bind arrow keys for navigation 69 $(top_level_links).keydown(function(e){ 70 if(e.keyCode == 37) { 71 e.preventDefault(); 72 // This is the first item 73 if($(this).parent('li').prev('li').length == 0) { 74 $(this).parents('ul').find('> li').last().find('a').first().focus(); 75 } else { 76 $(this).parent('li').prev('li').find('a').first().focus(); 77 } 78 } else if(e.keyCode == 38) { 79 e.preventDefault(); 80 if($(this).parent('li').find('ul').length > 0) { 81 $(this).parent('li').find('ul') 82 .attr('aria-hidden', 'false') 83 .addClass(settings.menuHoverClass) 84 .find('a').attr('tabIndex',0) 85 .last().focus(); 86 } 87 } else if(e.keyCode == 39) { 88 e.preventDefault(); 89 // This is the last item 90 if($(this).parent('li').next('li').length == 0) { 91 $(this).parents('ul').find('> li').first().find('a').first().focus(); 92 } else { 93 $(this).parent('li').next('li').find('a').first().focus(); 94 } 95 } else if(e.keyCode == 40) { 96 e.preventDefault(); 97 if($(this).parent('li').find('ul').length > 0) { 98 $(this).parent('li').find('ul') 99 .attr('aria-hidden', 'false') 100 .addClass(settings.menuHoverClass) 101 .find('a').attr('tabIndex',0) 102 .first().focus(); 103 } 104 } else if(e.keyCode == 32) { 105 // If submenu is hidden, open it 106 e.preventDefault(); 107 $(this).parent('li').find('ul[aria-hidden=true]') 108 .attr('aria-hidden', 'false') 109 .addClass(settings.menuHoverClass) 110 .find('a').attr('tabIndex',0) 111 .first().focus(); 112 } else if(e.keyCode == 27) { 113 e.preventDefault(); 114 $('.'+settings.menuHoverClass) 115 .attr('aria-hidden', 'true') 116 .removeClass(settings.menuHoverClass) 117 .find('a') 118 .attr('tabIndex',-1); 119 } else { 120 $(this).parent('li').find('ul[aria-hidden=false] a').each(function(){ 121 if($(this).text().substring(0,1).toLowerCase() == keyCodeMap[e.keyCode]) { 122 $(this).focus(); 123 return false; 124 } 125 }); 126 } 127 });
128 129 130 var links = $(top_level_links).parent('li').find('ul').find('a'); 131 $(links).keydown(function(e){ 132 if(e.keyCode == 38) { 133 e.preventDefault(); 134 // This is the first item 135 if($(this).parent('li').prev('li').length == 0) { 136 $(this).parents('ul').parents('li').find('a').first().focus(); 137 } else { 138 $(this).parent('li').prev('li').find('a').first().focus(); 139 } 140 } else if(e.keyCode == 40) { 141 e.preventDefault(); 142 if($(this).parent('li').next('li').length == 0) { 143 $(this).parents('ul').parents('li').find('a').first().focus(); 144 } else { 145 $(this).parent('li').next('li').find('a').first().focus(); 146 } 147 } else if(e.keyCode == 27 || e.keyCode == 37) { 148 e.preventDefault(); 149 $(this) 150 .parents('ul').first() 151 .prev('a').focus() 152 .parents('ul').first().find('.'+settings.menuHoverClass) 153 .attr('aria-hidden', 'true') 154 .removeClass(settings.menuHoverClass) 155 .find('a') 156 .attr('tabIndex',-1); 157 } else if(e.keyCode == 32) { 158 e.preventDefault(); 159 window.location = $(this).attr('href'); 160 } else { 161 var found = false; 162 $(this).parent('li').nextAll('li').find('a').each(function(){ 163 if($(this).text().substring(0,1).toLowerCase() == keyCodeMap[e.keyCode]) { 164 $(this).focus(); 165 found = true; 166 return false; 167 } 168 }); 169 170 if(!found) { 171 $(this).parent('li').prevAll('li').find('a').each(function(){ 172 if($(this).text().substring(0,1).toLowerCase() == keyCodeMap[e.keyCode]) { 173 $(this).focus(); 174 return false; 175 } 176 }); 177 } 178 } 179 }); 180 181 182 // Hide menu if click or focus occurs outside of navigation 183 $(this).find('a').last().keydown(function(e){ 184 if(e.keyCode == 9) { 185 // If the user tabs out of the navigation hide all menus 186 $('.'+settings.menuHoverClass) 187 .attr('aria-hidden', 'true') 188 .removeClass(settings.menuHoverClass) 189 .find('a') 190 .attr('tabIndex',-1); 191 } 192 }); 193 $(document).click(function(){ $('.'+settings.menuHoverClass).attr('aria-hidden', 'true').removeClass(settings.menuHoverClass).find('a').attr('tabIndex',-1); }); 194 195 $(this).click(function(e){ 196 e.stopPropagation(); 197 }); 198}; 199
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.