1$(function(){ 2 var searchToggleBtn, searchSlideNav; 3 var focusableElementsInSearchSlideNav; 4 var firstFocusableElementInSearchSlideNav, lastFocusableElementInSearchSlideNav; 5 6 searchToggleBtn = $("#searchToggleBtn"); 7 searchSlideNav = $("#searchSlideNav"); 8 focusableElementsInSearchSlideNav = $('#searchSlideNav input[type="text"], #searchSlideNav input[type="search"], #searchSlideNav [tabindex]:not([tabindex="-1"]), #searchSlideNav button:not([disabled]), #searchSlideNav a[href]'); 9 10 if(focusableElementsInSearchSlideNav.length) { 11 firstFocusableElementInSearchSlideNav = focusableElementsInSearchSlideNav.first(); 12 lastFocusableElementInSearchSlideNav = focusableElementsInSearchSlideNav.last(); 13 } 14 15 var hamburgerToggleBtn, hamburgerSlideNav; 16 var focusableElementsInHamburgerNav; 17 var firstFocusableElementInHamburgerNav, lastFocusableElementInHamburgerNav; 18 19 hamburgerToggleBtn = $("#hamburgerBtnNav"); 20 hamburgerSlideNav = $("#nav-collapse-design1"); 21 focusableElementsInHamburgerNav = $('#nav-collapse-design1 a, #nav-collapse-design1 [tabindex]:not([tabindex="-1"])'); 22 23 if(focusableElementsInHamburgerNav.length) { 24 firstFocusableElementInHamburgerNav = focusableElementsInHamburgerNav.first(); 25 lastFocusableElementInHamburgerNav = focusableElementsInHamburgerNav.last(); 26 } 27 28 searchSlideNav.on('shown.bs.collapse', function (e) { 29 // add initial focus. focusable elements in case DOM changed 30 if(focusableElementsInSearchSlideNav && focusableElementsInSearchSlideNav.length) { 31 firstFocusableElementInSearchSlideNav && firstFocusableElementInSearchSlideNav.focus(); 32 } 33 }); 34 35 36 searchSlideNav.on("keydown", function (e) { 37 38 if(!focusableElementsInSearchSlideNav.length) {return} 39 var first = focusableElementsInSearchSlideNav[0]; 40 var last = focusableElementsInSearchSlideNav[focusableElementsInSearchSlideNav.length - 1]; 41 42 // Robust focus trap inside popover 43 if (e.key === "Tab") { 44 if (e.shiftKey) { 45 // Shift+Tab: move backward 46 if (document.activeElement === first) { 47 e.preventDefault(); 48 last.focus(); 49 } 50 } else { 51 if (document.activeElement === last) { 52 e.preventDefault(); 53 first.focus(); 54 } 55 } 56 } else if (e.key === "Escape") { 57 searchSlideNav.collapse('hide'); 58 searchToggleBtn.focus(); 59 } 60 // Otherwise, do nothing 61 }); 62 63 // Remove per-element Tab trapping, now handled globally above 64 65 hamburgerSlideNav.on('shown.bs.collapse', function (e) { 66 // Update focusable elements in case DOM changed 67 focusableElementsInHamburgerNav = $('#nav-collapse-design1 a, #nav-collapse-design1 [tabindex]:not([tabindex="-1"])'); 68 if(focusableElementsInHamburgerNav.length) { 69 firstFocusableElementInHamburgerNav = focusableElementsInHamburgerNav.first(); 70 lastFocusableElementInHamburgerNav = focusableElementsInHamburgerNav.last(); 71 firstFocusableElementInHamburgerNav.focus(); 72 } 73 searchSlideNav.collapse('hide'); 74 }); 75 76 77 hamburgerSlideNav.on("keydown", function (e) { 78 if(!focusableElementsInHamburgerNav.length) return; 79 var first = focusableElementsInHamburgerNav[0]; 80 var last = focusableElementsInHamburgerNav[focusableElementsInHamburgerNav.length - 1]; 81 var currentIndex = Array.prototype.indexOf.call(focusableElementsInHamburgerNav, document.activeElement); 82 83 if (e.key === "ArrowDown") { 84 e.preventDefault(); 85 // Move to next, or wrap to first 86 var nextIndex = (currentIndex + 1) % focusableElementsInHamburgerNav.length; 87 focusableElementsInHamburgerNav[nextIndex].focus(); 88 } else if (e.key === "ArrowUp") { 89 e.preventDefault(); 90 // Move to previous, or wrap to last 91 var prevIndex = (currentIndex - 1 + focusableElementsInHamburgerNav.length) % focusableElementsInHamburgerNav.length; 92 focusableElementsInHamburgerNav[prevIndex].focus(); 93 } else if (e.key === "Tab") { 94 // Trap focus inside menu 95 if (e.shiftKey) { 96 if (document.activeElement === first) { 97 e.preventDefault(); 98 last.focus(); 99 } 100 } else { 101 if (document.activeElement === last) { 102 e.preventDefault(); 103 first.focus(); 104 } 105 } 106 } else if (e.key === "Escape") { 107 hamburgerSlideNav.collapse('hide'); 108 hamburgerToggleBtn.focus(); 109 } 110 // Otherwise, do nothing 111 }); 112 113 // Remove per-element Tab trapping, now handled globally above 114 115}); 116
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.