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);
+      }
     }
   });
 })();