{"version":3,"file":"modal_factory.min.js","sources":["../src/modal_factory.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 * Create a modal.\n *\n * @module     core/modal_factory\n * @class      modal_factory\n * @package    core\n * @copyright  2016 Ryan Wyllie <ryan@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal',\n        'core/modal_save_cancel', 'core/modal_cancel', 'core/local/modal/alert',\n        'core/templates', 'core/notification', 'core/custom_interaction_events',\n        'core/pending'],\n    function($, ModalEvents, ModalRegistry, Modal, ModalSaveCancel,\n        ModalCancel, ModalAlert, Templates, Notification, CustomEvents, Pending) {\n\n    // The templates for each type of modal.\n    var TEMPLATES = {\n        DEFAULT: 'core/modal',\n        SAVE_CANCEL: 'core/modal_save_cancel',\n        CANCEL: 'core/modal_cancel',\n        ALERT: 'core/local/modal/alert',\n    };\n\n    // The available types of modals.\n    var TYPES = {\n        DEFAULT: 'DEFAULT',\n        SAVE_CANCEL: 'SAVE_CANCEL',\n        CANCEL: 'CANCEL',\n        ALERT: 'ALERT',\n    };\n\n    // Register the common set of modals.\n    ModalRegistry.register(TYPES.DEFAULT, Modal, TEMPLATES.DEFAULT);\n    ModalRegistry.register(TYPES.SAVE_CANCEL, ModalSaveCancel, TEMPLATES.SAVE_CANCEL);\n    ModalRegistry.register(TYPES.CANCEL, ModalCancel, TEMPLATES.CANCEL);\n    ModalRegistry.register(TYPES.ALERT, ModalAlert, TEMPLATES.ALERT);\n\n    /**\n     * Set up the events required to show the modal and return focus when the modal\n     * is closed.\n     *\n     * @method setUpTrigger\n     * @param {Promise} modalPromise The modal instance\n     * @param {object} triggerElement The jQuery element to open the modal\n     * @param {object} modalConfig The modal configuration given to the factory\n     */\n    var setUpTrigger = function(modalPromise, triggerElement, modalConfig) {\n        // The element that actually shows the modal.\n        var actualTriggerElement = null;\n        // Check if the client has provided a callback function to be called\n        // before the modal is displayed.\n        var hasPreShowCallback = (typeof modalConfig.preShowCallback == 'function');\n        // Function to handle the trigger element being activated.\n        var triggeredCallback = function(e, data) {\n            var pendingPromise = new Pending('core/modal_factory:setUpTrigger:triggeredCallback');\n            actualTriggerElement = $(e.currentTarget);\n            modalPromise.then(function(modal) {\n                if (hasPreShowCallback) {\n                    // If the client provided a pre-show callback then execute\n                    // it now before showing the modal.\n                    modalConfig.preShowCallback(actualTriggerElement, modal);\n                }\n\n                modal.show();\n\n                return modal;\n            })\n            .then(pendingPromise.resolve);\n            data.originalEvent.preventDefault();\n        };\n\n        // The trigger element can either be a single element or it can be an\n        // element + selector pair to create a delegated event handler to trigger\n        // the modal.\n        if (Array.isArray(triggerElement)) {\n            var selector = triggerElement[1];\n            triggerElement = triggerElement[0];\n\n            CustomEvents.define(triggerElement, [CustomEvents.events.activate]);\n            triggerElement.on(CustomEvents.events.activate, selector, triggeredCallback);\n        } else {\n            CustomEvents.define(triggerElement, [CustomEvents.events.activate]);\n            triggerElement.on(CustomEvents.events.activate, triggeredCallback);\n        }\n\n        modalPromise.then(function(modal) {\n            modal.getRoot().on(ModalEvents.hidden, function() {\n                // Focus on the trigger element that actually launched the modal.\n                if (actualTriggerElement !== null) {\n                    actualTriggerElement.focus();\n                }\n            });\n\n            return modal;\n        });\n    };\n\n    /**\n     * Create the correct instance of a modal based on the givem type. Sets up\n     * the trigger between the modal and the trigger element.\n     *\n     * @method createFromElement\n     * @param {object} registryConf A config from the ModalRegistry\n     * @param {object} modalElement The modal HTML jQuery object\n     * @return {object} Modal instance\n     */\n    var createFromElement = function(registryConf, modalElement) {\n        modalElement = $(modalElement);\n        var module = registryConf.module;\n        var modal = new module(modalElement);\n\n        return modal;\n    };\n\n    /**\n     * Create the correct modal instance for the given type, including loading\n     * the correct template.\n     *\n     * @method createFromType\n     * @param {object} registryConf A config from the ModalRegistry\n     * @param {object} templateContext The context to render the template with\n     * @return {promise} Resolved with a Modal instance\n     */\n    var createFromType = function(registryConf, templateContext) {\n        var templateName = registryConf.template;\n\n        var modalPromise = Templates.render(templateName, templateContext)\n            .then(function(html) {\n                var modalElement = $(html);\n                return createFromElement(registryConf, modalElement);\n            })\n            .fail(Notification.exception);\n\n        return modalPromise;\n    };\n\n    /**\n     * Create a Modal instance.\n     *\n     * @method create\n     * @param {object} modalConfig The configuration to create the modal instance\n     * @param {object} triggerElement The trigger HTML jQuery object\n     * @return {promise} Resolved with a Modal instance\n     */\n    var create = function(modalConfig, triggerElement) {\n        var type = modalConfig.type || TYPES.DEFAULT;\n        var isLarge = modalConfig.large ? true : false;\n        var registryConf = null;\n        var templateContext = {};\n\n        registryConf = ModalRegistry.get(type);\n\n        if (!registryConf) {\n            Notification.exception({message: 'Unable to find modal of type: ' + type});\n        }\n\n        if (typeof modalConfig.templateContext != 'undefined') {\n            templateContext = modalConfig.templateContext;\n        }\n\n        var modalPromise = createFromType(registryConf, templateContext)\n            .then(function(modal) {\n                if (typeof modalConfig.title != 'undefined') {\n                    modal.setTitle(modalConfig.title);\n                }\n\n                if (typeof modalConfig.body != 'undefined') {\n                    modal.setBody(modalConfig.body);\n                }\n\n                if (typeof modalConfig.footer != 'undefined') {\n                    modal.setFooter(modalConfig.footer);\n                }\n\n                if (modalConfig.buttons) {\n                    Object.entries(modalConfig.buttons).forEach(function([key, value]) {\n                        modal.setButtonText(key, value);\n                    });\n                }\n\n                if (isLarge) {\n                    modal.setLarge();\n                }\n\n                if (typeof modalConfig.removeOnClose !== 'undefined') {\n                    // If configured remove the modal when hiding it.\n                    modal.setRemoveOnClose(modalConfig.removeOnClose);\n                }\n\n                return modal;\n            });\n\n        if (typeof triggerElement != 'undefined') {\n            setUpTrigger(modalPromise, triggerElement, modalConfig);\n        }\n\n        return modalPromise;\n    };\n\n    return {\n        create: create,\n        types: TYPES,\n    };\n});\n"],"names":["define","$","ModalEvents","ModalRegistry","Modal","ModalSaveCancel","ModalCancel","ModalAlert","Templates","Notification","CustomEvents","Pending","TEMPLATES","TYPES","DEFAULT","SAVE_CANCEL","CANCEL","ALERT","register","createFromType","registryConf","templateContext","templateName","template","modalPromise","render","then","html","modalElement","module","createFromElement","fail","exception","create","modalConfig","triggerElement","type","isLarge","large","get","message","modal","title","setTitle","body","setBody","footer","setFooter","buttons","Object","entries","forEach","key","value","setButtonText","setLarge","removeOnClose","setRemoveOnClose","actualTriggerElement","hasPreShowCallback","preShowCallback","triggeredCallback","e","data","pendingPromise","currentTarget","show","resolve","originalEvent","preventDefault","Array","isArray","selector","events","activate","on","getRoot","hidden","focus","setUpTrigger","types"],"mappings":";;;;;;;;;miCAwBAA,4BAAO,CAAC,SAAU,oBAAqB,sBAAuB,aACtD,yBAA0B,oBAAqB,yBAC/C,iBAAkB,oBAAqB,iCACvC,iBACJ,SAASC,EAAGC,YAAaC,cAAeC,MAAOC,gBAC3CC,YAAaC,WAAYC,UAAWC,aAAcC,aAAcC,aAGhEC,kBACS,aADTA,sBAEa,yBAFbA,iBAGQ,oBAHRA,gBAIO,yBAIPC,MAAQ,CACRC,QAAS,UACTC,YAAa,cACbC,OAAQ,SACRC,MAAO,SAIXd,cAAce,SAASL,MAAMC,QAASV,MAAOQ,mBAC7CT,cAAce,SAASL,MAAME,YAAaV,gBAAiBO,uBAC3DT,cAAce,SAASL,MAAMG,OAAQV,YAAaM,kBAClDT,cAAce,SAASL,MAAMI,MAAOV,WAAYK,qBAwF5CO,eAAiB,SAASC,aAAcC,qBACpCC,aAAeF,aAAaG,SAE5BC,aAAehB,UAAUiB,OAAOH,aAAcD,iBAC7CK,MAAK,SAASC,UACPC,aAAe3B,EAAE0B,aAtBT,SAASP,aAAcQ,qBAC3CA,aAAe3B,EAAE2B,cAEL,IAAIC,EADHT,aAAaS,QACHD,cAoBRE,CAAkBV,aAAcQ,iBAE1CG,KAAKtB,aAAauB,kBAEhBR,oBAkEJ,CACHS,OAxDS,SAASC,YAAaC,oBAG3Bf,aAFAgB,KAAOF,YAAYE,MAAQvB,MAAMC,QACjCuB,UAAUH,YAAYI,MAEtBjB,gBAAkB,IAEtBD,aAAejB,cAAcoC,IAAIH,QAG7B3B,aAAauB,UAAU,CAACQ,QAAS,iCAAmCJ,YAG9B,IAA/BF,YAAYb,kBACnBA,gBAAkBa,YAAYb,qBAG9BG,aAAeL,eAAeC,aAAcC,iBAC3CK,MAAK,SAASe,mBACqB,IAArBP,YAAYQ,OACnBD,MAAME,SAAST,YAAYQ,YAGA,IAApBR,YAAYU,MACnBH,MAAMI,QAAQX,YAAYU,WAGG,IAAtBV,YAAYY,QACnBL,MAAMM,UAAUb,YAAYY,QAG5BZ,YAAYc,SACZC,OAAOC,QAAQhB,YAAYc,SAASG,SAAQ,gDAAUC,aAAKC,eACvDZ,MAAMa,cAAcF,IAAKC,UAI7BhB,SACAI,MAAMc,gBAG+B,IAA9BrB,YAAYsB,eAEnBf,MAAMgB,iBAAiBvB,YAAYsB,eAGhCf,qBAGc,IAAlBN,gBAlJI,SAASX,aAAcW,eAAgBD,iBAElDwB,qBAAuB,KAGvBC,mBAA4D,mBAA/BzB,YAAY0B,gBAEzCC,kBAAoB,SAASC,EAAGC,UAC5BC,eAAiB,IAAIrD,QAAQ,qDACjC+C,qBAAuBzD,EAAE6D,EAAEG,eAC3BzC,aAAaE,MAAK,SAASe,cACnBkB,oBAGAzB,YAAY0B,gBAAgBF,qBAAsBjB,OAGtDA,MAAMyB,OAECzB,SAEVf,KAAKsC,eAAeG,SACrBJ,KAAKK,cAAcC,qBAMnBC,MAAMC,QAAQpC,gBAAiB,KAC3BqC,SAAWrC,eAAe,GAC9BA,eAAiBA,eAAe,GAEhCzB,aAAaV,OAAOmC,eAAgB,CAACzB,aAAa+D,OAAOC,WACzDvC,eAAewC,GAAGjE,aAAa+D,OAAOC,SAAUF,SAAUX,wBAE1DnD,aAAaV,OAAOmC,eAAgB,CAACzB,aAAa+D,OAAOC,WACzDvC,eAAewC,GAAGjE,aAAa+D,OAAOC,SAAUb,mBAGpDrC,aAAaE,MAAK,SAASe,cACvBA,MAAMmC,UAAUD,GAAGzE,YAAY2E,QAAQ,WAEN,OAAzBnB,sBACAA,qBAAqBoB,WAItBrC,SAoGPsC,CAAavD,aAAcW,eAAgBD,aAGxCV,cAKPwD,MAAOnE"}