From da04d3c68b10bb848539a359ef818d6500045cda Mon Sep 17 00:00:00 2001 From: Hugo Giraudel <hugo.giraudel@gmail.com> Date: Fri, 15 Apr 2016 12:49:21 +0200 Subject: [PATCH 1/4] Fixed an issue with non-button toggles --- a11y-toggle.js | 10 +++++++++- a11y-toggle.min.js | 2 +- example/main.js | 10 +++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/a11y-toggle.js b/a11y-toggle.js index e157be6..bf7f2f8 100644 --- a/a11y-toggle.js +++ b/a11y-toggle.js @@ -54,7 +54,7 @@ }); }); - document.addEventListener('click', function (event) { + function handleToggle (event) { var toggle = getClosestToggle(event.target); var target = toggle && targetsMap[toggle.getAttribute('aria-controls')]; @@ -69,5 +69,13 @@ toggles.forEach(function (toggle) { toggle.setAttribute('aria-expanded', !isExpanded); }); + } + + document.addEventListener('click', handleToggle); + document.addEventListener('keyup', function (event) { + if (event.which === 13 || event.which === 32) { + var toggle = getClosestToggle(event.target); + if (toggle && toggle.getAttribute('role') === 'button') handleToggle(event); + } }); })(); diff --git a/a11y-toggle.min.js b/a11y-toggle.min.js index 2ef2bcf..33a46d2 100644 --- a/a11y-toggle.min.js +++ b/a11y-toggle.min.js @@ -1 +1 @@ -!function(){"use strict";function t(t){return Array.prototype.slice.call(document.querySelectorAll(t))}function e(t){if(t.closest)return t.closest("[data-a11y-toggle]");for(;t;){if(1===t.nodeType&&t.hasAttribute("data-a11y-toggle"))return t;t=t.parentNode}return null}var a=0,r={},i={};document.addEventListener("DOMContentLoaded",function(){r=t("[data-a11y-toggle]").reduce(function(t,e){var a="#"+e.getAttribute("data-a11y-toggle");return t[a]=t[a]||[],t[a].push(e),t},r);var e=Object.keys(r);e.length&&t(e).forEach(function(t){var e=r["#"+t.id],n=t.hasAttribute("data-a11y-toggle-open"),o=[];e.forEach(function(e){e.id||e.setAttribute("id","a11y-toggle-"+a++),e.setAttribute("aria-controls",t.id),e.setAttribute("aria-expanded",n),o.push(e.id)}),t.setAttribute("aria-hidden",!n),t.hasAttribute("aria-labelledby")||t.setAttribute("aria-labelledby",o.join(" ")),i[t.id]=t})}),document.addEventListener("click",function(t){var a=e(t.target),n=a&&i[a.getAttribute("aria-controls")];if(!n)return!1;var o=r["#"+n.id],u="false"===n.getAttribute("aria-hidden");n.setAttribute("aria-hidden",u),o.forEach(function(t){t.setAttribute("aria-expanded",!u)})})}(); \ No newline at end of file +!function(){"use strict";function t(t){return Array.prototype.slice.call(document.querySelectorAll(t))}function e(t){if(t.closest)return t.closest("[data-a11y-toggle]");for(;t;){if(1===t.nodeType&&t.hasAttribute("data-a11y-toggle"))return t;t=t.parentNode}return null}function r(t){var r=e(t.target),a=r&&n[r.getAttribute("aria-controls")];if(!a)return!1;var u=i["#"+a.id],o="false"===a.getAttribute("aria-hidden");a.setAttribute("aria-hidden",o),u.forEach(function(t){t.setAttribute("aria-expanded",!o)})}var a=0,i={},n={};document.addEventListener("DOMContentLoaded",function(){i=t("[data-a11y-toggle]").reduce(function(t,e){var r="#"+e.getAttribute("data-a11y-toggle");return t[r]=t[r]||[],t[r].push(e),t},i);var e=Object.keys(i);e.length&&t(e).forEach(function(t){var e=i["#"+t.id],r=t.hasAttribute("data-a11y-toggle-open"),u=[];e.forEach(function(e){e.id||e.setAttribute("id","a11y-toggle-"+a++),e.setAttribute("aria-controls",t.id),e.setAttribute("aria-expanded",r),u.push(e.id)}),t.setAttribute("aria-hidden",!r),t.hasAttribute("aria-labelledby")||t.setAttribute("aria-labelledby",u.join(" ")),n[t.id]=t})}),document.addEventListener("click",r),document.addEventListener("keyup",function(t){if(13===t.which||32===t.which){var a=e(t.target);a&&"button"===a.getAttribute("role")&&r(t)}})}(); \ No newline at end of file diff --git a/example/main.js b/example/main.js index e157be6..bf7f2f8 100644 --- a/example/main.js +++ b/example/main.js @@ -54,7 +54,7 @@ }); }); - document.addEventListener('click', function (event) { + function handleToggle (event) { var toggle = getClosestToggle(event.target); var target = toggle && targetsMap[toggle.getAttribute('aria-controls')]; @@ -69,5 +69,13 @@ toggles.forEach(function (toggle) { toggle.setAttribute('aria-expanded', !isExpanded); }); + } + + document.addEventListener('click', handleToggle); + document.addEventListener('keyup', function (event) { + if (event.which === 13 || event.which === 32) { + var toggle = getClosestToggle(event.target); + if (toggle && toggle.getAttribute('role') === 'button') handleToggle(event); + } }); })(); From 6ff876c9755baa995401bdc2587ed218e49d6e1f Mon Sep 17 00:00:00 2001 From: Hugo Giraudel <hugo.giraudel@gmail.com> Date: Fri, 15 Apr 2016 13:09:47 +0200 Subject: [PATCH 2/4] Reorganised script --- a11y-toggle.js | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/a11y-toggle.js b/a11y-toggle.js index bf7f2f8..187d2ad 100644 --- a/a11y-toggle.js +++ b/a11y-toggle.js @@ -2,6 +2,8 @@ 'use strict'; var internalId = 0; + var togglesMap = {}; + var targetsMap = {}; function $ (selector) { return Array.prototype.slice.call(document.querySelectorAll(selector)); @@ -23,8 +25,22 @@ return null; } - var togglesMap = {}; - var targetsMap = {}; + function handleToggle (event) { + var toggle = getClosestToggle(event.target); + 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); + }); + } document.addEventListener('DOMContentLoaded', function () { togglesMap = $('[data-a11y-toggle]').reduce(function (acc, toggle) { @@ -54,23 +70,6 @@ }); }); - function handleToggle (event) { - var toggle = getClosestToggle(event.target); - 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); - }); - } - document.addEventListener('click', handleToggle); document.addEventListener('keyup', function (event) { if (event.which === 13 || event.which === 32) { From 2f4b78fbf83faa0d151fc2410f8d86315dab3f14 Mon Sep 17 00:00:00 2001 From: Hugo Giraudel <hugo.giraudel@gmail.com> Date: Fri, 15 Apr 2016 13:12:26 +0200 Subject: [PATCH 3/4] Added an extra test to cover this edge case --- tests/index.html | 5 +++++ tests/index.js | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/index.html b/tests/index.html index 108e6d0..52f0395 100644 --- a/tests/index.html +++ b/tests/index.html @@ -83,6 +83,11 @@ <button data-a11y-toggle="t13" type="button"><span>Toggle</span></button> <div id="t13">Target</div> </div> + + <div class="test test-14"> + <span data-a11y-toggle="t14" role="button" tabindex="0">Toggle</span> + <div id="t14">Target</div> + </div> </div> <script src="../a11y-toggle.js"></script> diff --git a/tests/index.js b/tests/index.js index abe48cc..2e85a6d 100644 --- a/tests/index.js +++ b/tests/index.js @@ -1,5 +1,6 @@ +/* globals describe, it, expect */ + describe('Initial setup', function () { - var toggle, target; var actual, expected; it('should add `id` attribute to toggle if not set', function () { @@ -103,4 +104,13 @@ describe('Click events', function () { expected = 'true'; expect(actual).to.be.equal(expected); }); + + it('should work correctly with accessible non-<button> toggle', function () { + var toggle = document.querySelector('[data-a11y-toggle="t14"]'); + toggle.click(); + + actual = toggle.getAttribute('aria-expanded'); + expected = 'true'; + expect(actual).to.be.equal(expected); + }); }); From 2c7350ca3be9621bbc8e3108fb2791dc0f1c4dfb Mon Sep 17 00:00:00 2001 From: Hugo Giraudel <hugo.giraudel@gmail.com> Date: Fri, 15 Apr 2016 14:22:30 +0200 Subject: [PATCH 4/4] Optimised script performance a bit --- a11y-toggle.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/a11y-toggle.js b/a11y-toggle.js index 187d2ad..c862546 100644 --- a/a11y-toggle.js +++ b/a11y-toggle.js @@ -25,8 +25,7 @@ return null; } - function handleToggle (event) { - var toggle = getClosestToggle(event.target); + function handleToggle (toggle) { var target = toggle && targetsMap[toggle.getAttribute('aria-controls')]; if (!target) { @@ -70,11 +69,17 @@ }); }); - document.addEventListener('click', handleToggle); + 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(event); + if (toggle && toggle.getAttribute('role') === 'button') { + handleToggle(toggle); + } } }); })();