Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"version":3,"file":"dialog.min.js","sources":["../../../src/local/dropdown/dialog.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 * Dropdown status JS controls.\n *\n * @module      core/local/dropdown/dialog\n * @copyright   2023 Ferran Recio <ferran@moodle.com>\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n// The jQuery module is only used for interacting with Bootstrap 4. It can be removed when MDL-71979 is integrated.\nimport jQuery from 'jquery';\nimport {\n    firstFocusableElement,\n    lastFocusableElement,\n    previousFocusableElement,\n    nextFocusableElement,\n} from 'core/pagehelpers';\nimport Pending from 'core/pending';\n\nconst Selectors = {\n    dropdownButton: '[data-for=\"dropdowndialog_button\"]',\n    dropdownDialog: '[data-for=\"dropdowndialog_dialog\"]',\n};\n\n/**\n * Dropdown dialog class.\n * @private\n */\nexport class DropdownDialog {\n    /**\n     * Constructor.\n     * @param {HTMLElement} element The element to initialize.\n     */\n    constructor(element) {\n        this.element = element;\n        this.button = element.querySelector(Selectors.dropdownButton);\n        this.panel = element.querySelector(Selectors.dropdownDialog);\n    }\n\n    /**\n     * Initialize the subpanel element.\n     *\n     * This method adds the event listeners to the subpanel and the position classes.\n     */\n    init() {\n        if (this.element.dataset.dropdownDialogInitialized) {\n            return;\n        }\n\n        // Menu Item events.\n        this.button.addEventListener('keydown', this._buttonKeyHandler.bind(this));\n        // Subpanel content events.\n        this.panel.addEventListener('keydown', this._contentKeyHandler.bind(this));\n\n        this.element.dataset.dropdownDialogInitialized = true;\n    }\n\n    /**\n     * Dropdown button key handler.\n     * @param {Event} event\n     * @private\n     */\n    _buttonKeyHandler(event) {\n        if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n            event.stopPropagation();\n            event.preventDefault();\n            this.setVisible(false);\n            return;\n        }\n\n        if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {\n            event.stopPropagation();\n            event.preventDefault();\n            this.setVisible(true);\n            this._focusPanelContent();\n        }\n    }\n\n    /**\n     * Sub panel content key handler.\n     * @param {Event} event\n     * @private\n     */\n    _contentKeyHandler(event) {\n        let newFocus = null;\n\n        if (event.key === 'End') {\n            newFocus = lastFocusableElement(this.panel);\n        }\n        if (event.key === 'Home') {\n            newFocus = firstFocusableElement(this.panel);\n        }\n        if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n            newFocus = previousFocusableElement(this.panel, false);\n            if (!newFocus) {\n                newFocus = this.button;\n            }\n        }\n        if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {\n            newFocus = nextFocusableElement(this.panel, false);\n        }\n        if (newFocus !== null) {\n            event.stopPropagation();\n            event.preventDefault();\n            newFocus.focus();\n        }\n    }\n\n    /**\n     * Focus on the first focusable element of the subpanel.\n     * @private\n     */\n    _focusPanelContent() {\n        const pendingPromise = new Pending('core/dropdown/dialog:focuscontent');\n        // Some Bootstrap events are triggered after the click event.\n        // To prevent this from affecting the focus we wait a bit.\n        setTimeout(() => {\n            const firstFocusable = firstFocusableElement(this.panel);\n            if (firstFocusable) {\n                firstFocusable.focus();\n            }\n            pendingPromise.resolve();\n        }, 100);\n    }\n\n    /**\n     * Set the visibility of a subpanel.\n     * @param {Boolean} visible true if the subpanel should be visible.\n     */\n    setVisible(visible) {\n        if (visible === this.isVisible()) {\n            return;\n        }\n        // All jQuery in this code can be replaced when MDL-71979 is integrated.\n        jQuery(this.button).dropdown('toggle');\n    }\n\n    /**\n     * Get the visibility of a subpanel.\n     * @returns {Boolean} true if the subpanel is visible.\n     */\n    isVisible() {\n        return this.button.getAttribute('aria-expanded') === 'true';\n    }\n\n    /**\n     * Set the content of the button.\n     * @param {String} content\n     */\n    setButtonContent(content) {\n        this.button.innerHTML = content;\n    }\n\n    /**\n     * Set the disabled state of the button.\n     * @param {Boolean} disabled\n     */\n    setButtonDisabled(disabled) {\n        if (disabled) {\n            this.button.setAttribute('disabled', 'disabled');\n        } else {\n            this.button.removeAttribute('disabled');\n        }\n    }\n\n    /**\n     * Return the main dropdown HTML element.\n     * @returns {HTMLElement} The element.\n     */\n    getElement() {\n        return this.element;\n    }\n}\n\n/**\n * Get the dropdown dialog instance from a selector.\n * @param {string} selector The query selector to init.\n * @returns {DropdownDialog|null} The dropdown dialog instance if any.\n */\nexport const getDropdownDialog = (selector) => {\n    const dropdownElement = document.querySelector(selector);\n    if (!dropdownElement) {\n        return null;\n    }\n    return new DropdownDialog(dropdownElement);\n};\n\n/**\n * Initialize module.\n *\n * @method\n * @param {string} selector The query selector to init.\n */\nexport const init = (selector) => {\n    const dropdown = getDropdownDialog(selector);\n    if (!dropdown) {\n        throw new Error(`Dopdown dialog element not found: ${selector}`);\n    }\n    dropdown.init();\n};\n"],"names":["Selectors","DropdownDialog","constructor","element","button","querySelector","panel","init","this","dataset","dropdownDialogInitialized","addEventListener","_buttonKeyHandler","bind","_contentKeyHandler","event","key","stopPropagation","preventDefault","setVisible","_focusPanelContent","newFocus","focus","pendingPromise","Pending","setTimeout","firstFocusable","resolve","visible","isVisible","dropdown","getAttribute","setButtonContent","content","innerHTML","setButtonDisabled","disabled","setAttribute","removeAttribute","getElement","getDropdownDialog","selector","dropdownElement","document","Error"],"mappings":";;;;;;;6NAiCMA,yBACc,qCADdA,yBAEc,2CAOPC,eAKTC,YAAYC,cACHA,QAAUA,aACVC,OAASD,QAAQE,cAAcL,+BAC/BM,MAAQH,QAAQE,cAAcL,0BAQvCO,OACQC,KAAKL,QAAQM,QAAQC,iCAKpBN,OAAOO,iBAAiB,UAAWH,KAAKI,kBAAkBC,KAAKL,YAE/DF,MAAMK,iBAAiB,UAAWH,KAAKM,mBAAmBD,KAAKL,YAE/DL,QAAQM,QAAQC,2BAA4B,GAQrDE,kBAAkBG,UACI,YAAdA,MAAMC,KAAmC,cAAdD,MAAMC,WACjCD,MAAME,kBACNF,MAAMG,2BACDC,YAAW,GAIF,cAAdJ,MAAMC,KAAqC,eAAdD,MAAMC,MACnCD,MAAME,kBACNF,MAAMG,sBACDC,YAAW,QACXC,sBASbN,mBAAmBC,WACXM,SAAW,KAEG,QAAdN,MAAMC,MACNK,UAAW,qCAAqBb,KAAKF,QAEvB,SAAdS,MAAMC,MACNK,UAAW,sCAAsBb,KAAKF,QAExB,YAAdS,MAAMC,KAAmC,cAAdD,MAAMC,MACjCK,UAAW,yCAAyBb,KAAKF,OAAO,GAC3Ce,WACDA,SAAWb,KAAKJ,SAGN,cAAdW,MAAMC,KAAqC,eAAdD,MAAMC,MACnCK,UAAW,qCAAqBb,KAAKF,OAAO,IAE/B,OAAbe,WACAN,MAAME,kBACNF,MAAMG,iBACNG,SAASC,SAQjBF,2BACUG,eAAiB,IAAIC,iBAAQ,qCAGnCC,YAAW,WACDC,gBAAiB,sCAAsBlB,KAAKF,OAC9CoB,gBACAA,eAAeJ,QAEnBC,eAAeI,YAChB,KAOPR,WAAWS,SACHA,UAAYpB,KAAKqB,iCAIdrB,KAAKJ,QAAQ0B,SAAS,UAOjCD,kBACyD,SAA9CrB,KAAKJ,OAAO2B,aAAa,iBAOpCC,iBAAiBC,cACR7B,OAAO8B,UAAYD,QAO5BE,kBAAkBC,UACVA,cACKhC,OAAOiC,aAAa,WAAY,iBAEhCjC,OAAOkC,gBAAgB,YAQpCC,oBACW/B,KAAKL,sDASPqC,kBAAqBC,iBACxBC,gBAAkBC,SAAStC,cAAcoC,iBAC1CC,gBAGE,IAAIzC,eAAeyC,iBAFf,iEAWMD,iBACXX,SAAWU,kBAAkBC,cAC9BX,eACK,IAAIc,kDAA2CH,WAEzDX,SAASvB"}