1(function(document, window, undefined) { 2 "use strict"; 3 4 // Vars 5 var faqSection = $(".js-acc"), 6 accTitle = $(".js-acc-title"), 7 faqContent = $(".js-acc-content"), 8 showOneAnswerAtATime = false; 9 10 /** 11 * Save Title focus 12 */ 13 var saveFocus = function(elem, thisSectionAccItems) { 14 // Reset other tab attributes 15 thisSectionAccItems.each(function() { 16 $(this).attr("tabindex", "-1"); 17 $(this).attr("aria-selected", "false"); 18 }); 19 20 // Set this tab attributes 21 elem.attr({ 22 tabindex: "0", 23 "aria-selected": "true" 24 }); 25 }; 26 27 /** 28 * Show answer on click 29 */ 30 var showAnswer = function(elem, thisSectionAccItems) { 31 var thisfaqContent = elem.next(); 32 33 // Save focus 34 saveFocus(elem, thisSectionAccItems); 35 36 // Set this tab attributes 37 if (thisfaqContent.hasClass("active")) { 38 // Hide answer 39 thisfaqContent.removeClass("active"); 40 elem.attr("aria-expanded", "false"); 41 thisfaqContent.attr("aria-hidden", "true"); 42 } else { 43 if (showOneAnswerAtATime) { 44 // Hide all answers 45 faqContent.removeClass("active").attr("aria-hidden", "true"); 46 accTitle.attr("aria-expanded", "false"); 47 } 48 49 // Show answer 50 thisfaqContent.addClass("active"); 51 elem.attr("aria-expanded", "true"); 52 thisfaqContent.attr("aria-hidden", "false"); 53 } 54 }; 55 56 /** 57 * Keyboard interaction 58 */ 59 var keyboardInteraction = function(elem, e, thisSectionAccItems) { 60 var keyCode = e.which, 61 nextTitle = elem 62 .next() 63 .next() 64 .is("dt") 65 ? elem.next().next() 66 : false, 67 previousTitle = elem 68 .prev() 69 .prev() 70 .is("dt") 71 ? elem.prev().prev() 72 : false, 73 firstTitle = elem.parent().find("dt:first"), 74 lastTitle = elem.parent().find("dt:last"); 75 76 switch (keyCode) { 77 // Left/Up 78 case 37: 79 case 38: 80 e.preventDefault(); 81 e.stopPropagation(); 82 83 // Check for previous Title 84 if (!previousTitle) { 85 // No previous, set focus on last Title 86 lastTitle.focus(); 87 } else { 88 // Move focus to previous Title 89 previousTitle.focus(); 90 } 91 92 break; 93 94 // Right/Down 95 case 39: 96 case 40: 97 e.preventDefault(); 98 e.stopPropagation(); 99 100 // Check for next Title 101 if (!nextTitle) { 102 // No next, set focus on first Title 103 firstTitle.focus(); 104 } else { 105 // Move focus to next Title 106 nextTitle.focus(); 107 } 108 109 break; 110 111 // Home 112 case 36: 113 e.preventDefault(); 114 e.stopPropagation(); 115 116 // Set focus on first Title 117 firstTitle.focus(); 118 break; 119 120 // End 121 case 35: 122 e.preventDefault(); 123 e.stopPropagation(); 124 125 // Set focus on last Title 126 lastTitle.focus(); 127 break; 128 129 // Enter/Space 130 case 13: 131 case 32: 132 e.preventDefault(); 133 e.stopPropagation(); 134 135 // Show answer content 136 showAnswer(elem, thisSectionAccItems); 137 break; 138 } 139 }; 140 141 /** 142 * On load, setup roles and initial properties 143 */ 144 145 // Each FAQ Title 146 accTitle.each(function(i) { 147 $(this).attr({ 148 id: "acc-title-" + i, 149 role: "tab", 150 "aria-controls": "acc-answer-" + i, 151 "aria-expanded": "false", 152 "aria-selected": "false", 153 tabindex: "-1" 154 }); 155 }); 156 157 // Each FAQ Answer 158 faqContent.each(function(i) { 159 $(this).attr({ 160 id: "acc-content-" + i, 161 role: "tabpanel", 162 "aria-labelledby": "acc-title-" + i, 163 "aria-hidden": "true" 164 }); 165 }); 166 167 // Each FAQ Section 168 faqSection.each(function() { 169 var $this = $(this), 170 thisSectionAccItems = $this.find(".js-acc-title"); 171 172 // Set section attributes 173 $this.attr({ 174 role: "tablist", 175 "aria-multiselectable": "true" 176 }); 177 178 thisSectionAccItems.each(function(i) { 179 var $this = $(this); 180 181 // Make first tab clickable 182 if (i === 0) { 183 $this.attr("tabindex", "0"); 184 } 185 186 // Click event 187 $this.on("click", function() { 188 showAnswer($(this), thisSectionAccItems); 189 }); 190 191 // Keydown event 192 $this.on("keydown", function(e) { 193 keyboardInteraction($(this), e, thisSectionAccItems); 194 }); 195 196 // Focus event 197 $this.on("focus", function() { 198 saveFocus($(this), thisSectionAccItems); 199 }); 200 }); 201 }); 202})(document, window);
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.