1var ia = { 2 aria: {}, 3 instances: [] 4 }; 5 6 (function() { 7 "use strict"; 8 9 ia.aria.Accordion = function(el, index) { 10 this.id = 'accordion-' + index; 11 this.el = el; 12 this.initialize(); 13 } 14 15 ia.aria.Accordion.prototype = { 16 17 tabs: [], 18 panels: [], 19 20 initialize: function() { 21 this.el.setAttribute('id', this.id); 22 this.el.setAttribute('role', 'tablist'); 23 this.el.setAttribute('aria-multiselectable', 'true'); 24 25 this.panels = [].slice.call( this.el.getElementsByTagName('dd') ); 26 27 this.panels.map( function( panel, i ){ 28 panel.setAttribute('id', this.id + "-panel-" + i); 29 panel.setAttribute('role', 'tabpanel'); 30 panel.setAttribute('aria-labeledby', this.id + "-tab-" + i); 31 panel.setAttribute('aria-hidden', 'true'); 32 panel.addEventListener( 'keydown', this.onPanelKeydown.bind(this), true ); 33 }, this ); 34 35 this.tabs = [].slice.call( this.el.getElementsByTagName('dt') ); 36 this.tabs.map( function( tab, i ){ 37 tab.setAttribute('role', 'tab'); 38 tab.setAttribute('id', this.id + "-tab-" + i); 39 tab.setAttribute('aria-controls', this.id + "-panel-" + i); 40 tab.setAttribute('aria-expanded', false); 41 tab.setAttribute('aria-selected', false); 42 tab.setAttribute('tabindex', i === 0 ? '0' : '-1'); 43 tab.addEventListener('click', this.onTabClick.bind(this)); 44 tab.addEventListener('keydown', this.onTabKeydown.bind(this)); 45 }, this ); 46 }, 47 48 getPanel: function(tab) { 49 return document.getElementById(tab.getAttribute('aria-controls')); 50 }, 51 52 select: function(tab) { 53 this.deselectAll(); 54 tab.setAttribute('aria-selected', 'true'); 55 tab.setAttribute('tabindex', '0'); 56 tab.focus(); 57 }, 58 59 deselectAll: function() { 60 this.tabs.map(function(tab, i){ 61 tab.setAttribute('aria-selected', 'false'); 62 tab.setAttribute('tabindex', '-1'); 63 }, this ); 64 }, 65 66 show: function(tab) { 67 this.getPanel(tab).setAttribute('aria-hidden', 'false'); 68 tab.setAttribute('aria-expanded', 'true'); 69 }, 70 71 hide: function(tab) { 72 this.getPanel(tab).setAttribute('aria-hidden', 'true'); 73 tab.setAttribute('aria-expanded', 'false'); 74 }, 75 76 hideAll: function() { 77 this.tabs.map(function(tab){ 78 this.hide(tab); 79 }, this); 80 }, 81 82 getNextTab: function(tab) { 83 var next = tab.nextSibling; 84 if (next === null) { 85 return this.tabs[0]; 86 } else if (next.tagName === 'DT') { 87 return next; 88 } else { 89 return this.getNextTab(next); 90 } 91 }, 92 93 getPrevTab: function(tab) { 94 var next = tab.previousSibling; 95 if (next === null) { 96 return this.tabs[this.tabs.length - 1]; 97 } else if (next.tagName === 'DT') { 98 return next; 99 } else { 100 return this.getPrevTab(next); 101 } 102 }, 103 104 onTabClick: function(e) { 105 var showTab = e.target.getAttribute('aria-expanded') !== 'true'; 106 this.hideAll(); 107 if (showTab) { 108 this.show(e.target); 109 } 110 }, 111 112 onTabKeydown: function(e) { 113 switch (e.which) { 114 case 13: // ENTER 115 case 32: // SPACE 116 e.preventDefault(); 117 e.stopPropagation(); 118 var showTab = e.target.getAttribute('aria-expanded') !== 'true'; 119 this.hideAll(); 120 if (showTab) { 121 this.show(e.target); 122 } 123 break; 124 case 37: // LEFT 125 case 38: // UP 126 e.preventDefault(); 127 e.stopPropagation(); 128 this.select(this.getPrevTab(e.target)); 129 break; 130 case 39: // RIGHT 131 case 40: // DOWN 132 e.preventDefault(); 133 e.stopPropagation(); 134 this.select(this.getNextTab(e.target)); 135 break; 136 case 35: // END 137 e.preventDefault(); 138 e.stopPropagation(); 139 this.select(this.tabs[this.tabs - 1]); 140 break; 141 case 36: // HOME 142 e.preventDefault(); 143 e.stopPropagation(); 144 this.select(this.tabs[0]); 145 break; 146 } 147 }, 148 149 onPanelKeydown: function(e) { 150 if ( e.ctrlKey || e.metaKey ) { 151 switch (e.which) { 152 case 38: // UP 153 e.preventDefault(); 154 e.stopPropagation(); 155 if( e.currentTarget ){ 156 this.select(this.getPrevTab(e.currentTarget)) ; 157 } 158 break; 159 case 40: // PAGE DOWN 160 e.preventDefault(); 161 e.stopPropagation(); 162 if( e.currentTarget ){ 163 this.select(this.getNextTab(e.currentTarget)) ; 164 } 165 break; 166 } 167 } 168 } 169 }; 170 171 window.addEventListener('load', function() { 172 var accordions = document.getElementsByClassName('accordion'); 173 for (var i = 0; i < accordions.length; i++) { 174 ia.instances[ia.instances.length] = new ia.aria.Accordion(accordions[i], i); 175 } 176 }); 177 })(); 178
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.