weekly release 4.0dev
[moodle.git] / lib / amd / build / local / aria / aria-hidden.min.js.map
1 {"version":3,"sources":["../../../src/local/aria/aria-hidden.js"],"names":["childObserverMap","Map","siblingObserverMap","supportsMutationObservers","MutationObserver","disableElementFocusability","target","HTMLElement","matches","Selectors","elements","focusable","disableAndStoreTabIndex","querySelectorAll","forEach","element","dataset","ariaHiddenTabIndex","getAttribute","setAttribute","enableElementFocusability","focusableToUnhide","restoreTabIndex","closest","aria","hidden","oldTabIndex","removeAttribute","hide","_hide","newNodeObserver","mutationList","mutation","addedNodes","observe","childList","subtree","set","unhide","_unhide","has","get","disconnect","delete","hideSiblings","_hideSiblings","parentElement","childNodes","node","contains","unhideSiblings","_unhideSiblings"],"mappings":"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","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 * ARIA helpers related to the aria-hidden attribute.\n *\n * @module     core/local/aria/aria-hidden.\n * @copyright  2020 Andrew Nicols <andrew@nicols.co.uk>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getList} from 'core/normalise';\nimport Selectors from './selectors';\n\n// The map of MutationObserver objects for an object.\nconst childObserverMap = new Map();\nconst siblingObserverMap = new Map();\n\n/**\n * Determine whether the browser supports the MutationObserver system.\n *\n * @method\n * @returns {Bool}\n */\nconst supportsMutationObservers = () => (MutationObserver && typeof MutationObserver === 'function');\n\n/**\n * Disable element focusability, disabling the tabindex for child elements which are normally focusable.\n *\n * @method\n * @param {HTMLElement} target\n */\nconst disableElementFocusability = target => {\n    if (!(target instanceof HTMLElement)) {\n        // This element is not an HTMLElement.\n        // This can happen for Text Nodes.\n        return;\n    }\n\n    if (target.matches(Selectors.elements.focusable)) {\n        disableAndStoreTabIndex(target);\n    }\n\n    target.querySelectorAll(Selectors.elements.focusable).forEach(disableAndStoreTabIndex);\n};\n\n/**\n * Remove the current tab-index and store it for later restoration.\n *\n * @method\n * @param {HTMLElement} element\n */\nconst disableAndStoreTabIndex = element => {\n    if (typeof element.dataset.ariaHiddenTabIndex !== 'undefined') {\n        // This child already has a hidden attribute.\n        // Do not modify it as the original value will be lost.\n        return;\n    }\n\n    // Store the old tabindex in a data attribute.\n    if (element.getAttribute('tabindex')) {\n        element.dataset.ariaHiddenTabIndex = element.getAttribute('tabindex');\n    } else {\n        element.dataset.ariaHiddenTabIndex = '';\n    }\n    element.setAttribute('tabindex', -1);\n};\n\n/**\n * Re-enable element focusability, restoring any tabindex.\n *\n * @method\n * @param {HTMLElement} target\n */\nconst enableElementFocusability = target => {\n    if (!(target instanceof HTMLElement)) {\n        // This element is not an HTMLElement.\n        // This can happen for Text Nodes.\n        return;\n    }\n\n    if (target.matches(Selectors.elements.focusableToUnhide)) {\n        restoreTabIndex(target);\n    }\n\n    target.querySelectorAll(Selectors.elements.focusableToUnhide).forEach(restoreTabIndex);\n};\n\n/**\n * Restore the tab-index of the supplied element.\n *\n * When disabling focusability the current tab-index is stored in the ariaHiddenTabIndex data attribute.\n * This is used to restore the tab-index, but only whilst the parent nodes remain unhidden.\n *\n * @method\n * @param {HTMLElement} element\n */\nconst restoreTabIndex = element => {\n    if (element.closest(Selectors.aria.hidden)) {\n        // This item still has a hidden parent, or is hidden itself. Do not unhide it.\n        return;\n    }\n\n    const oldTabIndex = element.dataset.ariaHiddenTabIndex;\n    if (oldTabIndex === '') {\n        element.removeAttribute('tabindex');\n    } else {\n        element.setAttribute('tabindex', oldTabIndex);\n    }\n\n    delete element.dataset.ariaHiddenTabIndex;\n};\n\n/**\n * Update the supplied DOM Module to be hidden.\n *\n * @method\n * @param {HTMLElement} target\n * @returns {Array}\n */\nexport const hide = target => getList(target).forEach(_hide);\n\nconst _hide = target => {\n    if (!(target instanceof HTMLElement)) {\n        // This element is not an HTMLElement.\n        // This can happen for Text Nodes.\n        return;\n    }\n\n    if (target.closest(Selectors.aria.hidden)) {\n        // This Element, or a parent Element, is already hidden.\n        // Stop processing.\n        return;\n    }\n\n    // Set the aria-hidden attribute to true.\n    target.setAttribute('aria-hidden', true);\n\n    // Based on advice from https://dequeuniversity.com/rules/axe/3.3/aria-hidden-focus, upon setting the aria-hidden\n    // attribute, all focusable elements underneath that element should be modified such that they are not focusable.\n    disableElementFocusability(target);\n\n    if (supportsMutationObservers()) {\n        // Add a MutationObserver to check for new children to the tree.\n        const newNodeObserver = new MutationObserver(mutationList => {\n            mutationList.forEach(mutation => {\n                mutation.addedNodes.forEach(disableElementFocusability);\n            });\n        });\n\n        newNodeObserver.observe(target, {childList: true, subtree: true});\n        childObserverMap.set(target, newNodeObserver);\n    }\n};\n\n/**\n * Reverse the effect of the hide action.\n *\n * @method\n * @param {HTMLElement} target\n * @returns {Array}\n */\nexport const unhide = target => getList(target).forEach(_unhide);\n\nconst _unhide = target => {\n    if (!(target instanceof HTMLElement)) {\n        return;\n    }\n\n    // Note: The aria-hidden attribute should be removed, and not set to false.\n    // The presence of the attribute is sufficient for some browsers to treat it as being true, regardless of its value.\n    target.removeAttribute('aria-hidden');\n\n    // Restore the tabindex across all child nodes of the target.\n    enableElementFocusability(target);\n\n    // Remove the focusability MutationObserver watching this tree.\n    if (childObserverMap.has(target)) {\n        childObserverMap.get(target).disconnect();\n        childObserverMap.delete(target);\n    }\n};\n\n/**\n * Correctly mark all siblings of the supplied target Element as hidden.\n *\n * @method\n * @param {HTMLElement} target\n * @returns {Array}\n */\nexport const hideSiblings = target => getList(target).forEach(_hideSiblings);\n\nconst _hideSiblings = target => {\n    if (!(target instanceof HTMLElement)) {\n        return;\n    }\n\n    if (!target.parentElement) {\n        return;\n    }\n\n    target.parentElement.childNodes.forEach(node => {\n        if (node === target) {\n            // Skip self;\n            return;\n        }\n\n        hide(node);\n    });\n\n    if (supportsMutationObservers()) {\n        // Add a MutationObserver to check for new children to the tree.\n        const newNodeObserver = new MutationObserver(mutationList => {\n            mutationList.forEach(mutation => {\n                mutation.addedNodes.forEach(node => {\n                    if (target.contains(node)) {\n                        // Skip self, and children of self.\n                        return;\n                    }\n\n                    hide(node);\n                });\n            });\n        });\n\n        newNodeObserver.observe(target.parentElement, {childList: true, subtree: true});\n        siblingObserverMap.set(target.parentElement, newNodeObserver);\n    }\n};\n\n/**\n * Correctly reverse the hide action of all children of the supplied target Element.\n *\n * @method\n * @param {HTMLElement} target\n * @returns {Array}\n */\nexport const unhideSiblings = target => getList(target).forEach(_unhideSiblings);\n\nconst _unhideSiblings = target => {\n    if (!(target instanceof HTMLElement)) {\n        return;\n    }\n\n    if (!target.parentElement) {\n        return;\n    }\n\n    target.parentElement.childNodes.forEach(node => {\n        if (node === target) {\n            // Skip self;\n            return;\n        }\n\n        unhide(node);\n    });\n\n    // Remove the sibling MutationObserver watching this tree.\n    if (siblingObserverMap.has(target.parentElement)) {\n        siblingObserverMap.get(target.parentElement).disconnect();\n        siblingObserverMap.delete(target.parentElement);\n    }\n};\n"],"file":"aria-hidden.min.js"}