diff options
Diffstat (limited to '')
-rw-r--r-- | helpcontent2/help3xsl/a11y-toggle.js | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/helpcontent2/help3xsl/a11y-toggle.js b/helpcontent2/help3xsl/a11y-toggle.js new file mode 100644 index 000000000..821a8e027 --- /dev/null +++ b/helpcontent2/help3xsl/a11y-toggle.js @@ -0,0 +1,100 @@ +/* +MIT License + +Copyright (c) 2016 Edenspiekermann + +*/ + +(function () { + 'use strict'; + + var internalId = 0; + var togglesMap = {}; + var targetsMap = {}; + + function $ (selector, context) { + return Array.prototype.slice.call( + (context || document).querySelectorAll(selector) + ); + } + + function getClosestToggle (element) { + if (element.closest) { + return element.closest('[data-a11y-toggle]'); + } + + while (element) { + if (element.nodeType === 1 && element.hasAttribute('data-a11y-toggle')) { + return element; + } + + element = element.parentNode; + } + + return null; + } + + function handleToggle (toggle) { + var target = toggle && targetsMap[toggle.getAttribute('aria-controls')]; + + if (!target) { + return false; + } + + var toggles = togglesMap['#' + target.id]; + var isExpanded = target.getAttribute('aria-hidden') === 'false'; + + target.setAttribute('aria-hidden', isExpanded); + toggles.forEach(function (toggle) { + toggle.setAttribute('aria-expanded', !isExpanded); + }); + } + + var initA11yToggle = function (context) { + togglesMap = $('[data-a11y-toggle]', context).reduce(function (acc, toggle) { + var selector = '#' + toggle.getAttribute('data-a11y-toggle'); + acc[selector] = acc[selector] || []; + acc[selector].push(toggle); + return acc; + }, togglesMap); + + var targets = Object.keys(togglesMap); + targets.length && $(targets).forEach(function (target) { + var toggles = togglesMap['#' + target.id]; + var isExpanded = target.hasAttribute('data-a11y-toggle-open'); + var labelledby = []; + + toggles.forEach(function (toggle) { + toggle.id || toggle.setAttribute('id', 'a11y-toggle-' + internalId++); + toggle.setAttribute('aria-controls', target.id); + toggle.setAttribute('aria-expanded', isExpanded); + labelledby.push(toggle.id); + }); + + target.setAttribute('aria-hidden', !isExpanded); + target.hasAttribute('aria-labelledby') || target.setAttribute('aria-labelledby', labelledby.join(' ')); + + targetsMap[target.id] = target; + }); + }; + + document.addEventListener('DOMContentLoaded', function () { + initA11yToggle(); + }); + + document.addEventListener('click', function (event) { + var toggle = getClosestToggle(event.target); + handleToggle(toggle); + }); + + document.addEventListener('keyup', function (event) { + if (event.which === 13 || event.which === 32) { + var toggle = getClosestToggle(event.target); + if (toggle && toggle.getAttribute('role') === 'button') { + handleToggle(toggle); + } + } + }); + + window && (window.a11yToggle = initA11yToggle); +})(); |