MDL-74073 core: Fix collapsesections accessibility

* Fix focus outline
* Set aria-expanded state accordingly
* Set aria-expanded in the template to false by default as the default
mode of the link is to expand all the sections.

Reference:
https://www.w3.org/TR/wai-aria-practices-1.1/#disclosure
This commit is contained in:
Jun Pataleta 2022-03-03 14:44:08 +08:00
parent 967d9b2546
commit 7dfb64c7cb
4 changed files with 12 additions and 3 deletions

View file

@ -6,6 +6,6 @@ define("core_form/collapsesections",["exports","jquery","core/pending"],(functio
* @copyright 2021 Bas Brands
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 4.0
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_pending=_interopRequireDefault(_pending);const SELECTORS_FORMCONTAINER=".fcontainer",CLASSES_SHOW="show",CLASSES_COLLAPSED="collapsed";_exports.init=collapsesections=>{const pendingPromise=new _pending.default("core_form/collapsesections"),collapsemenu=document.querySelector(collapsesections);collapsemenu.addEventListener("click",(()=>{let action="hide";collapsemenu.classList.contains(CLASSES_COLLAPSED)&&(action="show"),document.querySelectorAll(SELECTORS_FORMCONTAINER).forEach((collapsecontainer=>{(0,_jquery.default)(collapsecontainer).collapse(action)}))})),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("hidden.bs.collapse",(()=>{let allcollapsed=!0;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.classList.contains(CLASSES_SHOW)&&(allcollapsed=!1)})),allcollapsed&&collapsemenu.classList.add(CLASSES_COLLAPSED)})),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("shown.bs.collapse",(()=>{var allexpanded=!0;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.classList.contains(CLASSES_SHOW)||(allexpanded=!1)})),allexpanded&&collapsemenu.classList.remove(CLASSES_COLLAPSED)})),pendingPromise.resolve()}}));
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_pending=_interopRequireDefault(_pending);const SELECTORS_FORMCONTAINER=".fcontainer",CLASSES_SHOW="show",CLASSES_COLLAPSED="collapsed";_exports.init=collapsesections=>{const pendingPromise=new _pending.default("core_form/collapsesections"),collapsemenu=document.querySelector(collapsesections);collapsemenu.addEventListener("keydown",(e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),collapsemenu.click())})),collapsemenu.addEventListener("click",(()=>{let action="hide";collapsemenu.classList.contains(CLASSES_COLLAPSED)&&(action="show"),document.querySelectorAll(SELECTORS_FORMCONTAINER).forEach((collapsecontainer=>{(0,_jquery.default)(collapsecontainer).collapse(action)}))})),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("hidden.bs.collapse",(()=>{let allcollapsed=!0;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.classList.contains(CLASSES_SHOW)&&(allcollapsed=!1)})),allcollapsed&&(collapsemenu.classList.add(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!1))})),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("shown.bs.collapse",(()=>{var allexpanded=!0;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.classList.contains(CLASSES_SHOW)||(allexpanded=!1)})),allexpanded&&(collapsemenu.classList.remove(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!0))})),pendingPromise.resolve()}}));
//# sourceMappingURL=collapsesections.min.js.map

View file

@ -1 +1 @@
{"version":3,"file":"collapsesections.min.js","sources":["../src/collapsesections.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Collapse or expand all form sections on clicking the expand all / collapse al link.\n *\n * @module core_form/collapsesections\n * @copyright 2021 Bas Brands\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n */\n\nimport $ from 'jquery';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n FORMCONTAINER: '.fcontainer',\n};\n\nconst CLASSES = {\n SHOW: 'show',\n COLLAPSED: 'collapsed'\n};\n\n/**\n * Initialises the form section collapse / expand action.\n *\n * @param {string} collapsesections the collapse/expand link id.\n */\nexport const init = collapsesections => {\n // All jQuery in this code can be replaced when MDL-79179 is integrated.\n const pendingPromise = new Pending('core_form/collapsesections');\n const collapsemenu = document.querySelector(collapsesections);\n collapsemenu.addEventListener('click', () => {\n let action = 'hide';\n if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {\n action = 'show';\n }\n\n document.querySelectorAll(SELECTORS.FORMCONTAINER).forEach((collapsecontainer) => {\n $(collapsecontainer).collapse(action);\n });\n });\n $(SELECTORS.FORMCONTAINER).on('hidden.bs.collapse', () => {\n let allcollapsed = true;\n $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (collapsecontainer.classList.contains(CLASSES.SHOW)) {\n allcollapsed = false;\n }\n });\n if (allcollapsed) {\n collapsemenu.classList.add(CLASSES.COLLAPSED);\n }\n });\n $(SELECTORS.FORMCONTAINER).on('shown.bs.collapse', () => {\n var allexpanded = true;\n $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (!collapsecontainer.classList.contains(CLASSES.SHOW)) {\n allexpanded = false;\n }\n });\n\n if (allexpanded) {\n collapsemenu.classList.remove(CLASSES.COLLAPSED);\n }\n });\n pendingPromise.resolve();\n};\n"],"names":["SELECTORS","CLASSES","collapsesections","pendingPromise","Pending","collapsemenu","document","querySelector","addEventListener","action","classList","contains","querySelectorAll","forEach","collapsecontainer","collapse","on","allcollapsed","each","_","add","allexpanded","remove","resolve"],"mappings":";;;;;;;;0KA2BMA,wBACa,cAGbC,aACI,OADJA,kBAES,0BAQKC,yBAEVC,eAAiB,IAAIC,iBAAQ,8BAC7BC,aAAeC,SAASC,cAAcL,kBAC5CG,aAAaG,iBAAiB,SAAS,SAC/BC,OAAS,OACTJ,aAAaK,UAAUC,SAASV,qBAChCQ,OAAS,QAGbH,SAASM,iBAAiBZ,yBAAyBa,SAASC,wCACtDA,mBAAmBC,SAASN,kCAGpCT,yBAAyBgB,GAAG,sBAAsB,SAC5CC,cAAe,sBACjBjB,yBAAyBkB,MAAK,CAACC,EAAGL,qBAC5BA,kBAAkBJ,UAAUC,SAASV,gBACrCgB,cAAe,MAGnBA,cACAZ,aAAaK,UAAUU,IAAInB,0CAGjCD,yBAAyBgB,GAAG,qBAAqB,SAC3CK,aAAc,sBAChBrB,yBAAyBkB,MAAK,CAACC,EAAGL,qBAC3BA,kBAAkBJ,UAAUC,SAASV,gBACtCoB,aAAc,MAIlBA,aACAhB,aAAaK,UAAUY,OAAOrB,sBAGtCE,eAAeoB"}
{"version":3,"file":"collapsesections.min.js","sources":["../src/collapsesections.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Collapse or expand all form sections on clicking the expand all / collapse al link.\n *\n * @module core_form/collapsesections\n * @copyright 2021 Bas Brands\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n */\n\nimport $ from 'jquery';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n FORMCONTAINER: '.fcontainer',\n};\n\nconst CLASSES = {\n SHOW: 'show',\n COLLAPSED: 'collapsed'\n};\n\n/**\n * Initialises the form section collapse / expand action.\n *\n * @param {string} collapsesections the collapse/expand link id.\n */\nexport const init = collapsesections => {\n // All jQuery in this code can be replaced when MDL-79179 is integrated.\n const pendingPromise = new Pending('core_form/collapsesections');\n const collapsemenu = document.querySelector(collapsesections);\n collapsemenu.addEventListener('keydown', e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n collapsemenu.click();\n }\n });\n collapsemenu.addEventListener('click', () => {\n let action = 'hide';\n if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {\n action = 'show';\n }\n\n document.querySelectorAll(SELECTORS.FORMCONTAINER).forEach((collapsecontainer) => {\n $(collapsecontainer).collapse(action);\n });\n });\n $(SELECTORS.FORMCONTAINER).on('hidden.bs.collapse', () => {\n let allcollapsed = true;\n $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (collapsecontainer.classList.contains(CLASSES.SHOW)) {\n allcollapsed = false;\n }\n });\n if (allcollapsed) {\n collapsemenu.classList.add(CLASSES.COLLAPSED);\n collapsemenu.setAttribute('aria-expanded', false);\n }\n });\n $(SELECTORS.FORMCONTAINER).on('shown.bs.collapse', () => {\n var allexpanded = true;\n $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (!collapsecontainer.classList.contains(CLASSES.SHOW)) {\n allexpanded = false;\n }\n });\n\n if (allexpanded) {\n collapsemenu.classList.remove(CLASSES.COLLAPSED);\n collapsemenu.setAttribute('aria-expanded', true);\n }\n });\n pendingPromise.resolve();\n};\n"],"names":["SELECTORS","CLASSES","collapsesections","pendingPromise","Pending","collapsemenu","document","querySelector","addEventListener","e","key","preventDefault","click","action","classList","contains","querySelectorAll","forEach","collapsecontainer","collapse","on","allcollapsed","each","_","add","setAttribute","allexpanded","remove","resolve"],"mappings":";;;;;;;;0KA2BMA,wBACa,cAGbC,aACI,OADJA,kBAES,0BAQKC,yBAEVC,eAAiB,IAAIC,iBAAQ,8BAC7BC,aAAeC,SAASC,cAAcL,kBAC5CG,aAAaG,iBAAiB,WAAWC,IACvB,UAAVA,EAAEC,KAA6B,MAAVD,EAAEC,MACvBD,EAAEE,iBACFN,aAAaO,YAGrBP,aAAaG,iBAAiB,SAAS,SAC/BK,OAAS,OACTR,aAAaS,UAAUC,SAASd,qBAChCY,OAAS,QAGbP,SAASU,iBAAiBhB,yBAAyBiB,SAASC,wCACtDA,mBAAmBC,SAASN,kCAGpCb,yBAAyBoB,GAAG,sBAAsB,SAC5CC,cAAe,sBACjBrB,yBAAyBsB,MAAK,CAACC,EAAGL,qBAC5BA,kBAAkBJ,UAAUC,SAASd,gBACrCoB,cAAe,MAGnBA,eACAhB,aAAaS,UAAUU,IAAIvB,mBAC3BI,aAAaoB,aAAa,iBAAiB,2BAGjDzB,yBAAyBoB,GAAG,qBAAqB,SAC3CM,aAAc,sBAChB1B,yBAAyBsB,MAAK,CAACC,EAAGL,qBAC3BA,kBAAkBJ,UAAUC,SAASd,gBACtCyB,aAAc,MAIlBA,cACArB,aAAaS,UAAUa,OAAO1B,mBAC9BI,aAAaoB,aAAa,iBAAiB,OAGnDtB,eAAeyB"}

View file

@ -43,6 +43,12 @@ export const init = collapsesections => {
// All jQuery in this code can be replaced when MDL-79179 is integrated.
const pendingPromise = new Pending('core_form/collapsesections');
const collapsemenu = document.querySelector(collapsesections);
collapsemenu.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
collapsemenu.click();
}
});
collapsemenu.addEventListener('click', () => {
let action = 'hide';
if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {
@ -62,6 +68,7 @@ export const init = collapsesections => {
});
if (allcollapsed) {
collapsemenu.classList.add(CLASSES.COLLAPSED);
collapsemenu.setAttribute('aria-expanded', false);
}
});
$(SELECTORS.FORMCONTAINER).on('shown.bs.collapse', () => {
@ -74,6 +81,7 @@ export const init = collapsesections => {
if (allexpanded) {
collapsemenu.classList.remove(CLASSES.COLLAPSED);
collapsemenu.setAttribute('aria-expanded', true);
}
});
pendingPromise.resolve();

View file

@ -24,7 +24,8 @@
}
}}
<div class="collapsible-actions">
<a id="collapsesections{{uniqid}}" href="#" aria-expanded="true" class="collapseexpand collapsemenu collapsed">
<a id="collapsesections{{uniqid}}" href="#" aria-expanded="false" class="btn btn-link p-1 collapseexpand collapsemenu collapsed"{{!
}} role="button">
<span class="collapseall">{{#str}}collapseall{{/str}}</span>
<span class="expandall">{{#str}}expandall{{/str}}</span>
</a>