From ae8d60c4a1971c986f65151d4c06efd24fadb78a Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 6 Mar 2020 12:28:56 +0800 Subject: [PATCH 1/2] MDL-67827 behat: Add missing exception use --- lib/behat/classes/util.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/behat/classes/util.php b/lib/behat/classes/util.php index 5338be1c7f6..267406bb5bf 100644 --- a/lib/behat/classes/util.php +++ b/lib/behat/classes/util.php @@ -34,6 +34,7 @@ require_once(__DIR__ . '/../../filelib.php'); require_once(__DIR__ . '/../../clilib.php'); use Behat\Mink\Session; +use Behat\Mink\Exception\ExpectationException; /** * Init/reset utilities for Behat database and dataroot From 604887ce8f4b69e56abcdd7649fd55c3daa7e525 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 6 Mar 2020 12:27:51 +0800 Subject: [PATCH 2/2] MDL-67827 behat: Pending JS improvements for dialogues --- enrol/manual/amd/build/quickenrolment.min.js | 2 +- enrol/manual/amd/build/quickenrolment.min.js.map | 2 +- enrol/manual/amd/src/quickenrolment.js | 7 +++++-- lib/amd/build/modal.min.js | 2 +- lib/amd/build/modal.min.js.map | 2 +- lib/amd/build/modal_factory.min.js | 2 +- lib/amd/build/modal_factory.min.js.map | 2 +- lib/amd/src/modal.js | 13 ++++++++++--- lib/amd/src/modal_factory.js | 9 ++++++--- 9 files changed, 27 insertions(+), 14 deletions(-) diff --git a/enrol/manual/amd/build/quickenrolment.min.js b/enrol/manual/amd/build/quickenrolment.min.js index 1ae2fd7d24e..a08ba79e625 100644 --- a/enrol/manual/amd/build/quickenrolment.min.js +++ b/enrol/manual/amd/build/quickenrolment.min.js @@ -1,2 +1,2 @@ -define ("enrol_manual/quickenrolment",["core/templates","jquery","core/str","core/config","core/notification","core/modal_factory","core/modal_events","core/fragment"],function(a,b,c,d,f,g,h,i){var j={COHORTSELECT:"#id_cohortlist",TRIGGERBUTTONS:".enrolusersbutton.enrol_manual_plugin [type='submit']",UNWANTEDHIDDENFIELDS:":input[value='_qf__force_multiselect_submission']"},k=function(a){this.contextid=a.contextid;this.initModal()};k.prototype.courseid=0;k.prototype.modal=null;k.prototype.initModal=function(){var a=b(j.TRIGGERBUTTONS);b.when(c.get_strings([{key:"enroluserscohorts",component:"enrol_manual"},{key:"enrolusers",component:"enrol_manual"}]),g.create({type:g.types.SAVE_CANCEL,large:!0},a)).then(function(a,c){this.modal=c;c.setTitle(a[1]);c.setSaveButtonText(a[1]);c.getRoot().on(h.save,this.submitForm.bind(this));c.getRoot().on("submit","form",this.submitFormAjax.bind(this));c.getRoot().on(h.hidden,function(){c.setBody("")});c.getRoot().on(h.shown,function(){var d=this.getBody();d.then(function(d){var e=b(d).find(j.COHORTSELECT).length?0:1;c.setSaveButtonText(a[e])}).fail(f.exception);c.setBody(d)}.bind(this))}.bind(this)).fail(f.exception)};k.prototype.submitForm=function(a){a.preventDefault();this.modal.getRoot().find("form").submit()};k.prototype.submitFormAjax=function(a){a.preventDefault();var c=this.modal.getRoot().find("form"),e=c.find(j.UNWANTEDHIDDENFIELDS);e.each(function(){b(this).remove()});var g=c.serialize();this.modal.hide();var h=d.wwwroot+"/enrol/manual/ajax.php?"+g;b.ajax(h,{type:"GET",processData:!1,contentType:"application/json"}).then(function(a){if(a.error){f.addNotification({message:a.error,type:"error"})}else{if("undefined"!=typeof window.M.core_formchangechecker){window.M.core_formchangechecker.reset_form_dirty_state()}window.location.reload()}}).fail(f.exception)};k.prototype.getBody=function(){return i.loadFragment("enrol_manual","enrol_users_form",this.contextid,{}).fail(f.exception)};k.prototype.getFooter=function(){return a.render("enrol_manual/enrol_modal_footer",{})};return{init:function init(a){new k(a)}}}); +define ("enrol_manual/quickenrolment",["core/templates","jquery","core/str","core/config","core/notification","core/modal_factory","core/modal_events","core/fragment","core/pending"],function(a,b,c,d,f,g,h,i,j){var k={COHORTSELECT:"#id_cohortlist",TRIGGERBUTTONS:".enrolusersbutton.enrol_manual_plugin [type='submit']",UNWANTEDHIDDENFIELDS:":input[value='_qf__force_multiselect_submission']"},l=function(a){this.contextid=a.contextid;this.initModal()};l.prototype.courseid=0;l.prototype.modal=null;l.prototype.initModal=function(){var a=b(k.TRIGGERBUTTONS);b.when(c.get_strings([{key:"enroluserscohorts",component:"enrol_manual"},{key:"enrolusers",component:"enrol_manual"}]),g.create({type:g.types.SAVE_CANCEL,large:!0},a)).then(function(a,c){this.modal=c;c.setTitle(a[1]);c.setSaveButtonText(a[1]);c.getRoot().on(h.save,this.submitForm.bind(this));c.getRoot().on("submit","form",this.submitFormAjax.bind(this));c.getRoot().on(h.hidden,function(){c.setBody("")});c.getRoot().on(h.shown,function(){var d=new j("enrol_manual/quickenrolment:initModal:shown"),e=this.getBody();e.then(function(d){var e=b(d).find(k.COHORTSELECT).length?0:1;c.setSaveButtonText(a[e])}).then(d.resolve).catch(f.exception);c.setBody(e)}.bind(this))}.bind(this)).fail(f.exception)};l.prototype.submitForm=function(a){a.preventDefault();this.modal.getRoot().find("form").submit()};l.prototype.submitFormAjax=function(a){a.preventDefault();var c=this.modal.getRoot().find("form"),e=c.find(k.UNWANTEDHIDDENFIELDS);e.each(function(){b(this).remove()});var g=c.serialize();this.modal.hide();var h=d.wwwroot+"/enrol/manual/ajax.php?"+g;b.ajax(h,{type:"GET",processData:!1,contentType:"application/json"}).then(function(a){if(a.error){f.addNotification({message:a.error,type:"error"})}else{if("undefined"!=typeof window.M.core_formchangechecker){window.M.core_formchangechecker.reset_form_dirty_state()}window.location.reload()}}).fail(f.exception)};l.prototype.getBody=function(){return i.loadFragment("enrol_manual","enrol_users_form",this.contextid,{}).fail(f.exception)};l.prototype.getFooter=function(){return a.render("enrol_manual/enrol_modal_footer",{})};return{init:function init(a){new l(a)}}}); //# sourceMappingURL=quickenrolment.min.js.map diff --git a/enrol/manual/amd/build/quickenrolment.min.js.map b/enrol/manual/amd/build/quickenrolment.min.js.map index b408f4bd673..d8e65c31ae0 100644 --- a/enrol/manual/amd/build/quickenrolment.min.js.map +++ b/enrol/manual/amd/build/quickenrolment.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/quickenrolment.js"],"names":["define","Template","$","Str","Config","Notification","ModalFactory","ModalEvents","Fragment","SELECTORS","COHORTSELECT","TRIGGERBUTTONS","UNWANTEDHIDDENFIELDS","QuickEnrolment","options","contextid","initModal","prototype","courseid","modal","triggerButtons","when","get_strings","key","component","create","type","types","SAVE_CANCEL","large","then","strings","setTitle","setSaveButtonText","getRoot","on","save","submitForm","bind","submitFormAjax","hidden","setBody","shown","bodyPromise","getBody","html","stringIndex","find","length","fail","exception","e","preventDefault","submit","form","each","remove","formData","serialize","hide","script","wwwroot","ajax","processData","contentType","response","error","addNotification","message","window","M","core_formchangechecker","reset_form_dirty_state","location","reload","loadFragment","getFooter","render","init","config"],"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 .\n\n/**\n * Quick enrolment AMD module.\n *\n * @module enrol_manual/quickenrolment\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['core/templates',\n 'jquery',\n 'core/str',\n 'core/config',\n 'core/notification',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/fragment',\n ],\n function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment) {\n\n /** @type {Object} The list of selectors for the quick enrolment modal. */\n var SELECTORS = {\n COHORTSELECT: \"#id_cohortlist\",\n TRIGGERBUTTONS: \".enrolusersbutton.enrol_manual_plugin [type='submit']\",\n UNWANTEDHIDDENFIELDS: \":input[value='_qf__force_multiselect_submission']\"\n };\n\n /**\n * Constructor\n *\n * @param {Object} options Object containing options. The only valid option at this time is contextid.\n * Each call to templates.render gets it's own instance of this class.\n */\n var QuickEnrolment = function(options) {\n this.contextid = options.contextid;\n\n this.initModal();\n };\n // Class variables and functions.\n\n /** @var {number} courseid - */\n QuickEnrolment.prototype.courseid = 0;\n\n /** @var {Modal} modal */\n QuickEnrolment.prototype.modal = null;\n\n /**\n * Private method\n *\n * @method initModal\n * @private\n */\n QuickEnrolment.prototype.initModal = function() {\n var triggerButtons = $(SELECTORS.TRIGGERBUTTONS);\n\n $.when(\n Str.get_strings([\n {key: 'enroluserscohorts', component: 'enrol_manual'},\n {key: 'enrolusers', component: 'enrol_manual'},\n ]),\n ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n large: true,\n }, triggerButtons)\n )\n .then(function(strings, modal) {\n this.modal = modal;\n\n modal.setTitle(strings[1]);\n modal.setSaveButtonText(strings[1]);\n\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n // We want the reset the form every time it is opened.\n modal.getRoot().on(ModalEvents.hidden, function() {\n modal.setBody('');\n });\n\n modal.getRoot().on(ModalEvents.shown, function() {\n var bodyPromise = this.getBody();\n bodyPromise.then(function(html) {\n var stringIndex = $(html).find(SELECTORS.COHORTSELECT).length ? 0 : 1;\n modal.setSaveButtonText(strings[stringIndex]);\n\n return;\n })\n .fail(Notification.exception);\n\n modal.setBody(bodyPromise);\n }.bind(this));\n\n return;\n }.bind(this))\n .fail(Notification.exception);\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n QuickEnrolment.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n /**\n * Private method\n *\n * @method submitForm\n * @private\n * @param {Event} e Form submission event.\n */\n QuickEnrolment.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n var form = this.modal.getRoot().find('form');\n\n // Before send the data through AJAX, we need to parse and remove some unwanted hidden fields.\n // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.\n var hidden = form.find(SELECTORS.UNWANTEDHIDDENFIELDS);\n hidden.each(function() {\n $(this).remove();\n });\n\n var formData = form.serialize();\n\n this.modal.hide();\n\n var settings = {\n type: 'GET',\n processData: false,\n contentType: \"application/json\"\n };\n\n var script = Config.wwwroot + '/enrol/manual/ajax.php?' + formData;\n $.ajax(script, settings)\n .then(function(response) {\n\n if (response.error) {\n Notification.addNotification({\n message: response.error,\n type: \"error\"\n });\n } else {\n // Reload the page, don't show changed data warnings.\n if (typeof window.M.core_formchangechecker !== \"undefined\") {\n window.M.core_formchangechecker.reset_form_dirty_state();\n }\n window.location.reload();\n }\n return;\n })\n .fail(Notification.exception);\n };\n\n /**\n * Private method\n *\n * @method getBody\n * @private\n * @return {Promise}\n */\n QuickEnrolment.prototype.getBody = function() {\n return Fragment.loadFragment('enrol_manual', 'enrol_users_form', this.contextid, {}).fail(Notification.exception);\n };\n\n /**\n * Private method\n *\n * @method getFooter\n * @private\n * @return {Promise}\n */\n QuickEnrolment.prototype.getFooter = function() {\n return Template.render('enrol_manual/enrol_modal_footer', {});\n };\n\n return /** @alias module:enrol_manual/quickenrolment */ {\n // Public variables and functions.\n /**\n * Every call to init creates a new instance of the class with it's own event listeners etc.\n *\n * @method init\n * @public\n * @param {object} config - config variables for the module.\n */\n init: function(config) {\n (new QuickEnrolment(config));\n }\n };\n});\n"],"file":"quickenrolment.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/quickenrolment.js"],"names":["define","Template","$","Str","Config","Notification","ModalFactory","ModalEvents","Fragment","Pending","SELECTORS","COHORTSELECT","TRIGGERBUTTONS","UNWANTEDHIDDENFIELDS","QuickEnrolment","options","contextid","initModal","prototype","courseid","modal","triggerButtons","when","get_strings","key","component","create","type","types","SAVE_CANCEL","large","then","strings","setTitle","setSaveButtonText","getRoot","on","save","submitForm","bind","submitFormAjax","hidden","setBody","shown","pendingPromise","bodyPromise","getBody","html","stringIndex","find","length","resolve","catch","exception","fail","e","preventDefault","submit","form","each","remove","formData","serialize","hide","script","wwwroot","ajax","processData","contentType","response","error","addNotification","message","window","M","core_formchangechecker","reset_form_dirty_state","location","reload","loadFragment","getFooter","render","init","config"],"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 .\n\n/**\n * Quick enrolment AMD module.\n *\n * @module enrol_manual/quickenrolment\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['core/templates',\n 'jquery',\n 'core/str',\n 'core/config',\n 'core/notification',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/fragment',\n 'core/pending',\n ],\n function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment, Pending) {\n\n /** @type {Object} The list of selectors for the quick enrolment modal. */\n var SELECTORS = {\n COHORTSELECT: \"#id_cohortlist\",\n TRIGGERBUTTONS: \".enrolusersbutton.enrol_manual_plugin [type='submit']\",\n UNWANTEDHIDDENFIELDS: \":input[value='_qf__force_multiselect_submission']\"\n };\n\n /**\n * Constructor\n *\n * @param {Object} options Object containing options. The only valid option at this time is contextid.\n * Each call to templates.render gets it's own instance of this class.\n */\n var QuickEnrolment = function(options) {\n this.contextid = options.contextid;\n\n this.initModal();\n };\n // Class variables and functions.\n\n /** @var {number} courseid - */\n QuickEnrolment.prototype.courseid = 0;\n\n /** @var {Modal} modal */\n QuickEnrolment.prototype.modal = null;\n\n /**\n * Private method\n *\n * @method initModal\n * @private\n */\n QuickEnrolment.prototype.initModal = function() {\n var triggerButtons = $(SELECTORS.TRIGGERBUTTONS);\n\n $.when(\n Str.get_strings([\n {key: 'enroluserscohorts', component: 'enrol_manual'},\n {key: 'enrolusers', component: 'enrol_manual'},\n ]),\n ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n large: true,\n }, triggerButtons)\n )\n .then(function(strings, modal) {\n this.modal = modal;\n\n modal.setTitle(strings[1]);\n modal.setSaveButtonText(strings[1]);\n\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n // We want the reset the form every time it is opened.\n modal.getRoot().on(ModalEvents.hidden, function() {\n modal.setBody('');\n });\n\n modal.getRoot().on(ModalEvents.shown, function() {\n var pendingPromise = new Pending('enrol_manual/quickenrolment:initModal:shown');\n var bodyPromise = this.getBody();\n bodyPromise.then(function(html) {\n var stringIndex = $(html).find(SELECTORS.COHORTSELECT).length ? 0 : 1;\n modal.setSaveButtonText(strings[stringIndex]);\n\n return;\n })\n .then(pendingPromise.resolve)\n .catch(Notification.exception);\n\n modal.setBody(bodyPromise);\n }.bind(this));\n\n return;\n }.bind(this))\n .fail(Notification.exception);\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n QuickEnrolment.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n /**\n * Private method\n *\n * @method submitForm\n * @private\n * @param {Event} e Form submission event.\n */\n QuickEnrolment.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n var form = this.modal.getRoot().find('form');\n\n // Before send the data through AJAX, we need to parse and remove some unwanted hidden fields.\n // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.\n var hidden = form.find(SELECTORS.UNWANTEDHIDDENFIELDS);\n hidden.each(function() {\n $(this).remove();\n });\n\n var formData = form.serialize();\n\n this.modal.hide();\n\n var settings = {\n type: 'GET',\n processData: false,\n contentType: \"application/json\"\n };\n\n var script = Config.wwwroot + '/enrol/manual/ajax.php?' + formData;\n $.ajax(script, settings)\n .then(function(response) {\n\n if (response.error) {\n Notification.addNotification({\n message: response.error,\n type: \"error\"\n });\n } else {\n // Reload the page, don't show changed data warnings.\n if (typeof window.M.core_formchangechecker !== \"undefined\") {\n window.M.core_formchangechecker.reset_form_dirty_state();\n }\n window.location.reload();\n }\n return;\n })\n .fail(Notification.exception);\n };\n\n /**\n * Private method\n *\n * @method getBody\n * @private\n * @return {Promise}\n */\n QuickEnrolment.prototype.getBody = function() {\n return Fragment.loadFragment('enrol_manual', 'enrol_users_form', this.contextid, {}).fail(Notification.exception);\n };\n\n /**\n * Private method\n *\n * @method getFooter\n * @private\n * @return {Promise}\n */\n QuickEnrolment.prototype.getFooter = function() {\n return Template.render('enrol_manual/enrol_modal_footer', {});\n };\n\n return /** @alias module:enrol_manual/quickenrolment */ {\n // Public variables and functions.\n /**\n * Every call to init creates a new instance of the class with it's own event listeners etc.\n *\n * @method init\n * @public\n * @param {object} config - config variables for the module.\n */\n init: function(config) {\n (new QuickEnrolment(config));\n }\n };\n});\n"],"file":"quickenrolment.min.js"} \ No newline at end of file diff --git a/enrol/manual/amd/src/quickenrolment.js b/enrol/manual/amd/src/quickenrolment.js index 980581a94fa..74b9e21a6a7 100644 --- a/enrol/manual/amd/src/quickenrolment.js +++ b/enrol/manual/amd/src/quickenrolment.js @@ -28,8 +28,9 @@ define(['core/templates', 'core/modal_factory', 'core/modal_events', 'core/fragment', + 'core/pending', ], - function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment) { + function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment, Pending) { /** @type {Object} The list of selectors for the quick enrolment modal. */ var SELECTORS = { @@ -91,6 +92,7 @@ define(['core/templates', }); modal.getRoot().on(ModalEvents.shown, function() { + var pendingPromise = new Pending('enrol_manual/quickenrolment:initModal:shown'); var bodyPromise = this.getBody(); bodyPromise.then(function(html) { var stringIndex = $(html).find(SELECTORS.COHORTSELECT).length ? 0 : 1; @@ -98,7 +100,8 @@ define(['core/templates', return; }) - .fail(Notification.exception); + .then(pendingPromise.resolve) + .catch(Notification.exception); modal.setBody(bodyPromise); }.bind(this)); diff --git a/lib/amd/build/modal.min.js b/lib/amd/build/modal.min.js index e54631ad964..3269e6e7d7b 100644 --- a/lib/amd/build/modal.min.js +++ b/lib/amd/build/modal.min.js @@ -1,2 +1,2 @@ -function _typeof(a){if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core/modal",["jquery","core/templates","core/notification","core/key_codes","core/custom_interaction_events","core/modal_backdrop","core/event","core/modal_events","core/local/aria/focuslock"],function(a,b,c,d,e,f,g,h,i){var j={CONTAINER:"[data-region=\"modal-container\"]",MODAL:"[data-region=\"modal\"]",HEADER:"[data-region=\"header\"]",TITLE:"[data-region=\"title\"]",BODY:"[data-region=\"body\"]",FOOTER:"[data-region=\"footer\"]",HIDE:"[data-action=\"hide\"]",DIALOG:"[role=dialog]",FORM:"form",MENU_BAR:"[role=menubar]",HAS_Z_INDEX:".moodle-has-zindex",CAN_RECEIVE_FOCUS:"input:not([type=\"hidden\"]), a[href], button, textarea, select, [tabindex]"},k={LOADING:"core/loading",BACKDROP:"core/modal_backdrop"},l,m=0,n=function(b){this.root=a(b);this.modal=this.root.find(j.MODAL);this.header=this.modal.find(j.HEADER);this.headerPromise=a.Deferred();this.title=this.header.find(j.TITLE);this.titlePromise=a.Deferred();this.body=this.modal.find(j.BODY);this.bodyPromise=a.Deferred();this.footer=this.modal.find(j.FOOTER);this.footerPromise=a.Deferred();this.hiddenSiblings=[];this.isAttached=!1;this.bodyJS=null;this.footerJS=null;this.modalCount=m++;if(!this.root.is(j.CONTAINER)){c.exception({message:"Element is not a modal container"})}if(!this.modal.length){c.exception({message:"Container does not contain a modal"})}if(!this.header.length){c.exception({message:"Modal is missing a header region"})}if(!this.title.length){c.exception({message:"Modal header is missing a title region"})}if(!this.body.length){c.exception({message:"Modal is missing a body region"})}if(!this.footer.length){c.exception({message:"Modal is missing a footer region"})}this.registerEventListeners()};n.prototype.attachToDOM=function(){if(this.isAttached){return}a("body").append(this.root);i.trapFocus(this.root[0]);if(this.bodyJS){b.runTemplateJS(this.bodyJS);this.bodyJS=null}if(this.footerJS){b.runTemplateJS(this.footerJS);this.footerJS=null}this.isAttached=!0};n.prototype.countOtherVisibleModals=function(){var b=0;a("body").find(j.CONTAINER).each(function(c,d){d=a(d);if(!this.root.is(d)&&d.hasClass("show")){b++}}.bind(this));return b};n.prototype.getBackdrop=function(){if(!l){l=b.render(k.BACKDROP,{}).then(function(b){var c=a(b);return new f(c)}).fail(c.exception)}return l};n.prototype.getRoot=function(){return this.root};n.prototype.getModal=function(){return this.modal};n.prototype.getTitle=function(){return this.title};n.prototype.getBody=function(){return this.body};n.prototype.getFooter=function(){return this.footer};n.prototype.getTitlePromise=function(){return this.titlePromise};n.prototype.getBodyPromise=function(){return this.bodyPromise};n.prototype.getFooterPromise=function(){return this.footerPromise};n.prototype.getModalCount=function(){return this.modalCount};n.prototype.setTitle=function(b){var d=this.getTitle();this.titlePromise=a.Deferred();this.asyncSet(b,d.html.bind(d)).then(function(){this.titlePromise.resolve(d)}.bind(this)).catch(c.exception)};n.prototype.setBody=function(d){this.bodyPromise=a.Deferred();var e=this.getBody();if("string"==typeof d){e.html(d);g.notifyFilterContentUpdated(e);this.getRoot().trigger(h.bodyRendered,this);this.bodyPromise.resolve(e)}else{var f="amd-modal-js-pending-id-"+this.getModalCount();M.util.js_pending(f);var i=null;e.css("overflow","hidden");if("pending"==d.state()){var j=e.innerHeight();if(100>j){j=100}e.animate({height:j+"px"},150);e.html("");i=b.render(k.LOADING,{}).then(function(b){var c=a(b).hide();e.html(c);c.fadeIn(150);return a.when(c.promise(),d)}).then(function(a){return a.fadeOut(100).promise()}).then(function(){return d})}else{i=d}i.then(function(a,c){var d=null;if(this.isVisible()){e.css("opacity",0);var f=e.innerHeight();e.html(a);e.css("height","");var g=e.innerHeight();e.css("height",f+"px");d=e.animate({height:g+"px",opacity:1},{duration:150,queue:!1}).promise()}else{e.html(a)}if(c){if(this.isAttached){b.runTemplateJS(c)}else{this.bodyJS=c}}return d}.bind(this)).then(function(a){g.notifyFilterContentUpdated(e);this.getRoot().trigger(h.bodyRendered,this);return a}.bind(this)).then(function(){this.bodyPromise.resolve(e)}.bind(this)).fail(c.exception).always(function(){e.css("height","");e.css("overflow","");e.css("opacity","");M.util.js_complete(f)}).fail(c.exception)}};n.prototype.setFooter=function(d){this.showFooter();this.footerPromise=a.Deferred();var e=this.getFooter();if("string"==typeof d){e.html(d);this.footerPromise.resolve(e)}else{b.render(k.LOADING,{}).then(function(a){e.html(a);return d}).then(function(a,c){e.html(a);if(c){if(this.isAttached){b.runTemplateJS(c)}else{this.footerJS=c}}return e}.bind(this)).then(function(a){this.footerPromise.resolve(a)}.bind(this)).catch(c.exception)}};n.prototype.hasFooterContent=function(){return this.getFooter().children().length?!0:!1};n.prototype.hideFooter=function(){this.getFooter().addClass("hidden")};n.prototype.showFooter=function(){this.getFooter().removeClass("hidden")};n.prototype.setLarge=function(){if(this.isLarge()){return}this.getModal().addClass("modal-lg")};n.prototype.isLarge=function(){return this.getModal().hasClass("modal-lg")};n.prototype.setSmall=function(){if(this.isSmall()){return}this.getModal().removeClass("modal-lg")};n.prototype.isSmall=function(){return!this.getModal().hasClass("modal-lg")};n.prototype.calculateZIndex=function(){var b=a(j.DIALOG+", "+j.MENU_BAR+", "+j.HAS_Z_INDEX),c=parseInt(this.root.css("z-index"));b.each(function(b,d){d=a(d);var e=d.css("z-index")?parseInt(d.css("z-index")):0;if(e>c){c=e}});return c};n.prototype.isVisible=function(){return this.root.hasClass("show")};n.prototype.hasFocus=function(){var b=a(document.activeElement);return this.root.is(b)||this.root.has(b).length};n.prototype.hasTransitions=function(){return this.getRoot().hasClass("fade")};n.prototype.show=function(){if(this.isVisible()){return}if(this.hasFooterContent()){this.showFooter()}else{this.hideFooter()}if(!this.isAttached){this.attachToDOM()}this.getBackdrop().done(function(b){var c=this.calculateZIndex(),d=c+2;this.root.css("z-index",d);b.setZIndex(d-1);b.show();this.root.removeClass("hide").addClass("show");this.accessibilityShow();this.getModal().focus();a("body").addClass("modal-open");this.root.trigger(h.shown,this)}.bind(this))};n.prototype.hideIfNotForm=function(){var a=this.modal.find(j.FORM);if(0==a.length){this.hide()}};n.prototype.hide=function(){this.getBackdrop().done(function(b){i.untrapFocus();if(!this.countOtherVisibleModals()){b.hide();a("body").removeClass("modal-open")}var c=parseInt(this.root.css("z-index"));this.root.css("z-index","");b.setZIndex(c-3);this.accessibilityHide();if(this.hasTransitions()){this.getRoot().one("transitionend webkitTransitionEnd oTransitionEnd",function(){this.getRoot().removeClass("show").addClass("hide")}.bind(this))}else{this.getRoot().removeClass("show").addClass("hide")}this.root.trigger(h.hidden,this)}.bind(this))};n.prototype.destroy=function(){this.root.remove();this.root.trigger(h.destroyed,this)};n.prototype.accessibilityShow=function(){a("body").children().each(function(b,c){if(!this.root.is(c)){c=a(c);var d=c.attr("aria-hidden");if("true"!==d){c.data("previous-aria-hidden",d);this.hiddenSiblings.push(c);c.attr("aria-hidden","true")}}}.bind(this));this.root.attr("aria-hidden","false")};n.prototype.accessibilityHide=function(){this.root.attr("aria-hidden","true");a.each(this.hiddenSiblings,function(b,c){c=a(c);var d=c.data("previous-aria-hidden");if("undefined"==typeof d){c.removeAttr("aria-hidden")}else{c.attr("aria-hidden",d)}});this.hiddenSiblings=[]};n.prototype.registerEventListeners=function(){this.getRoot().on("keydown",function(a){if(!this.isVisible()){return}if(a.keyCode==d.escape){this.hide()}}.bind(this));this.getRoot().click(function(b){if(!a(b.target).closest(j.MODAL).length){if(a(b.target).closest(j.CONTAINER).length){this.hideIfNotForm()}}}.bind(this));e.define(this.getModal(),[e.events.activate]);this.getModal().on(e.events.activate,j.HIDE,function(a,b){this.hide();b.originalEvent.preventDefault()}.bind(this))};n.prototype.asyncSet=function(b,d){var e=b;if("object"!==_typeof(b)||!b.hasOwnProperty("then")){e=a.Deferred();e.resolve(b)}e.then(function(a){d(a)}).fail(c.exception);return e};return n}); +function _typeof(a){if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core/modal",["jquery","core/templates","core/notification","core/key_codes","core/custom_interaction_events","core/modal_backdrop","core/event","core/modal_events","core/local/aria/focuslock","core/pending"],function(a,b,c,d,e,f,g,h,i,j){var k={CONTAINER:"[data-region=\"modal-container\"]",MODAL:"[data-region=\"modal\"]",HEADER:"[data-region=\"header\"]",TITLE:"[data-region=\"title\"]",BODY:"[data-region=\"body\"]",FOOTER:"[data-region=\"footer\"]",HIDE:"[data-action=\"hide\"]",DIALOG:"[role=dialog]",FORM:"form",MENU_BAR:"[role=menubar]",HAS_Z_INDEX:".moodle-has-zindex",CAN_RECEIVE_FOCUS:"input:not([type=\"hidden\"]), a[href], button, textarea, select, [tabindex]"},l={LOADING:"core/loading",BACKDROP:"core/modal_backdrop"},m,n=0,o=function(b){this.root=a(b);this.modal=this.root.find(k.MODAL);this.header=this.modal.find(k.HEADER);this.headerPromise=a.Deferred();this.title=this.header.find(k.TITLE);this.titlePromise=a.Deferred();this.body=this.modal.find(k.BODY);this.bodyPromise=a.Deferred();this.footer=this.modal.find(k.FOOTER);this.footerPromise=a.Deferred();this.hiddenSiblings=[];this.isAttached=!1;this.bodyJS=null;this.footerJS=null;this.modalCount=n++;if(!this.root.is(k.CONTAINER)){c.exception({message:"Element is not a modal container"})}if(!this.modal.length){c.exception({message:"Container does not contain a modal"})}if(!this.header.length){c.exception({message:"Modal is missing a header region"})}if(!this.title.length){c.exception({message:"Modal header is missing a title region"})}if(!this.body.length){c.exception({message:"Modal is missing a body region"})}if(!this.footer.length){c.exception({message:"Modal is missing a footer region"})}this.registerEventListeners()};o.prototype.attachToDOM=function(){if(this.isAttached){return}a("body").append(this.root);i.trapFocus(this.root[0]);if(this.bodyJS){b.runTemplateJS(this.bodyJS);this.bodyJS=null}if(this.footerJS){b.runTemplateJS(this.footerJS);this.footerJS=null}this.isAttached=!0};o.prototype.countOtherVisibleModals=function(){var b=0;a("body").find(k.CONTAINER).each(function(c,d){d=a(d);if(!this.root.is(d)&&d.hasClass("show")){b++}}.bind(this));return b};o.prototype.getBackdrop=function(){if(!m){m=b.render(l.BACKDROP,{}).then(function(b){var c=a(b);return new f(c)}).fail(c.exception)}return m};o.prototype.getRoot=function(){return this.root};o.prototype.getModal=function(){return this.modal};o.prototype.getTitle=function(){return this.title};o.prototype.getBody=function(){return this.body};o.prototype.getFooter=function(){return this.footer};o.prototype.getTitlePromise=function(){return this.titlePromise};o.prototype.getBodyPromise=function(){return this.bodyPromise};o.prototype.getFooterPromise=function(){return this.footerPromise};o.prototype.getModalCount=function(){return this.modalCount};o.prototype.setTitle=function(b){var d=this.getTitle();this.titlePromise=a.Deferred();this.asyncSet(b,d.html.bind(d)).then(function(){this.titlePromise.resolve(d)}.bind(this)).catch(c.exception)};o.prototype.setBody=function(d){this.bodyPromise=a.Deferred();var e=this.getBody();if("string"==typeof d){e.html(d);g.notifyFilterContentUpdated(e);this.getRoot().trigger(h.bodyRendered,this);this.bodyPromise.resolve(e)}else{var f="amd-modal-js-pending-id-"+this.getModalCount();M.util.js_pending(f);var i=null;e.css("overflow","hidden");if("pending"==d.state()){var j=e.innerHeight();if(100>j){j=100}e.animate({height:j+"px"},150);e.html("");i=b.render(l.LOADING,{}).then(function(b){var c=a(b).hide();e.html(c);c.fadeIn(150);return a.when(c.promise(),d)}).then(function(a){return a.fadeOut(100).promise()}).then(function(){return d})}else{i=d}i.then(function(a,c){var d=null;if(this.isVisible()){e.css("opacity",0);var f=e.innerHeight();e.html(a);e.css("height","");var g=e.innerHeight();e.css("height",f+"px");d=e.animate({height:g+"px",opacity:1},{duration:150,queue:!1}).promise()}else{e.html(a)}if(c){if(this.isAttached){b.runTemplateJS(c)}else{this.bodyJS=c}}return d}.bind(this)).then(function(a){g.notifyFilterContentUpdated(e);this.getRoot().trigger(h.bodyRendered,this);return a}.bind(this)).then(function(){this.bodyPromise.resolve(e)}.bind(this)).fail(c.exception).always(function(){e.css("height","");e.css("overflow","");e.css("opacity","");M.util.js_complete(f)}).fail(c.exception)}};o.prototype.setFooter=function(d){this.showFooter();this.footerPromise=a.Deferred();var e=this.getFooter();if("string"==typeof d){e.html(d);this.footerPromise.resolve(e)}else{b.render(l.LOADING,{}).then(function(a){e.html(a);return d}).then(function(a,c){e.html(a);if(c){if(this.isAttached){b.runTemplateJS(c)}else{this.footerJS=c}}return e}.bind(this)).then(function(a){this.footerPromise.resolve(a)}.bind(this)).catch(c.exception)}};o.prototype.hasFooterContent=function(){return this.getFooter().children().length?!0:!1};o.prototype.hideFooter=function(){this.getFooter().addClass("hidden")};o.prototype.showFooter=function(){this.getFooter().removeClass("hidden")};o.prototype.setLarge=function(){if(this.isLarge()){return}this.getModal().addClass("modal-lg")};o.prototype.isLarge=function(){return this.getModal().hasClass("modal-lg")};o.prototype.setSmall=function(){if(this.isSmall()){return}this.getModal().removeClass("modal-lg")};o.prototype.isSmall=function(){return!this.getModal().hasClass("modal-lg")};o.prototype.calculateZIndex=function(){var b=a(k.DIALOG+", "+k.MENU_BAR+", "+k.HAS_Z_INDEX),c=parseInt(this.root.css("z-index"));b.each(function(b,d){d=a(d);var e=d.css("z-index")?parseInt(d.css("z-index")):0;if(e>c){c=e}});return c};o.prototype.isVisible=function(){return this.root.hasClass("show")};o.prototype.hasFocus=function(){var b=a(document.activeElement);return this.root.is(b)||this.root.has(b).length};o.prototype.hasTransitions=function(){return this.getRoot().hasClass("fade")};o.prototype.show=function(){if(this.isVisible()){return}var b=new j("core/modal:show");if(this.hasFooterContent()){this.showFooter()}else{this.hideFooter()}if(!this.isAttached){this.attachToDOM()}this.getBackdrop().then(function(b){var c=this.calculateZIndex(),d=c+2;this.root.css("z-index",d);b.setZIndex(d-1);b.show();this.root.removeClass("hide").addClass("show");this.accessibilityShow();this.getModal().focus();a("body").addClass("modal-open");this.root.trigger(h.shown,this)}.bind(this)).then(b.resolve)};o.prototype.hideIfNotForm=function(){var a=this.modal.find(k.FORM);if(0==a.length){this.hide()}};o.prototype.hide=function(){this.getBackdrop().done(function(b){i.untrapFocus();if(!this.countOtherVisibleModals()){b.hide();a("body").removeClass("modal-open")}var c=parseInt(this.root.css("z-index"));this.root.css("z-index","");b.setZIndex(c-3);this.accessibilityHide();if(this.hasTransitions()){this.getRoot().one("transitionend webkitTransitionEnd oTransitionEnd",function(){this.getRoot().removeClass("show").addClass("hide")}.bind(this))}else{this.getRoot().removeClass("show").addClass("hide")}this.root.trigger(h.hidden,this)}.bind(this))};o.prototype.destroy=function(){this.root.remove();this.root.trigger(h.destroyed,this)};o.prototype.accessibilityShow=function(){a("body").children().each(function(b,c){if(!this.root.is(c)){c=a(c);var d=c.attr("aria-hidden");if("true"!==d){c.data("previous-aria-hidden",d);this.hiddenSiblings.push(c);c.attr("aria-hidden","true")}}}.bind(this));this.root.attr("aria-hidden","false")};o.prototype.accessibilityHide=function(){this.root.attr("aria-hidden","true");a.each(this.hiddenSiblings,function(b,c){c=a(c);var d=c.data("previous-aria-hidden");if("undefined"==typeof d){c.removeAttr("aria-hidden")}else{c.attr("aria-hidden",d)}});this.hiddenSiblings=[]};o.prototype.registerEventListeners=function(){this.getRoot().on("keydown",function(a){if(!this.isVisible()){return}if(a.keyCode==d.escape){this.hide()}}.bind(this));this.getRoot().click(function(b){if(!a(b.target).closest(k.MODAL).length){if(a(b.target).closest(k.CONTAINER).length){this.hideIfNotForm()}}}.bind(this));e.define(this.getModal(),[e.events.activate]);this.getModal().on(e.events.activate,k.HIDE,function(a,b){this.hide();b.originalEvent.preventDefault()}.bind(this))};o.prototype.asyncSet=function(b,d){var e=b;if("object"!==_typeof(b)||!b.hasOwnProperty("then")){e=a.Deferred();e.resolve(b)}e.then(function(a){d(a)}).fail(c.exception);return e};return o}); //# sourceMappingURL=modal.min.js.map diff --git a/lib/amd/build/modal.min.js.map b/lib/amd/build/modal.min.js.map index 0a501e573de..5b24706db59 100644 --- a/lib/amd/build/modal.min.js.map +++ b/lib/amd/build/modal.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/modal.js"],"names":["define","$","Templates","Notification","KeyCodes","CustomEvents","ModalBackdrop","Event","ModalEvents","FocusLock","SELECTORS","CONTAINER","MODAL","HEADER","TITLE","BODY","FOOTER","HIDE","DIALOG","FORM","MENU_BAR","HAS_Z_INDEX","CAN_RECEIVE_FOCUS","TEMPLATES","LOADING","BACKDROP","backdropPromise","modalCounter","Modal","root","modal","find","header","headerPromise","Deferred","title","titlePromise","body","bodyPromise","footer","footerPromise","hiddenSiblings","isAttached","bodyJS","footerJS","modalCount","is","exception","message","length","registerEventListeners","prototype","attachToDOM","append","trapFocus","runTemplateJS","countOtherVisibleModals","count","each","index","element","hasClass","bind","getBackdrop","render","then","html","fail","getRoot","getModal","getTitle","getBody","getFooter","getTitlePromise","getBodyPromise","getFooterPromise","getModalCount","setTitle","value","asyncSet","resolve","catch","setBody","notifyFilterContentUpdated","trigger","bodyRendered","jsPendingId","M","util","js_pending","contentPromise","css","state","height","innerHeight","animate","loadingIcon","hide","fadeIn","when","promise","fadeOut","js","result","isVisible","currentHeight","newHeight","opacity","duration","queue","always","js_complete","setFooter","showFooter","hasFooterContent","children","hideFooter","addClass","removeClass","setLarge","isLarge","setSmall","isSmall","calculateZIndex","items","zIndex","parseInt","item","itemZIndex","hasFocus","target","document","activeElement","has","hasTransitions","show","done","backdrop","currentIndex","newIndex","setZIndex","accessibilityShow","focus","shown","hideIfNotForm","formElement","untrapFocus","accessibilityHide","one","hidden","destroy","remove","destroyed","child","attr","data","push","sibling","previousValue","removeAttr","on","e","keyCode","escape","click","closest","events","activate","originalEvent","preventDefault","setFunction","p","hasOwnProperty","content"],"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 .\n\n/**\n * Contain the logic for modals.\n *\n * @module core/modal\n * @class modal\n * @package core\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'core/key_codes',\n 'core/custom_interaction_events',\n 'core/modal_backdrop',\n 'core/event',\n 'core/modal_events',\n 'core/local/aria/focuslock',\n], function($, Templates, Notification, KeyCodes, CustomEvents, ModalBackdrop, Event, ModalEvents, FocusLock) {\n\n var SELECTORS = {\n CONTAINER: '[data-region=\"modal-container\"]',\n MODAL: '[data-region=\"modal\"]',\n HEADER: '[data-region=\"header\"]',\n TITLE: '[data-region=\"title\"]',\n BODY: '[data-region=\"body\"]',\n FOOTER: '[data-region=\"footer\"]',\n HIDE: '[data-action=\"hide\"]',\n DIALOG: '[role=dialog]',\n FORM: 'form',\n MENU_BAR: '[role=menubar]',\n HAS_Z_INDEX: '.moodle-has-zindex',\n CAN_RECEIVE_FOCUS: 'input:not([type=\"hidden\"]), a[href], button, textarea, select, [tabindex]',\n };\n\n var TEMPLATES = {\n LOADING: 'core/loading',\n BACKDROP: 'core/modal_backdrop',\n };\n\n /**\n * Module singleton for the backdrop to be reused by all Modal instances.\n */\n var backdropPromise;\n\n /**\n * A counter that gets incremented for each modal created. This can be\n * used to generate unique values for the modals.\n */\n var modalCounter = 0;\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n var Modal = function(root) {\n this.root = $(root);\n this.modal = this.root.find(SELECTORS.MODAL);\n this.header = this.modal.find(SELECTORS.HEADER);\n this.headerPromise = $.Deferred();\n this.title = this.header.find(SELECTORS.TITLE);\n this.titlePromise = $.Deferred();\n this.body = this.modal.find(SELECTORS.BODY);\n this.bodyPromise = $.Deferred();\n this.footer = this.modal.find(SELECTORS.FOOTER);\n this.footerPromise = $.Deferred();\n this.hiddenSiblings = [];\n this.isAttached = false;\n this.bodyJS = null;\n this.footerJS = null;\n this.modalCount = modalCounter++;\n\n if (!this.root.is(SELECTORS.CONTAINER)) {\n Notification.exception({message: 'Element is not a modal container'});\n }\n\n if (!this.modal.length) {\n Notification.exception({message: 'Container does not contain a modal'});\n }\n\n if (!this.header.length) {\n Notification.exception({message: 'Modal is missing a header region'});\n }\n\n if (!this.title.length) {\n Notification.exception({message: 'Modal header is missing a title region'});\n }\n\n if (!this.body.length) {\n Notification.exception({message: 'Modal is missing a body region'});\n }\n\n if (!this.footer.length) {\n Notification.exception({message: 'Modal is missing a footer region'});\n }\n\n this.registerEventListeners();\n };\n\n /**\n * Add the modal to the page, if it hasn't already been added. This includes running any\n * javascript that has been cached until now.\n *\n * @method attachToDOM\n */\n Modal.prototype.attachToDOM = function() {\n if (this.isAttached) {\n return;\n }\n\n $('body').append(this.root);\n FocusLock.trapFocus(this.root[0]);\n\n // If we'd cached any JS then we can run it how that the modal is\n // attached to the DOM.\n if (this.bodyJS) {\n Templates.runTemplateJS(this.bodyJS);\n this.bodyJS = null;\n }\n\n if (this.footerJS) {\n Templates.runTemplateJS(this.footerJS);\n this.footerJS = null;\n }\n\n this.isAttached = true;\n };\n\n /**\n * Count the number of other visible modals (not including this one).\n *\n * @method countOtherVisibleModals\n * @return {int}\n */\n Modal.prototype.countOtherVisibleModals = function() {\n var count = 0;\n $('body').find(SELECTORS.CONTAINER).each(function(index, element) {\n element = $(element);\n\n // If we haven't found ourself and the element is visible.\n if (!this.root.is(element) && element.hasClass('show')) {\n count++;\n }\n }.bind(this));\n\n return count;\n };\n\n /**\n * Get the modal backdrop.\n *\n * @method getBackdrop\n * @return {object} jQuery promise\n */\n Modal.prototype.getBackdrop = function() {\n if (!backdropPromise) {\n backdropPromise = Templates.render(TEMPLATES.BACKDROP, {})\n .then(function(html) {\n var element = $(html);\n\n return new ModalBackdrop(element);\n })\n .fail(Notification.exception);\n }\n\n return backdropPromise;\n };\n\n /**\n * Get the root element of this modal.\n *\n * @method getRoot\n * @return {object} jQuery object\n */\n Modal.prototype.getRoot = function() {\n return this.root;\n };\n\n /**\n * Get the modal element of this modal.\n *\n * @method getModal\n * @return {object} jQuery object\n */\n Modal.prototype.getModal = function() {\n return this.modal;\n };\n\n /**\n * Get the modal title element.\n *\n * @method getTitle\n * @return {object} jQuery object\n */\n Modal.prototype.getTitle = function() {\n return this.title;\n };\n\n /**\n * Get the modal body element.\n *\n * @method getBody\n * @return {object} jQuery object\n */\n Modal.prototype.getBody = function() {\n return this.body;\n };\n\n /**\n * Get the modal footer element.\n *\n * @method getFooter\n * @return {object} jQuery object\n */\n Modal.prototype.getFooter = function() {\n return this.footer;\n };\n\n /**\n * Get a promise resolving to the title region.\n *\n * @method getTitlePromise\n * @return {Promise}\n */\n Modal.prototype.getTitlePromise = function() {\n return this.titlePromise;\n };\n\n /**\n * Get a promise resolving to the body region.\n *\n * @method getBodyPromise\n * @return {object} jQuery object\n */\n Modal.prototype.getBodyPromise = function() {\n return this.bodyPromise;\n };\n\n /**\n * Get a promise resolving to the footer region.\n *\n * @method getFooterPromise\n * @return {object} jQuery object\n */\n Modal.prototype.getFooterPromise = function() {\n return this.footerPromise;\n };\n\n /**\n * Get the unique modal count.\n *\n * @method getModalCount\n * @return {int}\n */\n Modal.prototype.getModalCount = function() {\n return this.modalCount;\n };\n\n /**\n * Set the modal title element.\n *\n * This method is overloaded to take either a string value for the title or a jQuery promise that is resolved with\n * HTML most commonly from a Str.get_string call.\n *\n * @method setTitle\n * @param {(string|object)} value The title string or jQuery promise which resolves to the title.\n */\n Modal.prototype.setTitle = function(value) {\n var title = this.getTitle();\n this.titlePromise = $.Deferred();\n\n this.asyncSet(value, title.html.bind(title))\n .then(function() {\n this.titlePromise.resolve(title);\n }.bind(this))\n .catch(Notification.exception);\n };\n\n /**\n * Set the modal body element.\n *\n * This method is overloaded to take either a string value for the body or a jQuery promise that is resolved with\n * HTML and Javascript most commonly from a Templates.render call.\n *\n * @method setBody\n * @param {(string|object)} value The body string or jQuery promise which resolves to the body.\n */\n Modal.prototype.setBody = function(value) {\n this.bodyPromise = $.Deferred();\n\n var body = this.getBody();\n\n if (typeof value === 'string') {\n // Just set the value if it's a string.\n body.html(value);\n Event.notifyFilterContentUpdated(body);\n this.getRoot().trigger(ModalEvents.bodyRendered, this);\n this.bodyPromise.resolve(body);\n } else {\n var jsPendingId = 'amd-modal-js-pending-id-' + this.getModalCount();\n M.util.js_pending(jsPendingId);\n // Otherwise we assume it's a promise to be resolved with\n // html and javascript.\n var contentPromise = null;\n body.css('overflow', 'hidden');\n\n if (value.state() == 'pending') {\n // We're still waiting for the body promise to resolve so\n // let's show a loading icon.\n var height = body.innerHeight();\n if (height < 100) {\n height = 100;\n }\n\n body.animate({height: height + 'px'}, 150);\n\n body.html('');\n contentPromise = Templates.render(TEMPLATES.LOADING, {})\n .then(function(html) {\n var loadingIcon = $(html).hide();\n body.html(loadingIcon);\n loadingIcon.fadeIn(150);\n\n // We only want the loading icon to fade out\n // when the content for the body has finished\n // loading.\n return $.when(loadingIcon.promise(), value);\n })\n .then(function(loadingIcon) {\n // Once the content has finished loading and\n // the loading icon has been shown then we can\n // fade the icon away to reveal the content.\n return loadingIcon.fadeOut(100).promise();\n })\n .then(function() {\n return value;\n });\n } else {\n // The content is already loaded so let's just display\n // it to the user. No need for a loading icon.\n contentPromise = value;\n }\n\n // Now we can actually display the content.\n contentPromise.then(function(html, js) {\n var result = null;\n\n if (this.isVisible()) {\n // If the modal is visible then we should display\n // the content gracefully for the user.\n body.css('opacity', 0);\n var currentHeight = body.innerHeight();\n body.html(html);\n // We need to clear any height values we've set here\n // in order to measure the height of the content being\n // added. This then allows us to animate the height\n // transition.\n body.css('height', '');\n var newHeight = body.innerHeight();\n body.css('height', currentHeight + 'px');\n result = body.animate(\n {height: newHeight + 'px', opacity: 1},\n {duration: 150, queue: false}\n ).promise();\n } else {\n // Since the modal isn't visible we can just immediately\n // set the content. No need to animate it.\n body.html(html);\n }\n\n if (js) {\n if (this.isAttached) {\n // If we're in the DOM then run the JS immediately.\n Templates.runTemplateJS(js);\n } else {\n // Otherwise cache it to be run when we're attached.\n this.bodyJS = js;\n }\n }\n\n return result;\n }.bind(this))\n .then(function(result) {\n Event.notifyFilterContentUpdated(body);\n this.getRoot().trigger(ModalEvents.bodyRendered, this);\n return result;\n }.bind(this))\n .then(function() {\n this.bodyPromise.resolve(body);\n return;\n }.bind(this))\n .fail(Notification.exception)\n .always(function() {\n // When we're done displaying all of the content we need\n // to clear the custom values we've set here.\n body.css('height', '');\n body.css('overflow', '');\n body.css('opacity', '');\n M.util.js_complete(jsPendingId);\n\n return;\n })\n .fail(Notification.exception);\n }\n };\n\n /**\n * Set the modal footer element. The footer element is made visible, if it\n * isn't already.\n *\n * This method is overloaded to take either a string\n * value for the body or a jQuery promise that is resolved with HTML and Javascript\n * most commonly from a Templates.render call.\n *\n * @method setFooter\n * @param {(string|object)} value The footer string or jQuery promise\n */\n Modal.prototype.setFooter = function(value) {\n // Make sure the footer is visible.\n this.showFooter();\n this.footerPromise = $.Deferred();\n\n var footer = this.getFooter();\n\n if (typeof value === 'string') {\n // Just set the value if it's a string.\n footer.html(value);\n this.footerPromise.resolve(footer);\n } else {\n // Otherwise we assume it's a promise to be resolved with\n // html and javascript.\n Templates.render(TEMPLATES.LOADING, {})\n .then(function(html) {\n footer.html(html);\n\n return value;\n })\n .then(function(html, js) {\n footer.html(html);\n\n if (js) {\n if (this.isAttached) {\n // If we're in the DOM then run the JS immediately.\n Templates.runTemplateJS(js);\n } else {\n // Otherwise cache it to be run when we're attached.\n this.footerJS = js;\n }\n }\n\n return footer;\n }.bind(this))\n .then(function(footer) {\n this.footerPromise.resolve(footer);\n return;\n }.bind(this))\n .catch(Notification.exception);\n }\n };\n\n /**\n * Check if the footer has any content in it.\n *\n * @method hasFooterContent\n * @return {bool}\n */\n Modal.prototype.hasFooterContent = function() {\n return this.getFooter().children().length ? true : false;\n };\n\n /**\n * Hide the footer element.\n *\n * @method hideFooter\n */\n Modal.prototype.hideFooter = function() {\n this.getFooter().addClass('hidden');\n };\n\n /**\n * Show the footer element.\n *\n * @method showFooter\n */\n Modal.prototype.showFooter = function() {\n this.getFooter().removeClass('hidden');\n };\n\n /**\n * Mark the modal as a large modal.\n *\n * @method setLarge\n */\n Modal.prototype.setLarge = function() {\n if (this.isLarge()) {\n return;\n }\n\n this.getModal().addClass('modal-lg');\n };\n\n /**\n * Check if the modal is a large modal.\n *\n * @method isLarge\n * @return {bool}\n */\n Modal.prototype.isLarge = function() {\n return this.getModal().hasClass('modal-lg');\n };\n\n /**\n * Mark the modal as a small modal.\n *\n * @method setSmall\n */\n Modal.prototype.setSmall = function() {\n if (this.isSmall()) {\n return;\n }\n\n this.getModal().removeClass('modal-lg');\n };\n\n /**\n * Check if the modal is a small modal.\n *\n * @method isSmall\n * @return {bool}\n */\n Modal.prototype.isSmall = function() {\n return !this.getModal().hasClass('modal-lg');\n };\n\n /**\n * Determine the highest z-index value currently on the page.\n *\n * @method calculateZIndex\n * @return {int}\n */\n Modal.prototype.calculateZIndex = function() {\n var items = $(SELECTORS.DIALOG + ', ' + SELECTORS.MENU_BAR + ', ' + SELECTORS.HAS_Z_INDEX);\n var zIndex = parseInt(this.root.css('z-index'));\n\n items.each(function(index, item) {\n item = $(item);\n // Note that webkit browsers won't return the z-index value from the CSS stylesheet\n // if the element doesn't have a position specified. Instead it'll return \"auto\".\n var itemZIndex = item.css('z-index') ? parseInt(item.css('z-index')) : 0;\n\n if (itemZIndex > zIndex) {\n zIndex = itemZIndex;\n }\n });\n\n return zIndex;\n };\n\n /**\n * Check if this modal is visible.\n *\n * @method isVisible\n * @return {bool}\n */\n Modal.prototype.isVisible = function() {\n return this.root.hasClass('show');\n };\n\n /**\n * Check if this modal has focus.\n *\n * @method hasFocus\n * @return {bool}\n */\n Modal.prototype.hasFocus = function() {\n var target = $(document.activeElement);\n return this.root.is(target) || this.root.has(target).length;\n };\n\n /**\n * Check if this modal has CSS transitions applied.\n *\n * @method hasTransitions\n * @return {bool}\n */\n Modal.prototype.hasTransitions = function() {\n return this.getRoot().hasClass('fade');\n };\n\n /**\n * Display this modal. The modal will be attached to the DOM if it hasn't\n * already been.\n *\n * @method show\n */\n Modal.prototype.show = function() {\n if (this.isVisible()) {\n return;\n }\n\n if (this.hasFooterContent()) {\n this.showFooter();\n } else {\n this.hideFooter();\n }\n\n if (!this.isAttached) {\n this.attachToDOM();\n }\n\n this.getBackdrop().done(function(backdrop) {\n var currentIndex = this.calculateZIndex();\n var newIndex = currentIndex + 2;\n var newBackdropIndex = newIndex - 1;\n this.root.css('z-index', newIndex);\n backdrop.setZIndex(newBackdropIndex);\n backdrop.show();\n\n this.root.removeClass('hide').addClass('show');\n this.accessibilityShow();\n this.getModal().focus();\n $('body').addClass('modal-open');\n this.root.trigger(ModalEvents.shown, this);\n }.bind(this));\n };\n\n /**\n * Hide this modal if it does not contain a form.\n *\n * @method hideIfNotForm\n */\n Modal.prototype.hideIfNotForm = function() {\n var formElement = this.modal.find(SELECTORS.FORM);\n if (formElement.length == 0) {\n this.hide();\n }\n };\n\n /**\n * Hide this modal.\n *\n * @method hide\n */\n Modal.prototype.hide = function() {\n this.getBackdrop().done(function(backdrop) {\n FocusLock.untrapFocus();\n if (!this.countOtherVisibleModals()) {\n // Hide the backdrop if we're the last open modal.\n backdrop.hide();\n $('body').removeClass('modal-open');\n }\n\n var currentIndex = parseInt(this.root.css('z-index'));\n this.root.css('z-index', '');\n backdrop.setZIndex(currentIndex - 3);\n\n this.accessibilityHide();\n\n if (this.hasTransitions()) {\n // Wait for CSS transitions to complete before hiding the element.\n this.getRoot().one('transitionend webkitTransitionEnd oTransitionEnd', function() {\n this.getRoot().removeClass('show').addClass('hide');\n }.bind(this));\n } else {\n this.getRoot().removeClass('show').addClass('hide');\n }\n\n this.root.trigger(ModalEvents.hidden, this);\n }.bind(this));\n };\n\n /**\n * Remove this modal from the DOM.\n *\n * @method destroy\n */\n Modal.prototype.destroy = function() {\n this.root.remove();\n this.root.trigger(ModalEvents.destroyed, this);\n };\n\n /**\n * Sets the appropriate aria attributes on this dialogue and the other\n * elements in the DOM to ensure that screen readers are able to navigate\n * the dialogue popup correctly.\n *\n * @method accessibilityShow\n */\n Modal.prototype.accessibilityShow = function() {\n // We need to get a list containing each sibling element and the shallowest\n // non-ancestral nodes in the DOM. We can shortcut this a little by leveraging\n // the fact that this dialogue is always appended to the document body therefore\n // it's siblings are the shallowest non-ancestral nodes. If that changes then\n // this code should also be updated.\n $('body').children().each(function(index, child) {\n // Skip the current modal.\n if (!this.root.is(child)) {\n child = $(child);\n var hidden = child.attr('aria-hidden');\n // If they are already hidden we can ignore them.\n if (hidden !== 'true') {\n // Save their current state.\n child.data('previous-aria-hidden', hidden);\n this.hiddenSiblings.push(child);\n\n // Hide this node from screen readers.\n child.attr('aria-hidden', 'true');\n }\n }\n }.bind(this));\n\n // Make us visible to screen readers.\n this.root.attr('aria-hidden', 'false');\n };\n\n /**\n * Restores the aria visibility on the DOM elements changed when displaying\n * the dialogue popup and makes the dialogue aria hidden to allow screen\n * readers to navigate the main page correctly when the dialogue is closed.\n *\n * @method accessibilityHide\n */\n Modal.prototype.accessibilityHide = function() {\n this.root.attr('aria-hidden', 'true');\n\n // Restore the sibling nodes back to their original values.\n $.each(this.hiddenSiblings, function(index, sibling) {\n sibling = $(sibling);\n var previousValue = sibling.data('previous-aria-hidden');\n // If the element didn't previously have an aria-hidden attribute\n // then we can just remove the one we set.\n if (typeof previousValue == 'undefined') {\n sibling.removeAttr('aria-hidden');\n } else {\n // Otherwise set it back to the old value (which will be false).\n sibling.attr('aria-hidden', previousValue);\n }\n });\n\n // Clear the cache. No longer need to store these.\n this.hiddenSiblings = [];\n };\n\n /**\n * Set up all of the event handling for the modal.\n *\n * @method registerEventListeners\n */\n Modal.prototype.registerEventListeners = function() {\n this.getRoot().on('keydown', function(e) {\n if (!this.isVisible()) {\n return;\n }\n\n if (e.keyCode == KeyCodes.escape) {\n this.hide();\n }\n }.bind(this));\n\n // Listen for clicks on the modal container.\n this.getRoot().click(function(e) {\n // If the click wasn't inside the modal element then we should\n // hide the modal.\n if (!$(e.target).closest(SELECTORS.MODAL).length) {\n // The check above fails to detect the click was inside the modal when the DOM tree is already changed.\n // So, we check if we can still find the container element or not. If not, then the DOM tree is changed.\n // It's best not to hide the modal in that case.\n if ($(e.target).closest(SELECTORS.CONTAINER).length) {\n this.hideIfNotForm();\n }\n }\n }.bind(this));\n\n CustomEvents.define(this.getModal(), [CustomEvents.events.activate]);\n this.getModal().on(CustomEvents.events.activate, SELECTORS.HIDE, function(e, data) {\n this.hide();\n data.originalEvent.preventDefault();\n }.bind(this));\n };\n\n /**\n * Set or resolve and set the value using the function.\n *\n * @method asyncSet\n * @param {(string|object)} value The string or jQuery promise.\n * @param {function} setFunction The setter\n * @return {Promise}\n */\n Modal.prototype.asyncSet = function(value, setFunction) {\n var p = value;\n if (typeof value !== 'object' || !value.hasOwnProperty('then')) {\n p = $.Deferred();\n p.resolve(value);\n }\n\n p.then(function(content) {\n setFunction(content);\n\n return;\n })\n .fail(Notification.exception);\n\n return p;\n };\n\n return Modal;\n});\n"],"file":"modal.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/modal.js"],"names":["define","$","Templates","Notification","KeyCodes","CustomEvents","ModalBackdrop","Event","ModalEvents","FocusLock","Pending","SELECTORS","CONTAINER","MODAL","HEADER","TITLE","BODY","FOOTER","HIDE","DIALOG","FORM","MENU_BAR","HAS_Z_INDEX","CAN_RECEIVE_FOCUS","TEMPLATES","LOADING","BACKDROP","backdropPromise","modalCounter","Modal","root","modal","find","header","headerPromise","Deferred","title","titlePromise","body","bodyPromise","footer","footerPromise","hiddenSiblings","isAttached","bodyJS","footerJS","modalCount","is","exception","message","length","registerEventListeners","prototype","attachToDOM","append","trapFocus","runTemplateJS","countOtherVisibleModals","count","each","index","element","hasClass","bind","getBackdrop","render","then","html","fail","getRoot","getModal","getTitle","getBody","getFooter","getTitlePromise","getBodyPromise","getFooterPromise","getModalCount","setTitle","value","asyncSet","resolve","catch","setBody","notifyFilterContentUpdated","trigger","bodyRendered","jsPendingId","M","util","js_pending","contentPromise","css","state","height","innerHeight","animate","loadingIcon","hide","fadeIn","when","promise","fadeOut","js","result","isVisible","currentHeight","newHeight","opacity","duration","queue","always","js_complete","setFooter","showFooter","hasFooterContent","children","hideFooter","addClass","removeClass","setLarge","isLarge","setSmall","isSmall","calculateZIndex","items","zIndex","parseInt","item","itemZIndex","hasFocus","target","document","activeElement","has","hasTransitions","show","pendingPromise","backdrop","currentIndex","newIndex","setZIndex","accessibilityShow","focus","shown","hideIfNotForm","formElement","done","untrapFocus","accessibilityHide","one","hidden","destroy","remove","destroyed","child","attr","data","push","sibling","previousValue","removeAttr","on","e","keyCode","escape","click","closest","events","activate","originalEvent","preventDefault","setFunction","p","hasOwnProperty","content"],"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 .\n\n/**\n * Contain the logic for modals.\n *\n * @module core/modal\n * @class modal\n * @package core\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'core/key_codes',\n 'core/custom_interaction_events',\n 'core/modal_backdrop',\n 'core/event',\n 'core/modal_events',\n 'core/local/aria/focuslock',\n 'core/pending',\n], function($, Templates, Notification, KeyCodes, CustomEvents, ModalBackdrop, Event, ModalEvents, FocusLock, Pending) {\n\n var SELECTORS = {\n CONTAINER: '[data-region=\"modal-container\"]',\n MODAL: '[data-region=\"modal\"]',\n HEADER: '[data-region=\"header\"]',\n TITLE: '[data-region=\"title\"]',\n BODY: '[data-region=\"body\"]',\n FOOTER: '[data-region=\"footer\"]',\n HIDE: '[data-action=\"hide\"]',\n DIALOG: '[role=dialog]',\n FORM: 'form',\n MENU_BAR: '[role=menubar]',\n HAS_Z_INDEX: '.moodle-has-zindex',\n CAN_RECEIVE_FOCUS: 'input:not([type=\"hidden\"]), a[href], button, textarea, select, [tabindex]',\n };\n\n var TEMPLATES = {\n LOADING: 'core/loading',\n BACKDROP: 'core/modal_backdrop',\n };\n\n /**\n * Module singleton for the backdrop to be reused by all Modal instances.\n */\n var backdropPromise;\n\n /**\n * A counter that gets incremented for each modal created. This can be\n * used to generate unique values for the modals.\n */\n var modalCounter = 0;\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n var Modal = function(root) {\n this.root = $(root);\n this.modal = this.root.find(SELECTORS.MODAL);\n this.header = this.modal.find(SELECTORS.HEADER);\n this.headerPromise = $.Deferred();\n this.title = this.header.find(SELECTORS.TITLE);\n this.titlePromise = $.Deferred();\n this.body = this.modal.find(SELECTORS.BODY);\n this.bodyPromise = $.Deferred();\n this.footer = this.modal.find(SELECTORS.FOOTER);\n this.footerPromise = $.Deferred();\n this.hiddenSiblings = [];\n this.isAttached = false;\n this.bodyJS = null;\n this.footerJS = null;\n this.modalCount = modalCounter++;\n\n if (!this.root.is(SELECTORS.CONTAINER)) {\n Notification.exception({message: 'Element is not a modal container'});\n }\n\n if (!this.modal.length) {\n Notification.exception({message: 'Container does not contain a modal'});\n }\n\n if (!this.header.length) {\n Notification.exception({message: 'Modal is missing a header region'});\n }\n\n if (!this.title.length) {\n Notification.exception({message: 'Modal header is missing a title region'});\n }\n\n if (!this.body.length) {\n Notification.exception({message: 'Modal is missing a body region'});\n }\n\n if (!this.footer.length) {\n Notification.exception({message: 'Modal is missing a footer region'});\n }\n\n this.registerEventListeners();\n };\n\n /**\n * Add the modal to the page, if it hasn't already been added. This includes running any\n * javascript that has been cached until now.\n *\n * @method attachToDOM\n */\n Modal.prototype.attachToDOM = function() {\n if (this.isAttached) {\n return;\n }\n\n $('body').append(this.root);\n FocusLock.trapFocus(this.root[0]);\n\n // If we'd cached any JS then we can run it how that the modal is\n // attached to the DOM.\n if (this.bodyJS) {\n Templates.runTemplateJS(this.bodyJS);\n this.bodyJS = null;\n }\n\n if (this.footerJS) {\n Templates.runTemplateJS(this.footerJS);\n this.footerJS = null;\n }\n\n this.isAttached = true;\n };\n\n /**\n * Count the number of other visible modals (not including this one).\n *\n * @method countOtherVisibleModals\n * @return {int}\n */\n Modal.prototype.countOtherVisibleModals = function() {\n var count = 0;\n $('body').find(SELECTORS.CONTAINER).each(function(index, element) {\n element = $(element);\n\n // If we haven't found ourself and the element is visible.\n if (!this.root.is(element) && element.hasClass('show')) {\n count++;\n }\n }.bind(this));\n\n return count;\n };\n\n /**\n * Get the modal backdrop.\n *\n * @method getBackdrop\n * @return {object} jQuery promise\n */\n Modal.prototype.getBackdrop = function() {\n if (!backdropPromise) {\n backdropPromise = Templates.render(TEMPLATES.BACKDROP, {})\n .then(function(html) {\n var element = $(html);\n\n return new ModalBackdrop(element);\n })\n .fail(Notification.exception);\n }\n\n return backdropPromise;\n };\n\n /**\n * Get the root element of this modal.\n *\n * @method getRoot\n * @return {object} jQuery object\n */\n Modal.prototype.getRoot = function() {\n return this.root;\n };\n\n /**\n * Get the modal element of this modal.\n *\n * @method getModal\n * @return {object} jQuery object\n */\n Modal.prototype.getModal = function() {\n return this.modal;\n };\n\n /**\n * Get the modal title element.\n *\n * @method getTitle\n * @return {object} jQuery object\n */\n Modal.prototype.getTitle = function() {\n return this.title;\n };\n\n /**\n * Get the modal body element.\n *\n * @method getBody\n * @return {object} jQuery object\n */\n Modal.prototype.getBody = function() {\n return this.body;\n };\n\n /**\n * Get the modal footer element.\n *\n * @method getFooter\n * @return {object} jQuery object\n */\n Modal.prototype.getFooter = function() {\n return this.footer;\n };\n\n /**\n * Get a promise resolving to the title region.\n *\n * @method getTitlePromise\n * @return {Promise}\n */\n Modal.prototype.getTitlePromise = function() {\n return this.titlePromise;\n };\n\n /**\n * Get a promise resolving to the body region.\n *\n * @method getBodyPromise\n * @return {object} jQuery object\n */\n Modal.prototype.getBodyPromise = function() {\n return this.bodyPromise;\n };\n\n /**\n * Get a promise resolving to the footer region.\n *\n * @method getFooterPromise\n * @return {object} jQuery object\n */\n Modal.prototype.getFooterPromise = function() {\n return this.footerPromise;\n };\n\n /**\n * Get the unique modal count.\n *\n * @method getModalCount\n * @return {int}\n */\n Modal.prototype.getModalCount = function() {\n return this.modalCount;\n };\n\n /**\n * Set the modal title element.\n *\n * This method is overloaded to take either a string value for the title or a jQuery promise that is resolved with\n * HTML most commonly from a Str.get_string call.\n *\n * @method setTitle\n * @param {(string|object)} value The title string or jQuery promise which resolves to the title.\n */\n Modal.prototype.setTitle = function(value) {\n var title = this.getTitle();\n this.titlePromise = $.Deferred();\n\n this.asyncSet(value, title.html.bind(title))\n .then(function() {\n this.titlePromise.resolve(title);\n }.bind(this))\n .catch(Notification.exception);\n };\n\n /**\n * Set the modal body element.\n *\n * This method is overloaded to take either a string value for the body or a jQuery promise that is resolved with\n * HTML and Javascript most commonly from a Templates.render call.\n *\n * @method setBody\n * @param {(string|object)} value The body string or jQuery promise which resolves to the body.\n */\n Modal.prototype.setBody = function(value) {\n this.bodyPromise = $.Deferred();\n\n var body = this.getBody();\n\n if (typeof value === 'string') {\n // Just set the value if it's a string.\n body.html(value);\n Event.notifyFilterContentUpdated(body);\n this.getRoot().trigger(ModalEvents.bodyRendered, this);\n this.bodyPromise.resolve(body);\n } else {\n var jsPendingId = 'amd-modal-js-pending-id-' + this.getModalCount();\n M.util.js_pending(jsPendingId);\n // Otherwise we assume it's a promise to be resolved with\n // html and javascript.\n var contentPromise = null;\n body.css('overflow', 'hidden');\n\n if (value.state() == 'pending') {\n // We're still waiting for the body promise to resolve so\n // let's show a loading icon.\n var height = body.innerHeight();\n if (height < 100) {\n height = 100;\n }\n\n body.animate({height: height + 'px'}, 150);\n\n body.html('');\n contentPromise = Templates.render(TEMPLATES.LOADING, {})\n .then(function(html) {\n var loadingIcon = $(html).hide();\n body.html(loadingIcon);\n loadingIcon.fadeIn(150);\n\n // We only want the loading icon to fade out\n // when the content for the body has finished\n // loading.\n return $.when(loadingIcon.promise(), value);\n })\n .then(function(loadingIcon) {\n // Once the content has finished loading and\n // the loading icon has been shown then we can\n // fade the icon away to reveal the content.\n return loadingIcon.fadeOut(100).promise();\n })\n .then(function() {\n return value;\n });\n } else {\n // The content is already loaded so let's just display\n // it to the user. No need for a loading icon.\n contentPromise = value;\n }\n\n // Now we can actually display the content.\n contentPromise.then(function(html, js) {\n var result = null;\n\n if (this.isVisible()) {\n // If the modal is visible then we should display\n // the content gracefully for the user.\n body.css('opacity', 0);\n var currentHeight = body.innerHeight();\n body.html(html);\n // We need to clear any height values we've set here\n // in order to measure the height of the content being\n // added. This then allows us to animate the height\n // transition.\n body.css('height', '');\n var newHeight = body.innerHeight();\n body.css('height', currentHeight + 'px');\n result = body.animate(\n {height: newHeight + 'px', opacity: 1},\n {duration: 150, queue: false}\n ).promise();\n } else {\n // Since the modal isn't visible we can just immediately\n // set the content. No need to animate it.\n body.html(html);\n }\n\n if (js) {\n if (this.isAttached) {\n // If we're in the DOM then run the JS immediately.\n Templates.runTemplateJS(js);\n } else {\n // Otherwise cache it to be run when we're attached.\n this.bodyJS = js;\n }\n }\n\n return result;\n }.bind(this))\n .then(function(result) {\n Event.notifyFilterContentUpdated(body);\n this.getRoot().trigger(ModalEvents.bodyRendered, this);\n return result;\n }.bind(this))\n .then(function() {\n this.bodyPromise.resolve(body);\n return;\n }.bind(this))\n .fail(Notification.exception)\n .always(function() {\n // When we're done displaying all of the content we need\n // to clear the custom values we've set here.\n body.css('height', '');\n body.css('overflow', '');\n body.css('opacity', '');\n M.util.js_complete(jsPendingId);\n\n return;\n })\n .fail(Notification.exception);\n }\n };\n\n /**\n * Set the modal footer element. The footer element is made visible, if it\n * isn't already.\n *\n * This method is overloaded to take either a string\n * value for the body or a jQuery promise that is resolved with HTML and Javascript\n * most commonly from a Templates.render call.\n *\n * @method setFooter\n * @param {(string|object)} value The footer string or jQuery promise\n */\n Modal.prototype.setFooter = function(value) {\n // Make sure the footer is visible.\n this.showFooter();\n this.footerPromise = $.Deferred();\n\n var footer = this.getFooter();\n\n if (typeof value === 'string') {\n // Just set the value if it's a string.\n footer.html(value);\n this.footerPromise.resolve(footer);\n } else {\n // Otherwise we assume it's a promise to be resolved with\n // html and javascript.\n Templates.render(TEMPLATES.LOADING, {})\n .then(function(html) {\n footer.html(html);\n\n return value;\n })\n .then(function(html, js) {\n footer.html(html);\n\n if (js) {\n if (this.isAttached) {\n // If we're in the DOM then run the JS immediately.\n Templates.runTemplateJS(js);\n } else {\n // Otherwise cache it to be run when we're attached.\n this.footerJS = js;\n }\n }\n\n return footer;\n }.bind(this))\n .then(function(footer) {\n this.footerPromise.resolve(footer);\n return;\n }.bind(this))\n .catch(Notification.exception);\n }\n };\n\n /**\n * Check if the footer has any content in it.\n *\n * @method hasFooterContent\n * @return {bool}\n */\n Modal.prototype.hasFooterContent = function() {\n return this.getFooter().children().length ? true : false;\n };\n\n /**\n * Hide the footer element.\n *\n * @method hideFooter\n */\n Modal.prototype.hideFooter = function() {\n this.getFooter().addClass('hidden');\n };\n\n /**\n * Show the footer element.\n *\n * @method showFooter\n */\n Modal.prototype.showFooter = function() {\n this.getFooter().removeClass('hidden');\n };\n\n /**\n * Mark the modal as a large modal.\n *\n * @method setLarge\n */\n Modal.prototype.setLarge = function() {\n if (this.isLarge()) {\n return;\n }\n\n this.getModal().addClass('modal-lg');\n };\n\n /**\n * Check if the modal is a large modal.\n *\n * @method isLarge\n * @return {bool}\n */\n Modal.prototype.isLarge = function() {\n return this.getModal().hasClass('modal-lg');\n };\n\n /**\n * Mark the modal as a small modal.\n *\n * @method setSmall\n */\n Modal.prototype.setSmall = function() {\n if (this.isSmall()) {\n return;\n }\n\n this.getModal().removeClass('modal-lg');\n };\n\n /**\n * Check if the modal is a small modal.\n *\n * @method isSmall\n * @return {bool}\n */\n Modal.prototype.isSmall = function() {\n return !this.getModal().hasClass('modal-lg');\n };\n\n /**\n * Determine the highest z-index value currently on the page.\n *\n * @method calculateZIndex\n * @return {int}\n */\n Modal.prototype.calculateZIndex = function() {\n var items = $(SELECTORS.DIALOG + ', ' + SELECTORS.MENU_BAR + ', ' + SELECTORS.HAS_Z_INDEX);\n var zIndex = parseInt(this.root.css('z-index'));\n\n items.each(function(index, item) {\n item = $(item);\n // Note that webkit browsers won't return the z-index value from the CSS stylesheet\n // if the element doesn't have a position specified. Instead it'll return \"auto\".\n var itemZIndex = item.css('z-index') ? parseInt(item.css('z-index')) : 0;\n\n if (itemZIndex > zIndex) {\n zIndex = itemZIndex;\n }\n });\n\n return zIndex;\n };\n\n /**\n * Check if this modal is visible.\n *\n * @method isVisible\n * @return {bool}\n */\n Modal.prototype.isVisible = function() {\n return this.root.hasClass('show');\n };\n\n /**\n * Check if this modal has focus.\n *\n * @method hasFocus\n * @return {bool}\n */\n Modal.prototype.hasFocus = function() {\n var target = $(document.activeElement);\n return this.root.is(target) || this.root.has(target).length;\n };\n\n /**\n * Check if this modal has CSS transitions applied.\n *\n * @method hasTransitions\n * @return {bool}\n */\n Modal.prototype.hasTransitions = function() {\n return this.getRoot().hasClass('fade');\n };\n\n /**\n * Display this modal. The modal will be attached to the DOM if it hasn't\n * already been.\n *\n * @method show\n */\n Modal.prototype.show = function() {\n if (this.isVisible()) {\n return;\n }\n\n var pendingPromise = new Pending('core/modal:show');\n\n if (this.hasFooterContent()) {\n this.showFooter();\n } else {\n this.hideFooter();\n }\n\n if (!this.isAttached) {\n this.attachToDOM();\n }\n\n this.getBackdrop()\n .then(function(backdrop) {\n var currentIndex = this.calculateZIndex();\n var newIndex = currentIndex + 2;\n var newBackdropIndex = newIndex - 1;\n this.root.css('z-index', newIndex);\n backdrop.setZIndex(newBackdropIndex);\n backdrop.show();\n\n this.root.removeClass('hide').addClass('show');\n this.accessibilityShow();\n this.getModal().focus();\n $('body').addClass('modal-open');\n this.root.trigger(ModalEvents.shown, this);\n\n return;\n }.bind(this))\n .then(pendingPromise.resolve);\n };\n\n /**\n * Hide this modal if it does not contain a form.\n *\n * @method hideIfNotForm\n */\n Modal.prototype.hideIfNotForm = function() {\n var formElement = this.modal.find(SELECTORS.FORM);\n if (formElement.length == 0) {\n this.hide();\n }\n };\n\n /**\n * Hide this modal.\n *\n * @method hide\n */\n Modal.prototype.hide = function() {\n this.getBackdrop().done(function(backdrop) {\n FocusLock.untrapFocus();\n if (!this.countOtherVisibleModals()) {\n // Hide the backdrop if we're the last open modal.\n backdrop.hide();\n $('body').removeClass('modal-open');\n }\n\n var currentIndex = parseInt(this.root.css('z-index'));\n this.root.css('z-index', '');\n backdrop.setZIndex(currentIndex - 3);\n\n this.accessibilityHide();\n\n if (this.hasTransitions()) {\n // Wait for CSS transitions to complete before hiding the element.\n this.getRoot().one('transitionend webkitTransitionEnd oTransitionEnd', function() {\n this.getRoot().removeClass('show').addClass('hide');\n }.bind(this));\n } else {\n this.getRoot().removeClass('show').addClass('hide');\n }\n\n this.root.trigger(ModalEvents.hidden, this);\n }.bind(this));\n };\n\n /**\n * Remove this modal from the DOM.\n *\n * @method destroy\n */\n Modal.prototype.destroy = function() {\n this.root.remove();\n this.root.trigger(ModalEvents.destroyed, this);\n };\n\n /**\n * Sets the appropriate aria attributes on this dialogue and the other\n * elements in the DOM to ensure that screen readers are able to navigate\n * the dialogue popup correctly.\n *\n * @method accessibilityShow\n */\n Modal.prototype.accessibilityShow = function() {\n // We need to get a list containing each sibling element and the shallowest\n // non-ancestral nodes in the DOM. We can shortcut this a little by leveraging\n // the fact that this dialogue is always appended to the document body therefore\n // it's siblings are the shallowest non-ancestral nodes. If that changes then\n // this code should also be updated.\n $('body').children().each(function(index, child) {\n // Skip the current modal.\n if (!this.root.is(child)) {\n child = $(child);\n var hidden = child.attr('aria-hidden');\n // If they are already hidden we can ignore them.\n if (hidden !== 'true') {\n // Save their current state.\n child.data('previous-aria-hidden', hidden);\n this.hiddenSiblings.push(child);\n\n // Hide this node from screen readers.\n child.attr('aria-hidden', 'true');\n }\n }\n }.bind(this));\n\n // Make us visible to screen readers.\n this.root.attr('aria-hidden', 'false');\n };\n\n /**\n * Restores the aria visibility on the DOM elements changed when displaying\n * the dialogue popup and makes the dialogue aria hidden to allow screen\n * readers to navigate the main page correctly when the dialogue is closed.\n *\n * @method accessibilityHide\n */\n Modal.prototype.accessibilityHide = function() {\n this.root.attr('aria-hidden', 'true');\n\n // Restore the sibling nodes back to their original values.\n $.each(this.hiddenSiblings, function(index, sibling) {\n sibling = $(sibling);\n var previousValue = sibling.data('previous-aria-hidden');\n // If the element didn't previously have an aria-hidden attribute\n // then we can just remove the one we set.\n if (typeof previousValue == 'undefined') {\n sibling.removeAttr('aria-hidden');\n } else {\n // Otherwise set it back to the old value (which will be false).\n sibling.attr('aria-hidden', previousValue);\n }\n });\n\n // Clear the cache. No longer need to store these.\n this.hiddenSiblings = [];\n };\n\n /**\n * Set up all of the event handling for the modal.\n *\n * @method registerEventListeners\n */\n Modal.prototype.registerEventListeners = function() {\n this.getRoot().on('keydown', function(e) {\n if (!this.isVisible()) {\n return;\n }\n\n if (e.keyCode == KeyCodes.escape) {\n this.hide();\n }\n }.bind(this));\n\n // Listen for clicks on the modal container.\n this.getRoot().click(function(e) {\n // If the click wasn't inside the modal element then we should\n // hide the modal.\n if (!$(e.target).closest(SELECTORS.MODAL).length) {\n // The check above fails to detect the click was inside the modal when the DOM tree is already changed.\n // So, we check if we can still find the container element or not. If not, then the DOM tree is changed.\n // It's best not to hide the modal in that case.\n if ($(e.target).closest(SELECTORS.CONTAINER).length) {\n this.hideIfNotForm();\n }\n }\n }.bind(this));\n\n CustomEvents.define(this.getModal(), [CustomEvents.events.activate]);\n this.getModal().on(CustomEvents.events.activate, SELECTORS.HIDE, function(e, data) {\n this.hide();\n data.originalEvent.preventDefault();\n }.bind(this));\n };\n\n /**\n * Set or resolve and set the value using the function.\n *\n * @method asyncSet\n * @param {(string|object)} value The string or jQuery promise.\n * @param {function} setFunction The setter\n * @return {Promise}\n */\n Modal.prototype.asyncSet = function(value, setFunction) {\n var p = value;\n if (typeof value !== 'object' || !value.hasOwnProperty('then')) {\n p = $.Deferred();\n p.resolve(value);\n }\n\n p.then(function(content) {\n setFunction(content);\n\n return;\n })\n .fail(Notification.exception);\n\n return p;\n };\n\n return Modal;\n});\n"],"file":"modal.min.js"} \ No newline at end of file diff --git a/lib/amd/build/modal_factory.min.js b/lib/amd/build/modal_factory.min.js index f38a752f929..2fa4d54f33d 100644 --- a/lib/amd/build/modal_factory.min.js +++ b/lib/amd/build/modal_factory.min.js @@ -1,2 +1,2 @@ -define ("core/modal_factory",["jquery","core/modal_events","core/modal_registry","core/modal","core/modal_save_cancel","core/modal_cancel","core/templates","core/notification","core/custom_interaction_events"],function(a,b,c,d,e,f,g,h,i){var j={DEFAULT:"core/modal",SAVE_CANCEL:"core/modal_save_cancel",CANCEL:"core/modal_cancel"},k={DEFAULT:"DEFAULT",SAVE_CANCEL:"SAVE_CANCEL",CANCEL:"CANCEL"};c.register(k.DEFAULT,d,j.DEFAULT);c.register(k.SAVE_CANCEL,e,j.SAVE_CANCEL);c.register(k.CANCEL,f,j.CANCEL);var l=function(c,d,e){var f=null,g="function"==typeof e.preShowCallback,h=function(b,d){f=a(b.currentTarget);c.then(function(a){if(g){e.preShowCallback(f,a)}a.show();return a});d.originalEvent.preventDefault()};if(Array.isArray(d)){var j=d[1];d=d[0];i.define(d,[i.events.activate]);d.on(i.events.activate,j,h)}else{i.define(d,[i.events.activate]);d.on(i.events.activate,h)}c.then(function(a){a.getRoot().on(b.hidden,function(){if(null!==f){f.focus()}});return a})},m=function(b,c){c=a(c);var d=b.module,e=new d(c);return e},n=function(b,c){var d=b.template,e=g.render(d,c).then(function(c){var d=a(c);return m(b,d)}).fail(h.exception);return e};return{create:function create(a,b){var d=a.type||k.DEFAULT,e=a.large?!0:!1,f=null,g={};f=c.get(d);if(!f){h.exception({message:"Unable to find modal of type: "+d})}if("undefined"!=typeof a.templateContext){g=a.templateContext}var i=n(f,g).then(function(b){if("undefined"!=typeof a.title){b.setTitle(a.title)}if("undefined"!=typeof a.body){b.setBody(a.body)}if("undefined"!=typeof a.footer){b.setFooter(a.footer)}if(e){b.setLarge()}return b});if("undefined"!=typeof b){l(i,b,a)}return i},types:k}}); +define ("core/modal_factory",["jquery","core/modal_events","core/modal_registry","core/modal","core/modal_save_cancel","core/modal_cancel","core/templates","core/notification","core/custom_interaction_events","core/pending"],function(a,b,c,d,e,f,g,h,i,j){var k={DEFAULT:"core/modal",SAVE_CANCEL:"core/modal_save_cancel",CANCEL:"core/modal_cancel"},l={DEFAULT:"DEFAULT",SAVE_CANCEL:"SAVE_CANCEL",CANCEL:"CANCEL"};c.register(l.DEFAULT,d,k.DEFAULT);c.register(l.SAVE_CANCEL,e,k.SAVE_CANCEL);c.register(l.CANCEL,f,k.CANCEL);var m=function(c,d,e){var f=null,g="function"==typeof e.preShowCallback,h=function(b,d){var h=new j("core/modal_factory:setUpTrigger:triggeredCallback");f=a(b.currentTarget);c.then(function(a){if(g){e.preShowCallback(f,a)}a.show();return a}).then(h.resolve);d.originalEvent.preventDefault()};if(Array.isArray(d)){var k=d[1];d=d[0];i.define(d,[i.events.activate]);d.on(i.events.activate,k,h)}else{i.define(d,[i.events.activate]);d.on(i.events.activate,h)}c.then(function(a){a.getRoot().on(b.hidden,function(){if(null!==f){f.focus()}});return a})},n=function(b,c){c=a(c);var d=b.module,e=new d(c);return e},o=function(b,c){var d=b.template,e=g.render(d,c).then(function(c){var d=a(c);return n(b,d)}).fail(h.exception);return e};return{create:function create(a,b){var d=a.type||l.DEFAULT,e=a.large?!0:!1,f=null,g={};f=c.get(d);if(!f){h.exception({message:"Unable to find modal of type: "+d})}if("undefined"!=typeof a.templateContext){g=a.templateContext}var i=o(f,g).then(function(b){if("undefined"!=typeof a.title){b.setTitle(a.title)}if("undefined"!=typeof a.body){b.setBody(a.body)}if("undefined"!=typeof a.footer){b.setFooter(a.footer)}if(e){b.setLarge()}return b});if("undefined"!=typeof b){m(i,b,a)}return i},types:l}}); //# sourceMappingURL=modal_factory.min.js.map diff --git a/lib/amd/build/modal_factory.min.js.map b/lib/amd/build/modal_factory.min.js.map index 32561b546fc..ff93873faf3 100644 --- a/lib/amd/build/modal_factory.min.js.map +++ b/lib/amd/build/modal_factory.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/modal_factory.js"],"names":["define","$","ModalEvents","ModalRegistry","Modal","ModalSaveCancel","ModalCancel","Templates","Notification","CustomEvents","TEMPLATES","DEFAULT","SAVE_CANCEL","CANCEL","TYPES","register","setUpTrigger","modalPromise","triggerElement","modalConfig","actualTriggerElement","hasPreShowCallback","preShowCallback","triggeredCallback","e","data","currentTarget","then","modal","show","originalEvent","preventDefault","Array","isArray","selector","events","activate","on","getRoot","hidden","focus","createFromElement","registryConf","modalElement","module","createFromType","templateContext","templateName","template","render","html","fail","exception","create","type","isLarge","large","get","message","title","setTitle","body","setBody","footer","setFooter","setLarge","types"],"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 .\n\n/**\n * Create a modal.\n *\n * @module core/modal_factory\n * @class modal_factory\n * @package core\n * @copyright 2016 Ryan Wyllie \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',\n 'core/templates', 'core/notification', 'core/custom_interaction_events'],\n function($, ModalEvents, ModalRegistry, Modal, ModalSaveCancel,\n ModalCancel, Templates, Notification, CustomEvents) {\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 };\n\n // The available types of modals.\n var TYPES = {\n DEFAULT: 'DEFAULT',\n SAVE_CANCEL: 'SAVE_CANCEL',\n CANCEL: 'CANCEL',\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\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 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 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 (isLarge) {\n modal.setLarge();\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"],"file":"modal_factory.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/modal_factory.js"],"names":["define","$","ModalEvents","ModalRegistry","Modal","ModalSaveCancel","ModalCancel","Templates","Notification","CustomEvents","Pending","TEMPLATES","DEFAULT","SAVE_CANCEL","CANCEL","TYPES","register","setUpTrigger","modalPromise","triggerElement","modalConfig","actualTriggerElement","hasPreShowCallback","preShowCallback","triggeredCallback","e","data","pendingPromise","currentTarget","then","modal","show","resolve","originalEvent","preventDefault","Array","isArray","selector","events","activate","on","getRoot","hidden","focus","createFromElement","registryConf","modalElement","module","createFromType","templateContext","templateName","template","render","html","fail","exception","create","type","isLarge","large","get","message","title","setTitle","body","setBody","footer","setFooter","setLarge","types"],"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 .\n\n/**\n * Create a modal.\n *\n * @module core/modal_factory\n * @class modal_factory\n * @package core\n * @copyright 2016 Ryan Wyllie \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',\n 'core/templates', 'core/notification', 'core/custom_interaction_events',\n 'core/pending'],\n function($, ModalEvents, ModalRegistry, Modal, ModalSaveCancel,\n ModalCancel, 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 };\n\n // The available types of modals.\n var TYPES = {\n DEFAULT: 'DEFAULT',\n SAVE_CANCEL: 'SAVE_CANCEL',\n CANCEL: 'CANCEL',\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\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 (isLarge) {\n modal.setLarge();\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"],"file":"modal_factory.min.js"} \ No newline at end of file diff --git a/lib/amd/src/modal.js b/lib/amd/src/modal.js index 16469ae8dea..aeefaedf888 100644 --- a/lib/amd/src/modal.js +++ b/lib/amd/src/modal.js @@ -32,7 +32,8 @@ define([ 'core/event', 'core/modal_events', 'core/local/aria/focuslock', -], function($, Templates, Notification, KeyCodes, CustomEvents, ModalBackdrop, Event, ModalEvents, FocusLock) { + 'core/pending', +], function($, Templates, Notification, KeyCodes, CustomEvents, ModalBackdrop, Event, ModalEvents, FocusLock, Pending) { var SELECTORS = { CONTAINER: '[data-region="modal-container"]', @@ -615,6 +616,8 @@ define([ return; } + var pendingPromise = new Pending('core/modal:show'); + if (this.hasFooterContent()) { this.showFooter(); } else { @@ -625,7 +628,8 @@ define([ this.attachToDOM(); } - this.getBackdrop().done(function(backdrop) { + this.getBackdrop() + .then(function(backdrop) { var currentIndex = this.calculateZIndex(); var newIndex = currentIndex + 2; var newBackdropIndex = newIndex - 1; @@ -638,7 +642,10 @@ define([ this.getModal().focus(); $('body').addClass('modal-open'); this.root.trigger(ModalEvents.shown, this); - }.bind(this)); + + return; + }.bind(this)) + .then(pendingPromise.resolve); }; /** diff --git a/lib/amd/src/modal_factory.js b/lib/amd/src/modal_factory.js index 4e9381ea14b..2b304bc6428 100644 --- a/lib/amd/src/modal_factory.js +++ b/lib/amd/src/modal_factory.js @@ -24,9 +24,10 @@ */ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal', 'core/modal_save_cancel', 'core/modal_cancel', - 'core/templates', 'core/notification', 'core/custom_interaction_events'], + 'core/templates', 'core/notification', 'core/custom_interaction_events', + 'core/pending'], function($, ModalEvents, ModalRegistry, Modal, ModalSaveCancel, - ModalCancel, Templates, Notification, CustomEvents) { + ModalCancel, Templates, Notification, CustomEvents, Pending) { // The templates for each type of modal. var TEMPLATES = { @@ -64,6 +65,7 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal', var hasPreShowCallback = (typeof modalConfig.preShowCallback == 'function'); // Function to handle the trigger element being activated. var triggeredCallback = function(e, data) { + var pendingPromise = new Pending('core/modal_factory:setUpTrigger:triggeredCallback'); actualTriggerElement = $(e.currentTarget); modalPromise.then(function(modal) { if (hasPreShowCallback) { @@ -75,7 +77,8 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal', modal.show(); return modal; - }); + }) + .then(pendingPromise.resolve); data.originalEvent.preventDefault(); };