From b6a5f68c4b13b59d23e529e96f98057e672f7ebf Mon Sep 17 00:00:00 2001 From: "DESKTOP-0LNRR0O\\Nico" Date: Mon, 10 Apr 2017 18:44:39 +0200 Subject: [PATCH] Linted and re-indentation + added editorconfig --- .editorconfig | 15 + demo/index-fr.html | 2 +- demo/index.html | 2 +- dist/van11y-accessible-accordion-aria.es6.js | 743 ++++++++++--------- dist/van11y-accessible-accordion-aria.js | 732 +++++++++--------- dist/van11y-accessible-accordion-aria.min.js | 4 +- package.json | 2 +- src/van11y-accessible-accordion-aria.es6.js | 743 ++++++++++--------- 8 files changed, 1138 insertions(+), 1105 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..95d5513 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{js,scss,css,html,hbs,twig,json}] +indent_style = space +indent_size = 4 diff --git a/demo/index-fr.html b/demo/index-fr.html index 3f25f81..74d2c1b 100644 --- a/demo/index-fr.html +++ b/demo/index-fr.html @@ -59,7 +59,7 @@

Un accordéon animé avec sélection multiple

… pas ouvert par défaut

-

Oui, ça marche aussi.

+

Oui, ça marche aussi (ce texte est focusable).

diff --git a/demo/index.html b/demo/index.html index 1bccf92..521f12e 100644 --- a/demo/index.html +++ b/demo/index.html @@ -59,7 +59,7 @@

An accordion animated multi-selectable…

… not opened by default

-

Yes, it rocks too.

+

Yes, it rocks too.

diff --git a/dist/van11y-accessible-accordion-aria.es6.js b/dist/van11y-accessible-accordion-aria.es6.js index 4bb2e24..ad0659d 100644 --- a/dist/van11y-accessible-accordion-aria.es6.js +++ b/dist/van11y-accessible-accordion-aria.es6.js @@ -3,415 +3,424 @@ * Website: https://van11y.net/accessible-accordion/ * License MIT: https://github.com/nico3333fr/van11y-accessible-accordion-aria/blob/master/LICENSE */ -;(doc => { - - 'use strict'; - - const ACCORDION_JS = 'js-accordion'; - const ACCORDION_JS_HEADER = 'js-accordion__header'; - const ACCORDION_JS_PANEL = 'js-accordion__panel'; - - const ACCORDION_DATA_PREFIX_CLASS = 'data-accordion-prefix-classes'; - const ACCORDION_DATA_OPENED = 'data-accordion-opened'; - const ACCORDION_DATA_MULTISELECTABLE = 'data-accordion-multiselectable'; - - const ACCORDION_PREFIX_IDS = 'accordion'; - const ACCORDION_BUTTON_ID = '_tab'; - const ACCORDION_PANEL_ID = '_panel'; - - const ACCORDION_STYLE = 'accordion'; - const ACCORDION_TITLE_STYLE = 'accordion__title'; - const ACCORDION_HEADER_STYLE = 'accordion__header'; - const ACCORDION_PANEL_STYLE = 'accordion__panel'; - - const ACCORDION_ROLE_TABLIST = 'tablist'; - const ACCORDION_ROLE_TAB = 'tab'; - const ACCORDION_ROLE_TABPANEL = 'tabpanel'; - - const ATTR_ROLE = 'role'; - const ATTR_MULTISELECTABLE = 'aria-multiselectable'; - const ATTR_EXPANDED = 'aria-expanded'; - const ATTR_LABELLEDBY = 'aria-labelledby'; - const ATTR_HIDDEN = 'aria-hidden'; - const ATTR_CONTROLS = 'aria-controls'; - const ATTR_SELECTED = 'aria-selected'; - - - const IS_OPENED_CLASS = 'is-opened'; - - - - const findById = id => doc.getElementById(id); - - const addClass = (el, className) => { +(doc => { + + 'use strict'; + + const ACCORDION_JS = 'js-accordion'; + const ACCORDION_JS_HEADER = 'js-accordion__header'; + const ACCORDION_JS_PANEL = 'js-accordion__panel'; + + const ACCORDION_DATA_PREFIX_CLASS = 'data-accordion-prefix-classes'; + const ACCORDION_DATA_OPENED = 'data-accordion-opened'; + const ACCORDION_DATA_MULTISELECTABLE = 'data-accordion-multiselectable'; + + const ACCORDION_PREFIX_IDS = 'accordion'; + const ACCORDION_BUTTON_ID = '_tab'; + const ACCORDION_PANEL_ID = '_panel'; + + const ACCORDION_STYLE = 'accordion'; + const ACCORDION_TITLE_STYLE = 'accordion__title'; + const ACCORDION_HEADER_STYLE = 'accordion__header'; + const ACCORDION_PANEL_STYLE = 'accordion__panel'; + + const ACCORDION_ROLE_TABLIST = 'tablist'; + const ACCORDION_ROLE_TAB = 'tab'; + const ACCORDION_ROLE_TABPANEL = 'tabpanel'; + + const ATTR_ROLE = 'role'; + const ATTR_MULTISELECTABLE = 'aria-multiselectable'; + const ATTR_EXPANDED = 'aria-expanded'; + const ATTR_LABELLEDBY = 'aria-labelledby'; + const ATTR_HIDDEN = 'aria-hidden'; + const ATTR_CONTROLS = 'aria-controls'; + const ATTR_SELECTED = 'aria-selected'; + + + //const IS_OPENED_CLASS = 'is-opened'; + + + + const findById = id => doc.getElementById(id); + + const addClass = (el, className) => { if (el.classList) { - el.classList.add(className); // IE 10+ + el.classList.add(className); // IE 10+ + } else { + el.className += ' ' + className; // IE 8+ } - else { - el.className += ' ' + className; // IE 8+ - } - } - - const removeClass = (el, className) => { + } + + const removeClass = (el, className) => { if (el.classList) { - el.classList.remove(className); // IE 10+ - } - else { - el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); // IE 8+ - } + el.classList.remove(className); // IE 10+ + } else { + el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); // IE 8+ } + } - const hasClass = (el, className) => { + const hasClass = (el, className) => { if (el.classList) { - return el.classList.contains(className); // IE 10+ - } - else { - return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); // IE 8+ ? - } + return el.classList.contains(className); // IE 10+ + } else { + return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); // IE 8+ ? } - - const setAttributes = (node, attrs) => { + } + + const setAttributes = (node, attrs) => { Object - .keys(attrs) - .forEach((attribute) => { - node.setAttribute(attribute, attrs[attribute]); - }); - }; -/* const triggerEvent = (el, event_type) => { - if (el.fireEvent) { - el.fireEvent('on' + event_type); - } - else { - let evObj = document.createEvent('Events'); - evObj.initEvent(event_type, true, false); - el.dispatchEvent(evObj); - } - }*/ - const unSelectHeaders = (elts) => { + .keys(attrs) + .forEach((attribute) => { + node.setAttribute(attribute, attrs[attribute]); + }); + }; + /* const triggerEvent = (el, event_type) => { + if (el.fireEvent) { + el.fireEvent('on' + event_type); + } + else { + let evObj = document.createEvent('Events'); + evObj.initEvent(event_type, true, false); + el.dispatchEvent(evObj); + } + }*/ + const unSelectHeaders = (elts) => { elts - .forEach((header_node, index) => { - setAttributes(header_node, { - [ATTR_SELECTED] : 'false' , - 'tabindex' : '-1' - }); - }); - } - - const selectHeader = (el) => { - el.setAttribute( ATTR_SELECTED , true ); - el.removeAttribute ( 'tabindex' ); - } - - const selectHeaderInList = (elts, param) => { + .forEach((header_node) => { + setAttributes(header_node, { + [ATTR_SELECTED]: 'false', + 'tabindex': '-1' + }); + }); + } + + const selectHeader = (el) => { + el.setAttribute(ATTR_SELECTED, true); + el.removeAttribute('tabindex'); + } + + const selectHeaderInList = (elts, param) => { let indice_trouve; elts - .forEach((header_node, index) => { - - if ( header_node.getAttribute(ATTR_SELECTED) === 'true' ) { - indice_trouve = index; - } - - }); - if ( param === 'next' ){ - selectHeader ( elts[indice_trouve+1] ); - setTimeout(function(){ elts[indice_trouve+1].focus(); }, 0); - } - if ( param === 'prev' ){ - selectHeader ( elts[indice_trouve-1] ); - setTimeout(function(){ elts[indice_trouve-1].focus(); }, 0); - } - + .forEach((header_node, index) => { + + if (header_node.getAttribute(ATTR_SELECTED) === 'true') { + indice_trouve = index; + } + + }); + if (param === 'next') { + selectHeader(elts[indice_trouve + 1]); + setTimeout(function() { + elts[indice_trouve + 1].focus(); + }, 0); } + if (param === 'prev') { + selectHeader(elts[indice_trouve - 1]); + setTimeout(function() { + elts[indice_trouve - 1].focus(); + }, 0); + } + + } - /* gets an element el, search if it is child of parent class, returns id of the parent */ - let searchParent = ( el, parentClass ) => { + /* gets an element el, search if it is child of parent class, returns id of the parent */ + let searchParent = (el, parentClass) => { let found = false; let parentElement = el.parentNode; - while ( parentElement && found === false ) { - if ( hasClass( parentElement, parentClass ) === true ) { + while (parentElement && found === false) { + if (hasClass(parentElement, parentClass) === true) { found = true; - } - else { - parentElement = parentElement.parentNode; - } + } else { + parentElement = parentElement.parentNode; } - if ( found === true ) { - return parentElement.getAttribute('id'); - } - else { return ''; } - } - - - // Find all accordions - const $listAccordions = () => [].slice.call(doc.querySelectorAll('.' + ACCORDION_JS)); - - - const onLoad = () => { - - $listAccordions() - .forEach((accordion_node, index) => { - - let iLisible = index + 1; - let prefixClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) + '-' : '' ; - let accordionClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) : '' ; - let multiSelectableAttribute = accordion_node.hasAttribute(ACCORDION_DATA_MULTISELECTABLE) === true ? accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) : '' ; - /*let toExpand = node.nextElementSibling; - let expandmoreText = node.innerHTML; - let expandButton = doc.createElement("BUTTON");*/ - - // clear element before adding button to it - //node.innerHTML = ''; - - // Init attributes accordion - if (accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) == 'none'){ - accordion_node.setAttribute( ATTR_MULTISELECTABLE , 'false' ); - } - else { - accordion_node.setAttribute( ATTR_MULTISELECTABLE , 'true' ); - } - accordion_node.setAttribute( ATTR_ROLE , ACCORDION_ROLE_TABLIST ); - addClass( accordion_node, prefixClassName + ACCORDION_STYLE); - - let $listAccordionsHeader = [].slice.call(accordion_node.querySelectorAll('.' + ACCORDION_JS_HEADER)); - $listAccordionsHeader - .forEach((header_node, index_header) => { - - let indexHeaderLisible = index_header+1; - let accordionPanel = header_node.nextElementSibling; - let accordionHeaderText = header_node.innerHTML; - let accordionButton = document.createElement("BUTTON"); - let accordionOpenedAttribute = header_node.hasAttribute(ACCORDION_DATA_OPENED) === true ? header_node.getAttribute(ACCORDION_DATA_OPENED) : '' ; - - // set button with attributes - accordionButton.innerHTML = accordionHeaderText; - addClass( accordionButton, ACCORDION_JS_HEADER ); - addClass( accordionButton, prefixClassName + ACCORDION_HEADER_STYLE ); - setAttributes(accordionButton, { - [ATTR_ROLE] : ACCORDION_ROLE_TAB , - 'id' : ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible , - [ATTR_CONTROLS] : ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible , - [ATTR_SELECTED] : 'false' , - 'tabindex' : '-1', - 'type' : 'button' - }); - - // place button - accordionButton = accordion_node.insertBefore(accordionButton, header_node); - - // move title into panel - accordionPanel.insertBefore(header_node, accordionPanel.firstChild); - // set title with attributes - addClass( header_node, prefixClassName + ACCORDION_TITLE_STYLE ); - removeClass ( header_node, ACCORDION_JS_HEADER ); - - // set attributes to panels - addClass( accordionPanel, prefixClassName + ACCORDION_PANEL_STYLE); - setAttributes(accordionPanel, { - [ATTR_ROLE] : ACCORDION_ROLE_TABPANEL , - [ATTR_LABELLEDBY] : ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible , - 'id' : ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible - }); - - if (accordionOpenedAttribute === 'true'){ - accordionButton.setAttribute( ATTR_EXPANDED , 'true' ); - header_node.removeAttribute( ACCORDION_DATA_OPENED ); - accordionPanel.setAttribute( ATTR_HIDDEN , 'false' ); - } - else { - accordionButton.setAttribute( ATTR_EXPANDED , 'false' ); - accordionPanel.setAttribute( ATTR_HIDDEN , 'true' ); - } + } + if (found === true) { + return parentElement.getAttribute('id'); + } else { + return ''; + } + } - // init first one focusable - if ( indexHeaderLisible === 1 ) { - accordionButton.removeAttribute( 'tabindex' ); - } - }); + // Find all accordions + const $listAccordions = () => [].slice.call(doc.querySelectorAll('.' + ACCORDION_JS)); + + + const onLoad = () => { - - }); - - // click on - ['click', 'keydown', 'focus'] - .forEach(eventName => { - let isCtrl = false; - - doc.body - .addEventListener(eventName, e => { - - // focus on button - if ( hasClass( e.target, ACCORDION_JS_HEADER) === true && eventName === 'focus' ) { - let buttonTag = e.target; - let accordionContainer = buttonTag.parentNode; - let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - - unSelectHeaders($accordionAllHeaders); - - selectHeader(buttonTag); + $listAccordions() + .forEach((accordion_node, index) => { + let iLisible = index + 1; + let prefixClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) + '-' : ''; + //let accordionClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) : '' ; + //let multiSelectableAttribute = accordion_node.hasAttribute(ACCORDION_DATA_MULTISELECTABLE) === true ? accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) : '' ; + /*let toExpand = node.nextElementSibling; + let expandmoreText = node.innerHTML; + let expandButton = doc.createElement("BUTTON");*/ + + // clear element before adding button to it + //node.innerHTML = ''; + + // Init attributes accordion + if (accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) === 'none') { + accordion_node.setAttribute(ATTR_MULTISELECTABLE, 'false'); + } else { + accordion_node.setAttribute(ATTR_MULTISELECTABLE, 'true'); } + accordion_node.setAttribute(ATTR_ROLE, ACCORDION_ROLE_TABLIST); + addClass(accordion_node, prefixClassName + ACCORDION_STYLE); + + let $listAccordionsHeader = [].slice.call(accordion_node.querySelectorAll('.' + ACCORDION_JS_HEADER)); + $listAccordionsHeader + .forEach((header_node, index_header) => { + + let indexHeaderLisible = index_header + 1; + let accordionPanel = header_node.nextElementSibling; + let accordionHeaderText = header_node.innerHTML; + let accordionButton = document.createElement("BUTTON"); + let accordionOpenedAttribute = header_node.hasAttribute(ACCORDION_DATA_OPENED) === true ? header_node.getAttribute(ACCORDION_DATA_OPENED) : ''; + + // set button with attributes + accordionButton.innerHTML = accordionHeaderText; + addClass(accordionButton, ACCORDION_JS_HEADER); + addClass(accordionButton, prefixClassName + ACCORDION_HEADER_STYLE); + setAttributes(accordionButton, { + [ATTR_ROLE]: ACCORDION_ROLE_TAB, + 'id': ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible, + [ATTR_CONTROLS]: ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible, + [ATTR_SELECTED]: 'false', + 'tabindex': '-1', + 'type': 'button' + }); + + // place button + accordionButton = accordion_node.insertBefore(accordionButton, header_node); + + // move title into panel + accordionPanel.insertBefore(header_node, accordionPanel.firstChild); + // set title with attributes + addClass(header_node, prefixClassName + ACCORDION_TITLE_STYLE); + removeClass(header_node, ACCORDION_JS_HEADER); + + // set attributes to panels + addClass(accordionPanel, prefixClassName + ACCORDION_PANEL_STYLE); + setAttributes(accordionPanel, { + [ATTR_ROLE]: ACCORDION_ROLE_TABPANEL, + [ATTR_LABELLEDBY]: ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible, + 'id': ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible + }); + + if (accordionOpenedAttribute === 'true') { + accordionButton.setAttribute(ATTR_EXPANDED, 'true'); + header_node.removeAttribute(ACCORDION_DATA_OPENED); + accordionPanel.setAttribute(ATTR_HIDDEN, 'false'); + } else { + accordionButton.setAttribute(ATTR_EXPANDED, 'false'); + accordionPanel.setAttribute(ATTR_HIDDEN, 'true'); + } - // click on button - if ( hasClass( e.target, ACCORDION_JS_HEADER) === true && eventName === 'click' ) { - let buttonTag = e.target; - let accordionContainer = buttonTag.parentNode; - let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - let accordionMultiSelectable = accordionContainer.getAttribute(ATTR_MULTISELECTABLE); - let destination = findById(buttonTag.getAttribute( ATTR_CONTROLS )); - let stateButton = buttonTag.getAttribute(ATTR_EXPANDED); - - // if closed - if ( stateButton === 'false' ){ - buttonTag.setAttribute( ATTR_EXPANDED , true ); - destination.removeAttribute( ATTR_HIDDEN ); - } - else { - buttonTag.setAttribute( ATTR_EXPANDED , false ); - destination.setAttribute( ATTR_HIDDEN , true ); + // init first one focusable + if (indexHeaderLisible === 1) { + accordionButton.removeAttribute('tabindex'); } - if ( accordionMultiSelectable === 'false' ) { - $accordionAllHeaders - .forEach((header_node, index) => { - - let destinationPanel = findById(header_node.getAttribute( ATTR_CONTROLS )); - - if ( header_node !== buttonTag ){ - header_node.setAttribute( ATTR_SELECTED , false ); - header_node.setAttribute( ATTR_EXPANDED , false ); - destinationPanel.setAttribute( ATTR_HIDDEN , true ); - } - else { - header_node.setAttribute( ATTR_SELECTED , true ); - } - }); + }); - } - - setTimeout(function(){ buttonTag.focus(); }, 0); - e.preventDefault(); - } - - // keyboard management for headers - if ( hasClass( e.target, ACCORDION_JS_HEADER) === true && eventName === 'keydown' ) { - let buttonTag = e.target; - let accordionContainer = buttonTag.parentNode; - let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - - // strike home on a tab => 1st tab - if ( e.keyCode === 36 ) { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function(){ $accordionAllHeaders[0].focus(); }, 0); - e.preventDefault(); - } - // strike end on the tab => last tab - else if ( e.keyCode == 35 ) { + }); + + // click on + ['click', 'keydown', 'focus'] + .forEach(eventName => { + //let isCtrl = false; + + doc.body + .addEventListener(eventName, e => { + + // focus on button + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'focus') { + let buttonTag = e.target; + let accordionContainer = buttonTag.parentNode; + let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + + unSelectHeaders($accordionAllHeaders); + + selectHeader(buttonTag); + + } + + // click on button + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'click') { + let buttonTag = e.target; + let accordionContainer = buttonTag.parentNode; + let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + let accordionMultiSelectable = accordionContainer.getAttribute(ATTR_MULTISELECTABLE); + let destination = findById(buttonTag.getAttribute(ATTR_CONTROLS)); + let stateButton = buttonTag.getAttribute(ATTR_EXPANDED); + + // if closed + if (stateButton === 'false') { + buttonTag.setAttribute(ATTR_EXPANDED, true); + destination.removeAttribute(ATTR_HIDDEN); + } else { + buttonTag.setAttribute(ATTR_EXPANDED, false); + destination.setAttribute(ATTR_HIDDEN, true); + } + + if (accordionMultiSelectable === 'false') { + $accordionAllHeaders + .forEach((header_node) => { + + let destinationPanel = findById(header_node.getAttribute(ATTR_CONTROLS)); + + if (header_node !== buttonTag) { + header_node.setAttribute(ATTR_SELECTED, false); + header_node.setAttribute(ATTR_EXPANDED, false); + destinationPanel.setAttribute(ATTR_HIDDEN, true); + } else { + header_node.setAttribute(ATTR_SELECTED, true); + } + }); + + } + + setTimeout(function() { + buttonTag.focus(); + }, 0); + e.preventDefault(); + + } + + // keyboard management for headers + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'keydown') { + let buttonTag = e.target; + let accordionContainer = buttonTag.parentNode; + let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + + // strike home on a tab => 1st tab + if (e.keyCode === 36) { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function() { + $accordionAllHeaders[0].focus(); + }, 0); + e.preventDefault(); + } + // strike end on the tab => last tab + else if (e.keyCode === 35) { unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[ $accordionAllHeaders.length-1 ]); - setTimeout(function(){ $accordionAllHeaders[ $accordionAllHeaders.length-1 ].focus(); }, 0); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function() { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); e.preventDefault(); - } - // strike up or left on the tab => previous tab - else if ( ( e.keyCode == 37 || e.keyCode == 38 ) && !e.ctrlKey ) { - + } + // strike up or left on the tab => previous tab + else if ((e.keyCode === 37 || e.keyCode === 38) && !e.ctrlKey) { + // if first selected = select last //if ( $accordionAllHeaders[ $accordionAllHeaders.length-1 ].getAttribute( ATTR_SELECTED ) === 'true' ) { - if ( $accordionAllHeaders[ 0 ].getAttribute( ATTR_SELECTED ) === 'true' ) { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[ $accordionAllHeaders.length-1 ]); - setTimeout(function(){ $accordionAllHeaders[ $accordionAllHeaders.length-1 ].focus(); }, 0); - e.preventDefault(); - } - else { - selectHeaderInList( $accordionAllHeaders, 'prev' ); - e.preventDefault(); - } - + if ($accordionAllHeaders[0].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function() { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); + e.preventDefault(); + } else { + selectHeaderInList($accordionAllHeaders, 'prev'); + e.preventDefault(); } - // strike down or right in the tab => next tab - else if ( ( e.keyCode == 40 || e.keyCode == 39 ) && !e.ctrlKey ) { - - // if last selected = select first - if ( $accordionAllHeaders[ $accordionAllHeaders.length-1 ].getAttribute( ATTR_SELECTED ) === 'true' ) { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function(){ $accordionAllHeaders[0].focus(); }, 0); - e.preventDefault(); - } - else { - selectHeaderInList( $accordionAllHeaders, 'next' ); - e.preventDefault(); - } + } + // strike down or right in the tab => next tab + else if ((e.keyCode === 40 || e.keyCode === 39) && !e.ctrlKey) { + + // if last selected = select first + if ($accordionAllHeaders[$accordionAllHeaders.length - 1].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function() { + $accordionAllHeaders[0].focus(); + }, 0); + e.preventDefault(); + } else { + selectHeaderInList($accordionAllHeaders, 'next'); + e.preventDefault(); } + + } } - - - // keyboard management for panels - let id_panel = searchParent ( e.target, ACCORDION_JS_PANEL ); - if ( id_panel !== '' && eventName === 'keydown' ) { - //console.log('yes in pabnelk' + e.keyCode); - let panelTag = findById( id_panel ); - let accordionContainer = panelTag.parentNode; - let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - let buttonTag = findById(panelTag.getAttribute( ATTR_LABELLEDBY )); - - // strike up + ctrl => go to header - if ( e.keyCode == 38 && e.ctrlKey ) { - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - setTimeout(function(){ buttonTag.focus(); }, 0); - e.preventDefault(); + + + // keyboard management for panels + let id_panel = searchParent(e.target, ACCORDION_JS_PANEL); + if (id_panel !== '' && eventName === 'keydown') { + + let panelTag = findById(id_panel); + let accordionContainer = panelTag.parentNode; + let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + let buttonTag = findById(panelTag.getAttribute(ATTR_LABELLEDBY)); + + // strike up + ctrl => go to header + if (e.keyCode === 38 && e.ctrlKey) { + unSelectHeaders($accordionAllHeaders); + selectHeader(buttonTag); + setTimeout(function() { + buttonTag.focus(); + }, 0); + e.preventDefault(); } - // strike pageup + ctrl => go to prev header - if ( e.keyCode == 33 && e.ctrlKey ) { - // go to header - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - buttonTag.focus(); - e.preventDefault(); - // then previous - if ( $accordionAllHeaders[ 0 ].getAttribute( ATTR_SELECTED ) === 'true' ) { + // strike pageup + ctrl => go to prev header + if (e.keyCode === 33 && e.ctrlKey) { + // go to header unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[ $accordionAllHeaders.length-1 ]); - setTimeout(function(){ $accordionAllHeaders[ $accordionAllHeaders.length-1 ].focus(); }, 0); - } - else { - selectHeaderInList( $accordionAllHeaders, 'prev' ); - } - + selectHeader(buttonTag); + buttonTag.focus(); + e.preventDefault(); + // then previous + if ($accordionAllHeaders[0].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function() { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); + } else { + selectHeaderInList($accordionAllHeaders, 'prev'); + } + } - // strike pagedown + ctrl => go to next header - if ( e.keyCode == 34 && e.ctrlKey ) { - // go to header - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - buttonTag.focus(); - e.preventDefault(); - // then next - if ( $accordionAllHeaders[ $accordionAllHeaders.length-1 ].getAttribute( ATTR_SELECTED ) === 'true' ) { + // strike pagedown + ctrl => go to next header + if (e.keyCode === 34 && e.ctrlKey) { + // go to header unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function(){ $accordionAllHeaders[0].focus(); }, 0); - } - else { - selectHeaderInList( $accordionAllHeaders, 'next' ); - } - + selectHeader(buttonTag); + buttonTag.focus(); + e.preventDefault(); + // then next + if ($accordionAllHeaders[$accordionAllHeaders.length - 1].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function() { + $accordionAllHeaders[0].focus(); + }, 0); + } else { + selectHeaderInList($accordionAllHeaders, 'next'); + } + } - - } - }, true); - }); - document.removeEventListener('DOMContentLoaded', onLoad); - } + } + + }, true); + }); + document.removeEventListener('DOMContentLoaded', onLoad); + } - document.addEventListener('DOMContentLoaded', onLoad); + document.addEventListener('DOMContentLoaded', onLoad); -})(document); +})(document); \ No newline at end of file diff --git a/dist/van11y-accessible-accordion-aria.js b/dist/van11y-accessible-accordion-aria.js index a44c402..90183fe 100644 --- a/dist/van11y-accessible-accordion-aria.js +++ b/dist/van11y-accessible-accordion-aria.js @@ -7,391 +7,391 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } -;(function (doc) { - - 'use strict'; - - var ACCORDION_JS = 'js-accordion'; - var ACCORDION_JS_HEADER = 'js-accordion__header'; - var ACCORDION_JS_PANEL = 'js-accordion__panel'; - - var ACCORDION_DATA_PREFIX_CLASS = 'data-accordion-prefix-classes'; - var ACCORDION_DATA_OPENED = 'data-accordion-opened'; - var ACCORDION_DATA_MULTISELECTABLE = 'data-accordion-multiselectable'; - - var ACCORDION_PREFIX_IDS = 'accordion'; - var ACCORDION_BUTTON_ID = '_tab'; - var ACCORDION_PANEL_ID = '_panel'; - - var ACCORDION_STYLE = 'accordion'; - var ACCORDION_TITLE_STYLE = 'accordion__title'; - var ACCORDION_HEADER_STYLE = 'accordion__header'; - var ACCORDION_PANEL_STYLE = 'accordion__panel'; - - var ACCORDION_ROLE_TABLIST = 'tablist'; - var ACCORDION_ROLE_TAB = 'tab'; - var ACCORDION_ROLE_TABPANEL = 'tabpanel'; - - var ATTR_ROLE = 'role'; - var ATTR_MULTISELECTABLE = 'aria-multiselectable'; - var ATTR_EXPANDED = 'aria-expanded'; - var ATTR_LABELLEDBY = 'aria-labelledby'; - var ATTR_HIDDEN = 'aria-hidden'; - var ATTR_CONTROLS = 'aria-controls'; - var ATTR_SELECTED = 'aria-selected'; - - var IS_OPENED_CLASS = 'is-opened'; - - var findById = function findById(id) { - return doc.getElementById(id); - }; - - var addClass = function addClass(el, className) { - if (el.classList) { - el.classList.add(className); // IE 10+ - } else { - el.className += ' ' + className; // IE 8+ - } - }; - - var removeClass = function removeClass(el, className) { - if (el.classList) { - el.classList.remove(className); // IE 10+ - } else { - el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); // IE 8+ - } - }; - - var hasClass = function hasClass(el, className) { - if (el.classList) { - return el.classList.contains(className); // IE 10+ - } else { - return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); // IE 8+ ? - } - }; - - var setAttributes = function setAttributes(node, attrs) { - Object.keys(attrs).forEach(function (attribute) { - node.setAttribute(attribute, attrs[attribute]); - }); - }; - /* const triggerEvent = (el, event_type) => { - if (el.fireEvent) { - el.fireEvent('on' + event_type); - } - else { - let evObj = document.createEvent('Events'); - evObj.initEvent(event_type, true, false); - el.dispatchEvent(evObj); - } - }*/ - var unSelectHeaders = function unSelectHeaders(elts) { - elts.forEach(function (header_node, index) { - var _setAttributes; - - setAttributes(header_node, (_setAttributes = {}, _defineProperty(_setAttributes, ATTR_SELECTED, 'false'), _defineProperty(_setAttributes, 'tabindex', '-1'), _setAttributes)); - }); - }; - - var selectHeader = function selectHeader(el) { - el.setAttribute(ATTR_SELECTED, true); - el.removeAttribute('tabindex'); - }; - - var selectHeaderInList = function selectHeaderInList(elts, param) { - var indice_trouve = undefined; - elts.forEach(function (header_node, index) { - - if (header_node.getAttribute(ATTR_SELECTED) === 'true') { - indice_trouve = index; - } - }); - if (param === 'next') { - selectHeader(elts[indice_trouve + 1]); - setTimeout(function () { - elts[indice_trouve + 1].focus(); - }, 0); - } - if (param === 'prev') { - selectHeader(elts[indice_trouve - 1]); - setTimeout(function () { - elts[indice_trouve - 1].focus(); - }, 0); - } - }; - - /* gets an element el, search if it is child of parent class, returns id of the parent */ - var searchParent = function searchParent(el, parentClass) { - var found = false; - var parentElement = el.parentNode; - while (parentElement && found === false) { - if (hasClass(parentElement, parentClass) === true) { - found = true; - } else { - parentElement = parentElement.parentNode; - } - } - if (found === true) { - return parentElement.getAttribute('id'); - } else { - return ''; - } - }; - - // Find all accordions - var $listAccordions = function $listAccordions() { - return [].slice.call(doc.querySelectorAll('.' + ACCORDION_JS)); - }; - - var onLoad = function onLoad() { - - $listAccordions().forEach(function (accordion_node, index) { - - var iLisible = index + 1; - var prefixClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) + '-' : ''; - var accordionClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) : ''; - var multiSelectableAttribute = accordion_node.hasAttribute(ACCORDION_DATA_MULTISELECTABLE) === true ? accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) : ''; - /*let toExpand = node.nextElementSibling; - let expandmoreText = node.innerHTML; - let expandButton = doc.createElement("BUTTON");*/ - - // clear element before adding button to it - //node.innerHTML = ''; - - // Init attributes accordion - if (accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) == 'none') { - accordion_node.setAttribute(ATTR_MULTISELECTABLE, 'false'); - } else { - accordion_node.setAttribute(ATTR_MULTISELECTABLE, 'true'); - } - accordion_node.setAttribute(ATTR_ROLE, ACCORDION_ROLE_TABLIST); - addClass(accordion_node, prefixClassName + ACCORDION_STYLE); - - var $listAccordionsHeader = [].slice.call(accordion_node.querySelectorAll('.' + ACCORDION_JS_HEADER)); - $listAccordionsHeader.forEach(function (header_node, index_header) { - var _setAttributes2, _setAttributes3; - - var indexHeaderLisible = index_header + 1; - var accordionPanel = header_node.nextElementSibling; - var accordionHeaderText = header_node.innerHTML; - var accordionButton = document.createElement("BUTTON"); - var accordionOpenedAttribute = header_node.hasAttribute(ACCORDION_DATA_OPENED) === true ? header_node.getAttribute(ACCORDION_DATA_OPENED) : ''; - - // set button with attributes - accordionButton.innerHTML = accordionHeaderText; - addClass(accordionButton, ACCORDION_JS_HEADER); - addClass(accordionButton, prefixClassName + ACCORDION_HEADER_STYLE); - setAttributes(accordionButton, (_setAttributes2 = {}, _defineProperty(_setAttributes2, ATTR_ROLE, ACCORDION_ROLE_TAB), _defineProperty(_setAttributes2, 'id', ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible), _defineProperty(_setAttributes2, ATTR_CONTROLS, ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible), _defineProperty(_setAttributes2, ATTR_SELECTED, 'false'), _defineProperty(_setAttributes2, 'tabindex', '-1'), _defineProperty(_setAttributes2, 'type', 'button'), _setAttributes2)); - - // place button - accordionButton = accordion_node.insertBefore(accordionButton, header_node); - - // move title into panel - accordionPanel.insertBefore(header_node, accordionPanel.firstChild); - // set title with attributes - addClass(header_node, prefixClassName + ACCORDION_TITLE_STYLE); - removeClass(header_node, ACCORDION_JS_HEADER); - - // set attributes to panels - addClass(accordionPanel, prefixClassName + ACCORDION_PANEL_STYLE); - setAttributes(accordionPanel, (_setAttributes3 = {}, _defineProperty(_setAttributes3, ATTR_ROLE, ACCORDION_ROLE_TABPANEL), _defineProperty(_setAttributes3, ATTR_LABELLEDBY, ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible), _defineProperty(_setAttributes3, 'id', ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible), _setAttributes3)); - - if (accordionOpenedAttribute === 'true') { - accordionButton.setAttribute(ATTR_EXPANDED, 'true'); - header_node.removeAttribute(ACCORDION_DATA_OPENED); - accordionPanel.setAttribute(ATTR_HIDDEN, 'false'); - } else { - accordionButton.setAttribute(ATTR_EXPANDED, 'false'); - accordionPanel.setAttribute(ATTR_HIDDEN, 'true'); - } +(function (doc) { - // init first one focusable - if (indexHeaderLisible === 1) { - accordionButton.removeAttribute('tabindex'); - } - }); - }); + 'use strict'; - // click on - ['click', 'keydown', 'focus'].forEach(function (eventName) { - var isCtrl = false; + var ACCORDION_JS = 'js-accordion'; + var ACCORDION_JS_HEADER = 'js-accordion__header'; + var ACCORDION_JS_PANEL = 'js-accordion__panel'; - doc.body.addEventListener(eventName, function (e) { + var ACCORDION_DATA_PREFIX_CLASS = 'data-accordion-prefix-classes'; + var ACCORDION_DATA_OPENED = 'data-accordion-opened'; + var ACCORDION_DATA_MULTISELECTABLE = 'data-accordion-multiselectable'; - // focus on button - if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'focus') { - var buttonTag = e.target; - var accordionContainer = buttonTag.parentNode; - var $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + var ACCORDION_PREFIX_IDS = 'accordion'; + var ACCORDION_BUTTON_ID = '_tab'; + var ACCORDION_PANEL_ID = '_panel'; - unSelectHeaders($accordionAllHeaders); + var ACCORDION_STYLE = 'accordion'; + var ACCORDION_TITLE_STYLE = 'accordion__title'; + var ACCORDION_HEADER_STYLE = 'accordion__header'; + var ACCORDION_PANEL_STYLE = 'accordion__panel'; - selectHeader(buttonTag); - } + var ACCORDION_ROLE_TABLIST = 'tablist'; + var ACCORDION_ROLE_TAB = 'tab'; + var ACCORDION_ROLE_TABPANEL = 'tabpanel'; - // click on button - if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'click') { - (function () { - var buttonTag = e.target; - var accordionContainer = buttonTag.parentNode; - var $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - var accordionMultiSelectable = accordionContainer.getAttribute(ATTR_MULTISELECTABLE); - var destination = findById(buttonTag.getAttribute(ATTR_CONTROLS)); - var stateButton = buttonTag.getAttribute(ATTR_EXPANDED); - - // if closed - if (stateButton === 'false') { - buttonTag.setAttribute(ATTR_EXPANDED, true); - destination.removeAttribute(ATTR_HIDDEN); - } else { - buttonTag.setAttribute(ATTR_EXPANDED, false); - destination.setAttribute(ATTR_HIDDEN, true); - } + var ATTR_ROLE = 'role'; + var ATTR_MULTISELECTABLE = 'aria-multiselectable'; + var ATTR_EXPANDED = 'aria-expanded'; + var ATTR_LABELLEDBY = 'aria-labelledby'; + var ATTR_HIDDEN = 'aria-hidden'; + var ATTR_CONTROLS = 'aria-controls'; + var ATTR_SELECTED = 'aria-selected'; - if (accordionMultiSelectable === 'false') { - $accordionAllHeaders.forEach(function (header_node, index) { + //const IS_OPENED_CLASS = 'is-opened'; - var destinationPanel = findById(header_node.getAttribute(ATTR_CONTROLS)); + var findById = function findById(id) { + return doc.getElementById(id); + }; - if (header_node !== buttonTag) { - header_node.setAttribute(ATTR_SELECTED, false); - header_node.setAttribute(ATTR_EXPANDED, false); - destinationPanel.setAttribute(ATTR_HIDDEN, true); - } else { - header_node.setAttribute(ATTR_SELECTED, true); - } - }); + var addClass = function addClass(el, className) { + if (el.classList) { + el.classList.add(className); // IE 10+ + } else { + el.className += ' ' + className; // IE 8+ + } + }; + + var removeClass = function removeClass(el, className) { + if (el.classList) { + el.classList.remove(className); // IE 10+ + } else { + el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); // IE 8+ } + }; + var hasClass = function hasClass(el, className) { + if (el.classList) { + return el.classList.contains(className); // IE 10+ + } else { + return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); // IE 8+ ? + } + }; + + var setAttributes = function setAttributes(node, attrs) { + Object.keys(attrs).forEach(function (attribute) { + node.setAttribute(attribute, attrs[attribute]); + }); + }; + /* const triggerEvent = (el, event_type) => { + if (el.fireEvent) { + el.fireEvent('on' + event_type); + } + else { + let evObj = document.createEvent('Events'); + evObj.initEvent(event_type, true, false); + el.dispatchEvent(evObj); + } + }*/ + var unSelectHeaders = function unSelectHeaders(elts) { + elts.forEach(function (header_node) { + var _setAttributes; + + setAttributes(header_node, (_setAttributes = {}, _defineProperty(_setAttributes, ATTR_SELECTED, 'false'), _defineProperty(_setAttributes, 'tabindex', '-1'), _setAttributes)); + }); + }; + + var selectHeader = function selectHeader(el) { + el.setAttribute(ATTR_SELECTED, true); + el.removeAttribute('tabindex'); + }; + + var selectHeaderInList = function selectHeaderInList(elts, param) { + var indice_trouve = undefined; + elts.forEach(function (header_node, index) { + + if (header_node.getAttribute(ATTR_SELECTED) === 'true') { + indice_trouve = index; + } + }); + if (param === 'next') { + selectHeader(elts[indice_trouve + 1]); + setTimeout(function () { + elts[indice_trouve + 1].focus(); + }, 0); + } + if (param === 'prev') { + selectHeader(elts[indice_trouve - 1]); setTimeout(function () { - buttonTag.focus(); + elts[indice_trouve - 1].focus(); }, 0); - e.preventDefault(); - })(); } + }; + + /* gets an element el, search if it is child of parent class, returns id of the parent */ + var searchParent = function searchParent(el, parentClass) { + var found = false; + var parentElement = el.parentNode; + while (parentElement && found === false) { + if (hasClass(parentElement, parentClass) === true) { + found = true; + } else { + parentElement = parentElement.parentNode; + } + } + if (found === true) { + return parentElement.getAttribute('id'); + } else { + return ''; + } + }; + + // Find all accordions + var $listAccordions = function $listAccordions() { + return [].slice.call(doc.querySelectorAll('.' + ACCORDION_JS)); + }; - // keyboard management for headers - if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'keydown') { - (function () { - var buttonTag = e.target; - var accordionContainer = buttonTag.parentNode; - var $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - - // strike home on a tab => 1st tab - if (e.keyCode === 36) { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function () { - $accordionAllHeaders[0].focus(); - }, 0); - e.preventDefault(); + var onLoad = function onLoad() { + + $listAccordions().forEach(function (accordion_node, index) { + + var iLisible = index + 1; + var prefixClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) + '-' : ''; + //let accordionClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) : '' ; + //let multiSelectableAttribute = accordion_node.hasAttribute(ACCORDION_DATA_MULTISELECTABLE) === true ? accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) : '' ; + /*let toExpand = node.nextElementSibling; + let expandmoreText = node.innerHTML; + let expandButton = doc.createElement("BUTTON");*/ + + // clear element before adding button to it + //node.innerHTML = ''; + + // Init attributes accordion + if (accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) === 'none') { + accordion_node.setAttribute(ATTR_MULTISELECTABLE, 'false'); + } else { + accordion_node.setAttribute(ATTR_MULTISELECTABLE, 'true'); } - // strike end on the tab => last tab - else if (e.keyCode == 35) { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); - setTimeout(function () { - $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); - }, 0); - e.preventDefault(); - } - // strike up or left on the tab => previous tab - else if ((e.keyCode == 37 || e.keyCode == 38) && !e.ctrlKey) { - - // if first selected = select last - //if ( $accordionAllHeaders[ $accordionAllHeaders.length-1 ].getAttribute( ATTR_SELECTED ) === 'true' ) { - if ($accordionAllHeaders[0].getAttribute(ATTR_SELECTED) === 'true') { + accordion_node.setAttribute(ATTR_ROLE, ACCORDION_ROLE_TABLIST); + addClass(accordion_node, prefixClassName + ACCORDION_STYLE); + + var $listAccordionsHeader = [].slice.call(accordion_node.querySelectorAll('.' + ACCORDION_JS_HEADER)); + $listAccordionsHeader.forEach(function (header_node, index_header) { + var _setAttributes2, _setAttributes3; + + var indexHeaderLisible = index_header + 1; + var accordionPanel = header_node.nextElementSibling; + var accordionHeaderText = header_node.innerHTML; + var accordionButton = document.createElement("BUTTON"); + var accordionOpenedAttribute = header_node.hasAttribute(ACCORDION_DATA_OPENED) === true ? header_node.getAttribute(ACCORDION_DATA_OPENED) : ''; + + // set button with attributes + accordionButton.innerHTML = accordionHeaderText; + addClass(accordionButton, ACCORDION_JS_HEADER); + addClass(accordionButton, prefixClassName + ACCORDION_HEADER_STYLE); + setAttributes(accordionButton, (_setAttributes2 = {}, _defineProperty(_setAttributes2, ATTR_ROLE, ACCORDION_ROLE_TAB), _defineProperty(_setAttributes2, 'id', ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible), _defineProperty(_setAttributes2, ATTR_CONTROLS, ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible), _defineProperty(_setAttributes2, ATTR_SELECTED, 'false'), _defineProperty(_setAttributes2, 'tabindex', '-1'), _defineProperty(_setAttributes2, 'type', 'button'), _setAttributes2)); + + // place button + accordionButton = accordion_node.insertBefore(accordionButton, header_node); + + // move title into panel + accordionPanel.insertBefore(header_node, accordionPanel.firstChild); + // set title with attributes + addClass(header_node, prefixClassName + ACCORDION_TITLE_STYLE); + removeClass(header_node, ACCORDION_JS_HEADER); + + // set attributes to panels + addClass(accordionPanel, prefixClassName + ACCORDION_PANEL_STYLE); + setAttributes(accordionPanel, (_setAttributes3 = {}, _defineProperty(_setAttributes3, ATTR_ROLE, ACCORDION_ROLE_TABPANEL), _defineProperty(_setAttributes3, ATTR_LABELLEDBY, ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible), _defineProperty(_setAttributes3, 'id', ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible), _setAttributes3)); + + if (accordionOpenedAttribute === 'true') { + accordionButton.setAttribute(ATTR_EXPANDED, 'true'); + header_node.removeAttribute(ACCORDION_DATA_OPENED); + accordionPanel.setAttribute(ATTR_HIDDEN, 'false'); + } else { + accordionButton.setAttribute(ATTR_EXPANDED, 'false'); + accordionPanel.setAttribute(ATTR_HIDDEN, 'true'); + } + + // init first one focusable + if (indexHeaderLisible === 1) { + accordionButton.removeAttribute('tabindex'); + } + }); + }); + + // click on + ['click', 'keydown', 'focus'].forEach(function (eventName) { + //let isCtrl = false; + + doc.body.addEventListener(eventName, function (e) { + + // focus on button + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'focus') { + var buttonTag = e.target; + var accordionContainer = buttonTag.parentNode; + var $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); - setTimeout(function () { - $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); - }, 0); - e.preventDefault(); - } else { - selectHeaderInList($accordionAllHeaders, 'prev'); - e.preventDefault(); - } + + selectHeader(buttonTag); } - // strike down or right in the tab => next tab - else if ((e.keyCode == 40 || e.keyCode == 39) && !e.ctrlKey) { - - // if last selected = select first - if ($accordionAllHeaders[$accordionAllHeaders.length - 1].getAttribute(ATTR_SELECTED) === 'true') { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function () { - $accordionAllHeaders[0].focus(); - }, 0); - e.preventDefault(); - } else { - selectHeaderInList($accordionAllHeaders, 'next'); - e.preventDefault(); - } - } - })(); - } - // keyboard management for panels - var id_panel = searchParent(e.target, ACCORDION_JS_PANEL); - if (id_panel !== '' && eventName === 'keydown') { - (function () { - //console.log('yes in pabnelk' + e.keyCode); - var panelTag = findById(id_panel); - var accordionContainer = panelTag.parentNode; - var $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - var buttonTag = findById(panelTag.getAttribute(ATTR_LABELLEDBY)); - - // strike up + ctrl => go to header - if (e.keyCode == 38 && e.ctrlKey) { - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - setTimeout(function () { - buttonTag.focus(); - }, 0); - e.preventDefault(); - } - // strike pageup + ctrl => go to prev header - if (e.keyCode == 33 && e.ctrlKey) { - // go to header - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - buttonTag.focus(); - e.preventDefault(); - // then previous - if ($accordionAllHeaders[0].getAttribute(ATTR_SELECTED) === 'true') { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); - setTimeout(function () { - $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); - }, 0); - } else { - selectHeaderInList($accordionAllHeaders, 'prev'); - } - } - // strike pagedown + ctrl => go to next header - if (e.keyCode == 34 && e.ctrlKey) { - // go to header - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - buttonTag.focus(); - e.preventDefault(); - // then next - if ($accordionAllHeaders[$accordionAllHeaders.length - 1].getAttribute(ATTR_SELECTED) === 'true') { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function () { - $accordionAllHeaders[0].focus(); - }, 0); - } else { - selectHeaderInList($accordionAllHeaders, 'next'); - } - } - })(); - } - }, true); - }); - document.removeEventListener('DOMContentLoaded', onLoad); - }; + // click on button + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'click') { + (function () { + var buttonTag = e.target; + var accordionContainer = buttonTag.parentNode; + var $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + var accordionMultiSelectable = accordionContainer.getAttribute(ATTR_MULTISELECTABLE); + var destination = findById(buttonTag.getAttribute(ATTR_CONTROLS)); + var stateButton = buttonTag.getAttribute(ATTR_EXPANDED); + + // if closed + if (stateButton === 'false') { + buttonTag.setAttribute(ATTR_EXPANDED, true); + destination.removeAttribute(ATTR_HIDDEN); + } else { + buttonTag.setAttribute(ATTR_EXPANDED, false); + destination.setAttribute(ATTR_HIDDEN, true); + } + + if (accordionMultiSelectable === 'false') { + $accordionAllHeaders.forEach(function (header_node) { + + var destinationPanel = findById(header_node.getAttribute(ATTR_CONTROLS)); + + if (header_node !== buttonTag) { + header_node.setAttribute(ATTR_SELECTED, false); + header_node.setAttribute(ATTR_EXPANDED, false); + destinationPanel.setAttribute(ATTR_HIDDEN, true); + } else { + header_node.setAttribute(ATTR_SELECTED, true); + } + }); + } + + setTimeout(function () { + buttonTag.focus(); + }, 0); + e.preventDefault(); + })(); + } + + // keyboard management for headers + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'keydown') { + (function () { + var buttonTag = e.target; + var accordionContainer = buttonTag.parentNode; + var $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + + // strike home on a tab => 1st tab + if (e.keyCode === 36) { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function () { + $accordionAllHeaders[0].focus(); + }, 0); + e.preventDefault(); + } + // strike end on the tab => last tab + else if (e.keyCode === 35) { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function () { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); + e.preventDefault(); + } + // strike up or left on the tab => previous tab + else if ((e.keyCode === 37 || e.keyCode === 38) && !e.ctrlKey) { + + // if first selected = select last + //if ( $accordionAllHeaders[ $accordionAllHeaders.length-1 ].getAttribute( ATTR_SELECTED ) === 'true' ) { + if ($accordionAllHeaders[0].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function () { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); + e.preventDefault(); + } else { + selectHeaderInList($accordionAllHeaders, 'prev'); + e.preventDefault(); + } + } + // strike down or right in the tab => next tab + else if ((e.keyCode === 40 || e.keyCode === 39) && !e.ctrlKey) { + + // if last selected = select first + if ($accordionAllHeaders[$accordionAllHeaders.length - 1].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function () { + $accordionAllHeaders[0].focus(); + }, 0); + e.preventDefault(); + } else { + selectHeaderInList($accordionAllHeaders, 'next'); + e.preventDefault(); + } + } + })(); + } + + // keyboard management for panels + var id_panel = searchParent(e.target, ACCORDION_JS_PANEL); + if (id_panel !== '' && eventName === 'keydown') { + (function () { + + var panelTag = findById(id_panel); + var accordionContainer = panelTag.parentNode; + var $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + var buttonTag = findById(panelTag.getAttribute(ATTR_LABELLEDBY)); + + // strike up + ctrl => go to header + if (e.keyCode === 38 && e.ctrlKey) { + unSelectHeaders($accordionAllHeaders); + selectHeader(buttonTag); + setTimeout(function () { + buttonTag.focus(); + }, 0); + e.preventDefault(); + } + // strike pageup + ctrl => go to prev header + if (e.keyCode === 33 && e.ctrlKey) { + // go to header + unSelectHeaders($accordionAllHeaders); + selectHeader(buttonTag); + buttonTag.focus(); + e.preventDefault(); + // then previous + if ($accordionAllHeaders[0].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function () { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); + } else { + selectHeaderInList($accordionAllHeaders, 'prev'); + } + } + // strike pagedown + ctrl => go to next header + if (e.keyCode === 34 && e.ctrlKey) { + // go to header + unSelectHeaders($accordionAllHeaders); + selectHeader(buttonTag); + buttonTag.focus(); + e.preventDefault(); + // then next + if ($accordionAllHeaders[$accordionAllHeaders.length - 1].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function () { + $accordionAllHeaders[0].focus(); + }, 0); + } else { + selectHeaderInList($accordionAllHeaders, 'next'); + } + } + })(); + } + }, true); + }); + document.removeEventListener('DOMContentLoaded', onLoad); + }; - document.addEventListener('DOMContentLoaded', onLoad); + document.addEventListener('DOMContentLoaded', onLoad); })(document); \ No newline at end of file diff --git a/dist/van11y-accessible-accordion-aria.min.js b/dist/van11y-accessible-accordion-aria.min.js index 185ae3b..671cd72 100644 --- a/dist/van11y-accessible-accordion-aria.min.js +++ b/dist/van11y-accessible-accordion-aria.min.js @@ -1,7 +1,7 @@ /** * van11y-accessible-accordion-aria - ES2015 accessible accordion system, using ARIA (compatible IE9+ when transpiled) - * @version v1.0.4 + * @version v1.0.5 * @link https://van11y.net/accessible-accordion/ * @license MIT : https://github.com/nico3333fr/van11y-accessible-accordion-aria/blob/master/LICENSE */ -"use strict";function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}!function(e){var t="js-accordion",r="js-accordion__header",n="js-accordion__panel",i="data-accordion-prefix-classes",o="data-accordion-opened",u="data-accordion-multiselectable",a="accordion",c="_tab",l="_panel",s="accordion",f="accordion__title",d="accordion__header",b="accordion__panel",A="tablist",p="tab",y="tabpanel",g="role",v="aria-multiselectable",m="aria-expanded",_="aria-labelledby",h="aria-hidden",k="aria-controls",E="aria-selected",T=function(t){return e.getElementById(t)},L=function(e,t){e.classList?e.classList.add(t):e.className+=" "+t},P=function(e,t){e.classList?e.classList.remove(t):e.className=e.className.replace(new RegExp("(^|\\b)"+t.split(" ").join("|")+"(\\b|$)","gi")," ")},x=function(e,t){return e.classList?e.classList.contains(t):new RegExp("(^| )"+t+"( |$)","gi").test(e.className)},C=function(e,t){Object.keys(t).forEach(function(r){e.setAttribute(r,t[r])})},D=function(e){e.forEach(function(e,t){var r;C(e,(r={},_defineProperty(r,E,"false"),_defineProperty(r,"tabindex","-1"),r))})},N=function(e){e.setAttribute(E,!0),e.removeAttribute("tabindex")},S=function(e,t){var r=void 0;e.forEach(function(e,t){"true"===e.getAttribute(E)&&(r=t)}),"next"===t&&(N(e[r+1]),setTimeout(function(){e[r+1].focus()},0)),"prev"===t&&(N(e[r-1]),setTimeout(function(){e[r-1].focus()},0))},j=function(e,t){for(var r=!1,n=e.parentNode;n&&r===!1;)x(n,t)===!0?r=!0:n=n.parentNode;return r===!0?n.getAttribute("id"):""},q=function(){return[].slice.call(e.querySelectorAll("."+t))},w=function K(){q().forEach(function(e,t){var n=t+1,T=e.hasAttribute(i)===!0?e.getAttribute(i)+"-":"";e.hasAttribute(i)===!0?e.getAttribute(i):"",e.hasAttribute(u)===!0?e.getAttribute(u):"";"none"==e.getAttribute(u)?e.setAttribute(v,"false"):e.setAttribute(v,"true"),e.setAttribute(g,A),L(e,T+s);var x=[].slice.call(e.querySelectorAll("."+r));x.forEach(function(t,i){var u,s,A=i+1,v=t.nextElementSibling,x=t.innerHTML,D=document.createElement("BUTTON"),N=t.hasAttribute(o)===!0?t.getAttribute(o):"";D.innerHTML=x,L(D,r),L(D,T+d),C(D,(u={},_defineProperty(u,g,p),_defineProperty(u,"id",a+n+c+A),_defineProperty(u,k,a+n+l+A),_defineProperty(u,E,"false"),_defineProperty(u,"tabindex","-1"),_defineProperty(u,"type","button"),u)),D=e.insertBefore(D,t),v.insertBefore(t,v.firstChild),L(t,T+f),P(t,r),L(v,T+b),C(v,(s={},_defineProperty(s,g,y),_defineProperty(s,_,a+n+c+A),_defineProperty(s,"id",a+n+l+A),s)),"true"===N?(D.setAttribute(m,"true"),t.removeAttribute(o),v.setAttribute(h,"false")):(D.setAttribute(m,"false"),v.setAttribute(h,"true")),1===A&&D.removeAttribute("tabindex")})}),["click","keydown","focus"].forEach(function(t){e.body.addEventListener(t,function(e){if(x(e.target,r)===!0&&"focus"===t){var i=e.target,o=i.parentNode,u=[].slice.call(o.querySelectorAll("."+r));D(u),N(i)}x(e.target,r)===!0&&"click"===t&&!function(){var t=e.target,n=t.parentNode,i=[].slice.call(n.querySelectorAll("."+r)),o=n.getAttribute(v),u=T(t.getAttribute(k)),a=t.getAttribute(m);"false"===a?(t.setAttribute(m,!0),u.removeAttribute(h)):(t.setAttribute(m,!1),u.setAttribute(h,!0)),"false"===o&&i.forEach(function(e,r){var n=T(e.getAttribute(k));e!==t?(e.setAttribute(E,!1),e.setAttribute(m,!1),n.setAttribute(h,!0)):e.setAttribute(E,!0)}),setTimeout(function(){t.focus()},0),e.preventDefault()}(),x(e.target,r)===!0&&"keydown"===t&&!function(){var t=e.target,n=t.parentNode,i=[].slice.call(n.querySelectorAll("."+r));36===e.keyCode?(D(i),N(i[0]),setTimeout(function(){i[0].focus()},0),e.preventDefault()):35==e.keyCode?(D(i),N(i[i.length-1]),setTimeout(function(){i[i.length-1].focus()},0),e.preventDefault()):37!=e.keyCode&&38!=e.keyCode||e.ctrlKey?40!=e.keyCode&&39!=e.keyCode||e.ctrlKey||("true"===i[i.length-1].getAttribute(E)?(D(i),N(i[0]),setTimeout(function(){i[0].focus()},0),e.preventDefault()):(S(i,"next"),e.preventDefault())):"true"===i[0].getAttribute(E)?(D(i),N(i[i.length-1]),setTimeout(function(){i[i.length-1].focus()},0),e.preventDefault()):(S(i,"prev"),e.preventDefault())}();var a=j(e.target,n);""!==a&&"keydown"===t&&!function(){var t=T(a),n=t.parentNode,i=[].slice.call(n.querySelectorAll("."+r)),o=T(t.getAttribute(_));38==e.keyCode&&e.ctrlKey&&(D(i),N(o),setTimeout(function(){o.focus()},0),e.preventDefault()),33==e.keyCode&&e.ctrlKey&&(D(i),N(o),o.focus(),e.preventDefault(),"true"===i[0].getAttribute(E)?(D(i),N(i[i.length-1]),setTimeout(function(){i[i.length-1].focus()},0)):S(i,"prev")),34==e.keyCode&&e.ctrlKey&&(D(i),N(o),o.focus(),e.preventDefault(),"true"===i[i.length-1].getAttribute(E)?(D(i),N(i[0]),setTimeout(function(){i[0].focus()},0)):S(i,"next"))}()},!0)}),document.removeEventListener("DOMContentLoaded",K)};document.addEventListener("DOMContentLoaded",w)}(document); \ No newline at end of file +"use strict";function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}!function(e){var t="js-accordion",r="js-accordion__header",n="js-accordion__panel",i="data-accordion-prefix-classes",o="data-accordion-opened",u="data-accordion-multiselectable",a="accordion",c="_tab",l="_panel",s="accordion",f="accordion__title",d="accordion__header",b="accordion__panel",p="tablist",A="tab",y="tabpanel",v="role",g="aria-multiselectable",m="aria-expanded",_="aria-labelledby",h="aria-hidden",k="aria-controls",E="aria-selected",T=function(t){return e.getElementById(t)},L=function(e,t){e.classList?e.classList.add(t):e.className+=" "+t},P=function(e,t){e.classList?e.classList.remove(t):e.className=e.className.replace(new RegExp("(^|\\b)"+t.split(" ").join("|")+"(\\b|$)","gi")," ")},x=function(e,t){return e.classList?e.classList.contains(t):new RegExp("(^| )"+t+"( |$)","gi").test(e.className)},C=function(e,t){Object.keys(t).forEach(function(r){e.setAttribute(r,t[r])})},D=function(e){e.forEach(function(e){var t;C(e,(t={},_defineProperty(t,E,"false"),_defineProperty(t,"tabindex","-1"),t))})},N=function(e){e.setAttribute(E,!0),e.removeAttribute("tabindex")},S=function(e,t){var r=void 0;e.forEach(function(e,t){"true"===e.getAttribute(E)&&(r=t)}),"next"===t&&(N(e[r+1]),setTimeout(function(){e[r+1].focus()},0)),"prev"===t&&(N(e[r-1]),setTimeout(function(){e[r-1].focus()},0))},j=function(e,t){for(var r=!1,n=e.parentNode;n&&r===!1;)x(n,t)===!0?r=!0:n=n.parentNode;return r===!0?n.getAttribute("id"):""},q=function(){return[].slice.call(e.querySelectorAll("."+t))},w=function K(){q().forEach(function(e,t){var n=t+1,T=e.hasAttribute(i)===!0?e.getAttribute(i)+"-":"";"none"===e.getAttribute(u)?e.setAttribute(g,"false"):e.setAttribute(g,"true"),e.setAttribute(v,p),L(e,T+s);var x=[].slice.call(e.querySelectorAll("."+r));x.forEach(function(t,i){var u,s,p=i+1,g=t.nextElementSibling,x=t.innerHTML,D=document.createElement("BUTTON"),N=t.hasAttribute(o)===!0?t.getAttribute(o):"";D.innerHTML=x,L(D,r),L(D,T+d),C(D,(u={},_defineProperty(u,v,A),_defineProperty(u,"id",a+n+c+p),_defineProperty(u,k,a+n+l+p),_defineProperty(u,E,"false"),_defineProperty(u,"tabindex","-1"),_defineProperty(u,"type","button"),u)),D=e.insertBefore(D,t),g.insertBefore(t,g.firstChild),L(t,T+f),P(t,r),L(g,T+b),C(g,(s={},_defineProperty(s,v,y),_defineProperty(s,_,a+n+c+p),_defineProperty(s,"id",a+n+l+p),s)),"true"===N?(D.setAttribute(m,"true"),t.removeAttribute(o),g.setAttribute(h,"false")):(D.setAttribute(m,"false"),g.setAttribute(h,"true")),1===p&&D.removeAttribute("tabindex")})}),["click","keydown","focus"].forEach(function(t){e.body.addEventListener(t,function(e){if(x(e.target,r)===!0&&"focus"===t){var i=e.target,o=i.parentNode,u=[].slice.call(o.querySelectorAll("."+r));D(u),N(i)}x(e.target,r)===!0&&"click"===t&&!function(){var t=e.target,n=t.parentNode,i=[].slice.call(n.querySelectorAll("."+r)),o=n.getAttribute(g),u=T(t.getAttribute(k)),a=t.getAttribute(m);"false"===a?(t.setAttribute(m,!0),u.removeAttribute(h)):(t.setAttribute(m,!1),u.setAttribute(h,!0)),"false"===o&&i.forEach(function(e){var r=T(e.getAttribute(k));e!==t?(e.setAttribute(E,!1),e.setAttribute(m,!1),r.setAttribute(h,!0)):e.setAttribute(E,!0)}),setTimeout(function(){t.focus()},0),e.preventDefault()}(),x(e.target,r)===!0&&"keydown"===t&&!function(){var t=e.target,n=t.parentNode,i=[].slice.call(n.querySelectorAll("."+r));36===e.keyCode?(D(i),N(i[0]),setTimeout(function(){i[0].focus()},0),e.preventDefault()):35===e.keyCode?(D(i),N(i[i.length-1]),setTimeout(function(){i[i.length-1].focus()},0),e.preventDefault()):37!==e.keyCode&&38!==e.keyCode||e.ctrlKey?40!==e.keyCode&&39!==e.keyCode||e.ctrlKey||("true"===i[i.length-1].getAttribute(E)?(D(i),N(i[0]),setTimeout(function(){i[0].focus()},0),e.preventDefault()):(S(i,"next"),e.preventDefault())):"true"===i[0].getAttribute(E)?(D(i),N(i[i.length-1]),setTimeout(function(){i[i.length-1].focus()},0),e.preventDefault()):(S(i,"prev"),e.preventDefault())}();var a=j(e.target,n);""!==a&&"keydown"===t&&!function(){var t=T(a),n=t.parentNode,i=[].slice.call(n.querySelectorAll("."+r)),o=T(t.getAttribute(_));38===e.keyCode&&e.ctrlKey&&(D(i),N(o),setTimeout(function(){o.focus()},0),e.preventDefault()),33===e.keyCode&&e.ctrlKey&&(D(i),N(o),o.focus(),e.preventDefault(),"true"===i[0].getAttribute(E)?(D(i),N(i[i.length-1]),setTimeout(function(){i[i.length-1].focus()},0)):S(i,"prev")),34===e.keyCode&&e.ctrlKey&&(D(i),N(o),o.focus(),e.preventDefault(),"true"===i[i.length-1].getAttribute(E)?(D(i),N(i[0]),setTimeout(function(){i[0].focus()},0)):S(i,"next"))}()},!0)}),document.removeEventListener("DOMContentLoaded",K)};document.addEventListener("DOMContentLoaded",w)}(document); \ No newline at end of file diff --git a/package.json b/package.json index e126ccf..1a86028 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "van11y-accessible-accordion-aria", "description": "ES2015 accessible accordion system, using ARIA (compatible IE9+ when transpiled)", "main": "dist/van11y-accessible-accordion-aria.min.js", - "version": "1.0.4", + "version": "1.0.5", "keywords": [ "Accessibility", "ARIA", diff --git a/src/van11y-accessible-accordion-aria.es6.js b/src/van11y-accessible-accordion-aria.es6.js index 4bb2e24..ad0659d 100644 --- a/src/van11y-accessible-accordion-aria.es6.js +++ b/src/van11y-accessible-accordion-aria.es6.js @@ -3,415 +3,424 @@ * Website: https://van11y.net/accessible-accordion/ * License MIT: https://github.com/nico3333fr/van11y-accessible-accordion-aria/blob/master/LICENSE */ -;(doc => { - - 'use strict'; - - const ACCORDION_JS = 'js-accordion'; - const ACCORDION_JS_HEADER = 'js-accordion__header'; - const ACCORDION_JS_PANEL = 'js-accordion__panel'; - - const ACCORDION_DATA_PREFIX_CLASS = 'data-accordion-prefix-classes'; - const ACCORDION_DATA_OPENED = 'data-accordion-opened'; - const ACCORDION_DATA_MULTISELECTABLE = 'data-accordion-multiselectable'; - - const ACCORDION_PREFIX_IDS = 'accordion'; - const ACCORDION_BUTTON_ID = '_tab'; - const ACCORDION_PANEL_ID = '_panel'; - - const ACCORDION_STYLE = 'accordion'; - const ACCORDION_TITLE_STYLE = 'accordion__title'; - const ACCORDION_HEADER_STYLE = 'accordion__header'; - const ACCORDION_PANEL_STYLE = 'accordion__panel'; - - const ACCORDION_ROLE_TABLIST = 'tablist'; - const ACCORDION_ROLE_TAB = 'tab'; - const ACCORDION_ROLE_TABPANEL = 'tabpanel'; - - const ATTR_ROLE = 'role'; - const ATTR_MULTISELECTABLE = 'aria-multiselectable'; - const ATTR_EXPANDED = 'aria-expanded'; - const ATTR_LABELLEDBY = 'aria-labelledby'; - const ATTR_HIDDEN = 'aria-hidden'; - const ATTR_CONTROLS = 'aria-controls'; - const ATTR_SELECTED = 'aria-selected'; - - - const IS_OPENED_CLASS = 'is-opened'; - - - - const findById = id => doc.getElementById(id); - - const addClass = (el, className) => { +(doc => { + + 'use strict'; + + const ACCORDION_JS = 'js-accordion'; + const ACCORDION_JS_HEADER = 'js-accordion__header'; + const ACCORDION_JS_PANEL = 'js-accordion__panel'; + + const ACCORDION_DATA_PREFIX_CLASS = 'data-accordion-prefix-classes'; + const ACCORDION_DATA_OPENED = 'data-accordion-opened'; + const ACCORDION_DATA_MULTISELECTABLE = 'data-accordion-multiselectable'; + + const ACCORDION_PREFIX_IDS = 'accordion'; + const ACCORDION_BUTTON_ID = '_tab'; + const ACCORDION_PANEL_ID = '_panel'; + + const ACCORDION_STYLE = 'accordion'; + const ACCORDION_TITLE_STYLE = 'accordion__title'; + const ACCORDION_HEADER_STYLE = 'accordion__header'; + const ACCORDION_PANEL_STYLE = 'accordion__panel'; + + const ACCORDION_ROLE_TABLIST = 'tablist'; + const ACCORDION_ROLE_TAB = 'tab'; + const ACCORDION_ROLE_TABPANEL = 'tabpanel'; + + const ATTR_ROLE = 'role'; + const ATTR_MULTISELECTABLE = 'aria-multiselectable'; + const ATTR_EXPANDED = 'aria-expanded'; + const ATTR_LABELLEDBY = 'aria-labelledby'; + const ATTR_HIDDEN = 'aria-hidden'; + const ATTR_CONTROLS = 'aria-controls'; + const ATTR_SELECTED = 'aria-selected'; + + + //const IS_OPENED_CLASS = 'is-opened'; + + + + const findById = id => doc.getElementById(id); + + const addClass = (el, className) => { if (el.classList) { - el.classList.add(className); // IE 10+ + el.classList.add(className); // IE 10+ + } else { + el.className += ' ' + className; // IE 8+ } - else { - el.className += ' ' + className; // IE 8+ - } - } - - const removeClass = (el, className) => { + } + + const removeClass = (el, className) => { if (el.classList) { - el.classList.remove(className); // IE 10+ - } - else { - el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); // IE 8+ - } + el.classList.remove(className); // IE 10+ + } else { + el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); // IE 8+ } + } - const hasClass = (el, className) => { + const hasClass = (el, className) => { if (el.classList) { - return el.classList.contains(className); // IE 10+ - } - else { - return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); // IE 8+ ? - } + return el.classList.contains(className); // IE 10+ + } else { + return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); // IE 8+ ? } - - const setAttributes = (node, attrs) => { + } + + const setAttributes = (node, attrs) => { Object - .keys(attrs) - .forEach((attribute) => { - node.setAttribute(attribute, attrs[attribute]); - }); - }; -/* const triggerEvent = (el, event_type) => { - if (el.fireEvent) { - el.fireEvent('on' + event_type); - } - else { - let evObj = document.createEvent('Events'); - evObj.initEvent(event_type, true, false); - el.dispatchEvent(evObj); - } - }*/ - const unSelectHeaders = (elts) => { + .keys(attrs) + .forEach((attribute) => { + node.setAttribute(attribute, attrs[attribute]); + }); + }; + /* const triggerEvent = (el, event_type) => { + if (el.fireEvent) { + el.fireEvent('on' + event_type); + } + else { + let evObj = document.createEvent('Events'); + evObj.initEvent(event_type, true, false); + el.dispatchEvent(evObj); + } + }*/ + const unSelectHeaders = (elts) => { elts - .forEach((header_node, index) => { - setAttributes(header_node, { - [ATTR_SELECTED] : 'false' , - 'tabindex' : '-1' - }); - }); - } - - const selectHeader = (el) => { - el.setAttribute( ATTR_SELECTED , true ); - el.removeAttribute ( 'tabindex' ); - } - - const selectHeaderInList = (elts, param) => { + .forEach((header_node) => { + setAttributes(header_node, { + [ATTR_SELECTED]: 'false', + 'tabindex': '-1' + }); + }); + } + + const selectHeader = (el) => { + el.setAttribute(ATTR_SELECTED, true); + el.removeAttribute('tabindex'); + } + + const selectHeaderInList = (elts, param) => { let indice_trouve; elts - .forEach((header_node, index) => { - - if ( header_node.getAttribute(ATTR_SELECTED) === 'true' ) { - indice_trouve = index; - } - - }); - if ( param === 'next' ){ - selectHeader ( elts[indice_trouve+1] ); - setTimeout(function(){ elts[indice_trouve+1].focus(); }, 0); - } - if ( param === 'prev' ){ - selectHeader ( elts[indice_trouve-1] ); - setTimeout(function(){ elts[indice_trouve-1].focus(); }, 0); - } - + .forEach((header_node, index) => { + + if (header_node.getAttribute(ATTR_SELECTED) === 'true') { + indice_trouve = index; + } + + }); + if (param === 'next') { + selectHeader(elts[indice_trouve + 1]); + setTimeout(function() { + elts[indice_trouve + 1].focus(); + }, 0); } + if (param === 'prev') { + selectHeader(elts[indice_trouve - 1]); + setTimeout(function() { + elts[indice_trouve - 1].focus(); + }, 0); + } + + } - /* gets an element el, search if it is child of parent class, returns id of the parent */ - let searchParent = ( el, parentClass ) => { + /* gets an element el, search if it is child of parent class, returns id of the parent */ + let searchParent = (el, parentClass) => { let found = false; let parentElement = el.parentNode; - while ( parentElement && found === false ) { - if ( hasClass( parentElement, parentClass ) === true ) { + while (parentElement && found === false) { + if (hasClass(parentElement, parentClass) === true) { found = true; - } - else { - parentElement = parentElement.parentNode; - } + } else { + parentElement = parentElement.parentNode; } - if ( found === true ) { - return parentElement.getAttribute('id'); - } - else { return ''; } - } - - - // Find all accordions - const $listAccordions = () => [].slice.call(doc.querySelectorAll('.' + ACCORDION_JS)); - - - const onLoad = () => { - - $listAccordions() - .forEach((accordion_node, index) => { - - let iLisible = index + 1; - let prefixClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) + '-' : '' ; - let accordionClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) : '' ; - let multiSelectableAttribute = accordion_node.hasAttribute(ACCORDION_DATA_MULTISELECTABLE) === true ? accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) : '' ; - /*let toExpand = node.nextElementSibling; - let expandmoreText = node.innerHTML; - let expandButton = doc.createElement("BUTTON");*/ - - // clear element before adding button to it - //node.innerHTML = ''; - - // Init attributes accordion - if (accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) == 'none'){ - accordion_node.setAttribute( ATTR_MULTISELECTABLE , 'false' ); - } - else { - accordion_node.setAttribute( ATTR_MULTISELECTABLE , 'true' ); - } - accordion_node.setAttribute( ATTR_ROLE , ACCORDION_ROLE_TABLIST ); - addClass( accordion_node, prefixClassName + ACCORDION_STYLE); - - let $listAccordionsHeader = [].slice.call(accordion_node.querySelectorAll('.' + ACCORDION_JS_HEADER)); - $listAccordionsHeader - .forEach((header_node, index_header) => { - - let indexHeaderLisible = index_header+1; - let accordionPanel = header_node.nextElementSibling; - let accordionHeaderText = header_node.innerHTML; - let accordionButton = document.createElement("BUTTON"); - let accordionOpenedAttribute = header_node.hasAttribute(ACCORDION_DATA_OPENED) === true ? header_node.getAttribute(ACCORDION_DATA_OPENED) : '' ; - - // set button with attributes - accordionButton.innerHTML = accordionHeaderText; - addClass( accordionButton, ACCORDION_JS_HEADER ); - addClass( accordionButton, prefixClassName + ACCORDION_HEADER_STYLE ); - setAttributes(accordionButton, { - [ATTR_ROLE] : ACCORDION_ROLE_TAB , - 'id' : ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible , - [ATTR_CONTROLS] : ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible , - [ATTR_SELECTED] : 'false' , - 'tabindex' : '-1', - 'type' : 'button' - }); - - // place button - accordionButton = accordion_node.insertBefore(accordionButton, header_node); - - // move title into panel - accordionPanel.insertBefore(header_node, accordionPanel.firstChild); - // set title with attributes - addClass( header_node, prefixClassName + ACCORDION_TITLE_STYLE ); - removeClass ( header_node, ACCORDION_JS_HEADER ); - - // set attributes to panels - addClass( accordionPanel, prefixClassName + ACCORDION_PANEL_STYLE); - setAttributes(accordionPanel, { - [ATTR_ROLE] : ACCORDION_ROLE_TABPANEL , - [ATTR_LABELLEDBY] : ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible , - 'id' : ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible - }); - - if (accordionOpenedAttribute === 'true'){ - accordionButton.setAttribute( ATTR_EXPANDED , 'true' ); - header_node.removeAttribute( ACCORDION_DATA_OPENED ); - accordionPanel.setAttribute( ATTR_HIDDEN , 'false' ); - } - else { - accordionButton.setAttribute( ATTR_EXPANDED , 'false' ); - accordionPanel.setAttribute( ATTR_HIDDEN , 'true' ); - } + } + if (found === true) { + return parentElement.getAttribute('id'); + } else { + return ''; + } + } - // init first one focusable - if ( indexHeaderLisible === 1 ) { - accordionButton.removeAttribute( 'tabindex' ); - } - }); + // Find all accordions + const $listAccordions = () => [].slice.call(doc.querySelectorAll('.' + ACCORDION_JS)); + + + const onLoad = () => { - - }); - - // click on - ['click', 'keydown', 'focus'] - .forEach(eventName => { - let isCtrl = false; - - doc.body - .addEventListener(eventName, e => { - - // focus on button - if ( hasClass( e.target, ACCORDION_JS_HEADER) === true && eventName === 'focus' ) { - let buttonTag = e.target; - let accordionContainer = buttonTag.parentNode; - let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - - unSelectHeaders($accordionAllHeaders); - - selectHeader(buttonTag); + $listAccordions() + .forEach((accordion_node, index) => { + let iLisible = index + 1; + let prefixClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) + '-' : ''; + //let accordionClassName = accordion_node.hasAttribute(ACCORDION_DATA_PREFIX_CLASS) === true ? accordion_node.getAttribute(ACCORDION_DATA_PREFIX_CLASS) : '' ; + //let multiSelectableAttribute = accordion_node.hasAttribute(ACCORDION_DATA_MULTISELECTABLE) === true ? accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) : '' ; + /*let toExpand = node.nextElementSibling; + let expandmoreText = node.innerHTML; + let expandButton = doc.createElement("BUTTON");*/ + + // clear element before adding button to it + //node.innerHTML = ''; + + // Init attributes accordion + if (accordion_node.getAttribute(ACCORDION_DATA_MULTISELECTABLE) === 'none') { + accordion_node.setAttribute(ATTR_MULTISELECTABLE, 'false'); + } else { + accordion_node.setAttribute(ATTR_MULTISELECTABLE, 'true'); } + accordion_node.setAttribute(ATTR_ROLE, ACCORDION_ROLE_TABLIST); + addClass(accordion_node, prefixClassName + ACCORDION_STYLE); + + let $listAccordionsHeader = [].slice.call(accordion_node.querySelectorAll('.' + ACCORDION_JS_HEADER)); + $listAccordionsHeader + .forEach((header_node, index_header) => { + + let indexHeaderLisible = index_header + 1; + let accordionPanel = header_node.nextElementSibling; + let accordionHeaderText = header_node.innerHTML; + let accordionButton = document.createElement("BUTTON"); + let accordionOpenedAttribute = header_node.hasAttribute(ACCORDION_DATA_OPENED) === true ? header_node.getAttribute(ACCORDION_DATA_OPENED) : ''; + + // set button with attributes + accordionButton.innerHTML = accordionHeaderText; + addClass(accordionButton, ACCORDION_JS_HEADER); + addClass(accordionButton, prefixClassName + ACCORDION_HEADER_STYLE); + setAttributes(accordionButton, { + [ATTR_ROLE]: ACCORDION_ROLE_TAB, + 'id': ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible, + [ATTR_CONTROLS]: ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible, + [ATTR_SELECTED]: 'false', + 'tabindex': '-1', + 'type': 'button' + }); + + // place button + accordionButton = accordion_node.insertBefore(accordionButton, header_node); + + // move title into panel + accordionPanel.insertBefore(header_node, accordionPanel.firstChild); + // set title with attributes + addClass(header_node, prefixClassName + ACCORDION_TITLE_STYLE); + removeClass(header_node, ACCORDION_JS_HEADER); + + // set attributes to panels + addClass(accordionPanel, prefixClassName + ACCORDION_PANEL_STYLE); + setAttributes(accordionPanel, { + [ATTR_ROLE]: ACCORDION_ROLE_TABPANEL, + [ATTR_LABELLEDBY]: ACCORDION_PREFIX_IDS + iLisible + ACCORDION_BUTTON_ID + indexHeaderLisible, + 'id': ACCORDION_PREFIX_IDS + iLisible + ACCORDION_PANEL_ID + indexHeaderLisible + }); + + if (accordionOpenedAttribute === 'true') { + accordionButton.setAttribute(ATTR_EXPANDED, 'true'); + header_node.removeAttribute(ACCORDION_DATA_OPENED); + accordionPanel.setAttribute(ATTR_HIDDEN, 'false'); + } else { + accordionButton.setAttribute(ATTR_EXPANDED, 'false'); + accordionPanel.setAttribute(ATTR_HIDDEN, 'true'); + } - // click on button - if ( hasClass( e.target, ACCORDION_JS_HEADER) === true && eventName === 'click' ) { - let buttonTag = e.target; - let accordionContainer = buttonTag.parentNode; - let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - let accordionMultiSelectable = accordionContainer.getAttribute(ATTR_MULTISELECTABLE); - let destination = findById(buttonTag.getAttribute( ATTR_CONTROLS )); - let stateButton = buttonTag.getAttribute(ATTR_EXPANDED); - - // if closed - if ( stateButton === 'false' ){ - buttonTag.setAttribute( ATTR_EXPANDED , true ); - destination.removeAttribute( ATTR_HIDDEN ); - } - else { - buttonTag.setAttribute( ATTR_EXPANDED , false ); - destination.setAttribute( ATTR_HIDDEN , true ); + // init first one focusable + if (indexHeaderLisible === 1) { + accordionButton.removeAttribute('tabindex'); } - if ( accordionMultiSelectable === 'false' ) { - $accordionAllHeaders - .forEach((header_node, index) => { - - let destinationPanel = findById(header_node.getAttribute( ATTR_CONTROLS )); - - if ( header_node !== buttonTag ){ - header_node.setAttribute( ATTR_SELECTED , false ); - header_node.setAttribute( ATTR_EXPANDED , false ); - destinationPanel.setAttribute( ATTR_HIDDEN , true ); - } - else { - header_node.setAttribute( ATTR_SELECTED , true ); - } - }); + }); - } - - setTimeout(function(){ buttonTag.focus(); }, 0); - e.preventDefault(); - } - - // keyboard management for headers - if ( hasClass( e.target, ACCORDION_JS_HEADER) === true && eventName === 'keydown' ) { - let buttonTag = e.target; - let accordionContainer = buttonTag.parentNode; - let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - - // strike home on a tab => 1st tab - if ( e.keyCode === 36 ) { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function(){ $accordionAllHeaders[0].focus(); }, 0); - e.preventDefault(); - } - // strike end on the tab => last tab - else if ( e.keyCode == 35 ) { + }); + + // click on + ['click', 'keydown', 'focus'] + .forEach(eventName => { + //let isCtrl = false; + + doc.body + .addEventListener(eventName, e => { + + // focus on button + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'focus') { + let buttonTag = e.target; + let accordionContainer = buttonTag.parentNode; + let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + + unSelectHeaders($accordionAllHeaders); + + selectHeader(buttonTag); + + } + + // click on button + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'click') { + let buttonTag = e.target; + let accordionContainer = buttonTag.parentNode; + let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + let accordionMultiSelectable = accordionContainer.getAttribute(ATTR_MULTISELECTABLE); + let destination = findById(buttonTag.getAttribute(ATTR_CONTROLS)); + let stateButton = buttonTag.getAttribute(ATTR_EXPANDED); + + // if closed + if (stateButton === 'false') { + buttonTag.setAttribute(ATTR_EXPANDED, true); + destination.removeAttribute(ATTR_HIDDEN); + } else { + buttonTag.setAttribute(ATTR_EXPANDED, false); + destination.setAttribute(ATTR_HIDDEN, true); + } + + if (accordionMultiSelectable === 'false') { + $accordionAllHeaders + .forEach((header_node) => { + + let destinationPanel = findById(header_node.getAttribute(ATTR_CONTROLS)); + + if (header_node !== buttonTag) { + header_node.setAttribute(ATTR_SELECTED, false); + header_node.setAttribute(ATTR_EXPANDED, false); + destinationPanel.setAttribute(ATTR_HIDDEN, true); + } else { + header_node.setAttribute(ATTR_SELECTED, true); + } + }); + + } + + setTimeout(function() { + buttonTag.focus(); + }, 0); + e.preventDefault(); + + } + + // keyboard management for headers + if (hasClass(e.target, ACCORDION_JS_HEADER) === true && eventName === 'keydown') { + let buttonTag = e.target; + let accordionContainer = buttonTag.parentNode; + let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + + // strike home on a tab => 1st tab + if (e.keyCode === 36) { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function() { + $accordionAllHeaders[0].focus(); + }, 0); + e.preventDefault(); + } + // strike end on the tab => last tab + else if (e.keyCode === 35) { unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[ $accordionAllHeaders.length-1 ]); - setTimeout(function(){ $accordionAllHeaders[ $accordionAllHeaders.length-1 ].focus(); }, 0); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function() { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); e.preventDefault(); - } - // strike up or left on the tab => previous tab - else if ( ( e.keyCode == 37 || e.keyCode == 38 ) && !e.ctrlKey ) { - + } + // strike up or left on the tab => previous tab + else if ((e.keyCode === 37 || e.keyCode === 38) && !e.ctrlKey) { + // if first selected = select last //if ( $accordionAllHeaders[ $accordionAllHeaders.length-1 ].getAttribute( ATTR_SELECTED ) === 'true' ) { - if ( $accordionAllHeaders[ 0 ].getAttribute( ATTR_SELECTED ) === 'true' ) { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[ $accordionAllHeaders.length-1 ]); - setTimeout(function(){ $accordionAllHeaders[ $accordionAllHeaders.length-1 ].focus(); }, 0); - e.preventDefault(); - } - else { - selectHeaderInList( $accordionAllHeaders, 'prev' ); - e.preventDefault(); - } - + if ($accordionAllHeaders[0].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function() { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); + e.preventDefault(); + } else { + selectHeaderInList($accordionAllHeaders, 'prev'); + e.preventDefault(); } - // strike down or right in the tab => next tab - else if ( ( e.keyCode == 40 || e.keyCode == 39 ) && !e.ctrlKey ) { - - // if last selected = select first - if ( $accordionAllHeaders[ $accordionAllHeaders.length-1 ].getAttribute( ATTR_SELECTED ) === 'true' ) { - unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function(){ $accordionAllHeaders[0].focus(); }, 0); - e.preventDefault(); - } - else { - selectHeaderInList( $accordionAllHeaders, 'next' ); - e.preventDefault(); - } + } + // strike down or right in the tab => next tab + else if ((e.keyCode === 40 || e.keyCode === 39) && !e.ctrlKey) { + + // if last selected = select first + if ($accordionAllHeaders[$accordionAllHeaders.length - 1].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function() { + $accordionAllHeaders[0].focus(); + }, 0); + e.preventDefault(); + } else { + selectHeaderInList($accordionAllHeaders, 'next'); + e.preventDefault(); } + + } } - - - // keyboard management for panels - let id_panel = searchParent ( e.target, ACCORDION_JS_PANEL ); - if ( id_panel !== '' && eventName === 'keydown' ) { - //console.log('yes in pabnelk' + e.keyCode); - let panelTag = findById( id_panel ); - let accordionContainer = panelTag.parentNode; - let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); - let buttonTag = findById(panelTag.getAttribute( ATTR_LABELLEDBY )); - - // strike up + ctrl => go to header - if ( e.keyCode == 38 && e.ctrlKey ) { - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - setTimeout(function(){ buttonTag.focus(); }, 0); - e.preventDefault(); + + + // keyboard management for panels + let id_panel = searchParent(e.target, ACCORDION_JS_PANEL); + if (id_panel !== '' && eventName === 'keydown') { + + let panelTag = findById(id_panel); + let accordionContainer = panelTag.parentNode; + let $accordionAllHeaders = [].slice.call(accordionContainer.querySelectorAll('.' + ACCORDION_JS_HEADER)); + let buttonTag = findById(panelTag.getAttribute(ATTR_LABELLEDBY)); + + // strike up + ctrl => go to header + if (e.keyCode === 38 && e.ctrlKey) { + unSelectHeaders($accordionAllHeaders); + selectHeader(buttonTag); + setTimeout(function() { + buttonTag.focus(); + }, 0); + e.preventDefault(); } - // strike pageup + ctrl => go to prev header - if ( e.keyCode == 33 && e.ctrlKey ) { - // go to header - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - buttonTag.focus(); - e.preventDefault(); - // then previous - if ( $accordionAllHeaders[ 0 ].getAttribute( ATTR_SELECTED ) === 'true' ) { + // strike pageup + ctrl => go to prev header + if (e.keyCode === 33 && e.ctrlKey) { + // go to header unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[ $accordionAllHeaders.length-1 ]); - setTimeout(function(){ $accordionAllHeaders[ $accordionAllHeaders.length-1 ].focus(); }, 0); - } - else { - selectHeaderInList( $accordionAllHeaders, 'prev' ); - } - + selectHeader(buttonTag); + buttonTag.focus(); + e.preventDefault(); + // then previous + if ($accordionAllHeaders[0].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[$accordionAllHeaders.length - 1]); + setTimeout(function() { + $accordionAllHeaders[$accordionAllHeaders.length - 1].focus(); + }, 0); + } else { + selectHeaderInList($accordionAllHeaders, 'prev'); + } + } - // strike pagedown + ctrl => go to next header - if ( e.keyCode == 34 && e.ctrlKey ) { - // go to header - unSelectHeaders($accordionAllHeaders); - selectHeader(buttonTag); - buttonTag.focus(); - e.preventDefault(); - // then next - if ( $accordionAllHeaders[ $accordionAllHeaders.length-1 ].getAttribute( ATTR_SELECTED ) === 'true' ) { + // strike pagedown + ctrl => go to next header + if (e.keyCode === 34 && e.ctrlKey) { + // go to header unSelectHeaders($accordionAllHeaders); - selectHeader($accordionAllHeaders[0]); - setTimeout(function(){ $accordionAllHeaders[0].focus(); }, 0); - } - else { - selectHeaderInList( $accordionAllHeaders, 'next' ); - } - + selectHeader(buttonTag); + buttonTag.focus(); + e.preventDefault(); + // then next + if ($accordionAllHeaders[$accordionAllHeaders.length - 1].getAttribute(ATTR_SELECTED) === 'true') { + unSelectHeaders($accordionAllHeaders); + selectHeader($accordionAllHeaders[0]); + setTimeout(function() { + $accordionAllHeaders[0].focus(); + }, 0); + } else { + selectHeaderInList($accordionAllHeaders, 'next'); + } + } - - } - }, true); - }); - document.removeEventListener('DOMContentLoaded', onLoad); - } + } + + }, true); + }); + document.removeEventListener('DOMContentLoaded', onLoad); + } - document.addEventListener('DOMContentLoaded', onLoad); + document.addEventListener('DOMContentLoaded', onLoad); -})(document); +})(document); \ No newline at end of file