|
74 | 74 | toggle(event.target); |
75 | 75 | }; |
76 | 76 |
|
| 77 | + var getKeyboardFocusableElements = function (element) { |
| 78 | + return [ |
| 79 | + ...element.querySelectorAll( |
| 80 | + 'a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])' |
| 81 | + ), |
| 82 | + ].filter( |
| 83 | + (el) => !el.hasAttribute("disabled") && !el.getAttribute("aria-hidden") |
| 84 | + ); |
| 85 | + }; |
| 86 | + |
77 | 87 | /** |
78 | 88 | * Remove roles and attributes from a tab and its content |
79 | 89 | * @param {Node} tab The tab |
|
93 | 103 | tab.removeAttribute("role"); |
94 | 104 | tab.removeAttribute("aria-controls"); |
95 | 105 | tab.removeAttribute("aria-selected"); |
| 106 | + tab.removeAttribute("tabindex"); |
96 | 107 | tab.closest("li").removeAttribute("role"); |
97 | 108 | content.removeAttribute("role"); |
98 | 109 | content.removeAttribute("aria-labelledby"); |
|
114 | 125 | // Add roles |
115 | 126 | tab.setAttribute("role", "tab"); |
116 | 127 | tab.setAttribute("aria-controls", content.id); |
117 | | - tab.setAttribute("tabindex", "0"); |
118 | 128 | tab.closest("li").setAttribute("role", "presentation"); |
119 | 129 | content.setAttribute("role", "tabpanel"); |
120 | 130 | content.setAttribute("aria-labelledby", tab.id); |
|
302 | 312 | // Add role to wrapper |
303 | 313 | tabWrapper.setAttribute("role", "tablist"); |
304 | 314 |
|
305 | | - // Add roles to tabs |
| 315 | + // Add roles to tabs. provide dynanmic tab indexes if we are within reveal |
| 316 | + var contentTabindexes = |
| 317 | + window.document.body.classList.contains("reveal-viewport"); |
| 318 | + var nextTabindex = 1; |
306 | 319 | Array.prototype.forEach.call(tabs, function (tab) { |
| 320 | + if (contentTabindexes) { |
| 321 | + tab.setAttribute("tabindex", "" + nextTabindex++); |
| 322 | + } else { |
| 323 | + tab.setAttribute("tabindex", "0"); |
| 324 | + } |
| 325 | + |
307 | 326 | // Get the tab content |
308 | 327 | var content = document.querySelector(tab.hash); |
309 | 328 | if (!content) return; |
310 | 329 |
|
| 330 | + // set tab indexes for content |
| 331 | + if (contentTabindexes) { |
| 332 | + getKeyboardFocusableElements(content).forEach(function (el) { |
| 333 | + el.setAttribute("tabindex", "" + nextTabindex++); |
| 334 | + }); |
| 335 | + } |
| 336 | + |
311 | 337 | // Setup the tab |
312 | 338 | setupTab(tab, content, settings); |
313 | 339 | }); |
|
0 commit comments