From 6fd7ea810b56a6df2ba6cd5dcb8a1e7010de835c Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 16 Aug 2017 12:31:21 +0800 Subject: [PATCH 1/3] MDL-59784 core: Refactor addblock to listen earlier --- lib/amd/build/addblockmodal.min.js | 2 +- lib/amd/src/addblockmodal.js | 44 +++++++++++++++++------------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/lib/amd/build/addblockmodal.min.js b/lib/amd/build/addblockmodal.min.js index 7cf5cb8a2be..6778d415ca3 100644 --- a/lib/amd/build/addblockmodal.min.js +++ b/lib/amd/build/addblockmodal.min.js @@ -1 +1 @@ -define(["jquery","core/modal_factory","core/templates","core/str","core/notification"],function(a,b,c,d,e){return{init:function(f){var g=a("[data-key=addblock]");d.get_string("addblock").done(function(e){var h=[];a.each(f.blocks,function(a,b){h[h.length]={key:"pluginname",component:"block_"+b}});var i=[];d.get_strings(h).done(function(d){a.each(d,function(a,b){i[i.length]={name:f.blocks[a],title:b}}),f.blocks=i,b.create({title:e,body:c.render("core/add_block_body",f),type:"CANCEL"},g)})}).fail(e.exception)}}}); \ No newline at end of file +define(["jquery","core/modal_factory","core/templates","core/str","core/notification"],function(a,b,c,d,e){return{init:function(f){var g=a("[data-key=addblock]"),h=[];a.each(f.blocks,function(a,b){h[h.length]={key:"pluginname",component:"block_"+b}});var i=d.get_strings(h).then(function(a){return a.map(function(a,b){return{name:f.blocks[b],title:a}})}).then(function(a){return f.blocks=a,c.render("core/add_block_body",f)}).fail(e.exception),j=d.get_string("addblock").fail(e.exception);b.create({title:j,body:i,type:"CANCEL"},g)}}}); \ No newline at end of file diff --git a/lib/amd/src/addblockmodal.js b/lib/amd/src/addblockmodal.js index 5da0bdec872..02b363d94a7 100644 --- a/lib/amd/src/addblockmodal.js +++ b/lib/amd/src/addblockmodal.js @@ -37,28 +37,34 @@ define(['jquery', 'core/modal_factory', 'core/templates', 'core/str', 'core/noti var addblocklink = $('[data-key=addblock]'); // We need the fetch the names of the blocks. It was too much to send in the page. - Str.get_string('addblock').done(function(title) { + var titlerequests = []; + $.each(context.blocks, function(index, key) { + titlerequests[titlerequests.length] = {key: 'pluginname', component: 'block_' + key}; + }); - var titlerequests = []; - $.each(context.blocks, function(index, key) { - titlerequests[titlerequests.length] = {key: 'pluginname', component: 'block_' + key}; - }); - - var blocks = []; - Str.get_strings(titlerequests).done(function(titles) { - $.each(titles, function(index, title) { - blocks[blocks.length] = {name: context.blocks[index], title: title}; - }); - - context.blocks = blocks; - - ModalFactory.create({ + var bodyPromise = Str.get_strings(titlerequests) + .then(function(titles) { + return titles.map(function(title, index) { + return { + name: context.blocks[index], title: title, - body: Templates.render('core/add_block_body', context), - type: 'CANCEL', - }, addblocklink); + }; }); - }).fail(Notification.exception); + }) + .then(function(blocks) { + context.blocks = blocks; + return Templates.render('core/add_block_body', context); + }) + .fail(Notification.exception); + + var titlePromise = Str.get_string('addblock') + .fail(Notification.exception); + + ModalFactory.create({ + title: titlePromise, + body: bodyPromise, + type: 'CANCEL', + }, addblocklink); } }; }); From 5607739ed73573f6c761016296bf5e10308b9240 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 16 Aug 2017 12:31:53 +0800 Subject: [PATCH 2/3] MDL-59784 core: Modal should accept title as a promise --- lib/amd/build/modal.min.js | 2 +- lib/amd/src/modal.js | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/amd/build/modal.min.js b/lib/amd/build/modal.min.js index 244be47c5d1..7606b203609 100644 --- a/lib/amd/build/modal.min.js +++ b/lib/amd/build/modal.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/notification","core/key_codes","core/custom_interaction_events","core/modal_backdrop","core/modal_events"],function(a,b,c,d,e,f,g){var h,i={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]",MENU_BAR:"[role=menubar]",HAS_Z_INDEX:".moodle-has-zindex",CAN_RECEIVE_FOCUS:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]'},j={LOADING:"core/loading",BACKDROP:"core/modal_backdrop"},k=function(b){this.root=a(b),this.modal=this.root.find(i.MODAL),this.header=this.modal.find(i.HEADER),this.title=this.header.find(i.TITLE),this.body=this.modal.find(i.BODY),this.footer=this.modal.find(i.FOOTER),this.hiddenSiblings=[],this.isAttached=!1,this.bodyJS=null,this.footerJS=null,this.root.is(i.CONTAINER)||c.exception({message:"Element is not a modal container"}),this.modal.length||c.exception({message:"Container does not contain a modal"}),this.header.length||c.exception({message:"Modal is missing a header region"}),this.title.length||c.exception({message:"Modal header is missing a title region"}),this.body.length||c.exception({message:"Modal is missing a body region"}),this.footer.length||c.exception({message:"Modal is missing a footer region"}),this.registerEventListeners()};return k.prototype.attachToDOM=function(){this.isAttached||(a("body").append(this.root),this.bodyJS&&(b.runTemplateJS(this.bodyJS),this.bodyJS=null),this.footerJS&&(b.runTemplateJS(this.footerJS),this.footerJS=null),this.isAttached=!0)},k.prototype.countOtherVisibleModals=function(){var b=0;return a("body").find(i.CONTAINER).each(function(c,d){d=a(d),!this.root.is(d)&&d.hasClass("show")&&b++}.bind(this)),b},k.prototype.getBackdrop=function(){return h||(h=b.render(j.BACKDROP,{}).then(function(b){var c=a(b);return new f(c)}).fail(c.exception)),h},k.prototype.getRoot=function(){return this.root},k.prototype.getModal=function(){return this.modal},k.prototype.getTitle=function(){return this.title},k.prototype.getBody=function(){return this.body},k.prototype.getFooter=function(){return this.footer},k.prototype.setTitle=function(a){var b=this.getTitle();b.html(a)},k.prototype.setBody=function(a){var c=this.getBody();"string"==typeof a?c.html(a):b.render(j.LOADING,{}).done(function(d){c.html(d),a.done(function(a,d){c.html(a),d&&(this.isAttached?b.runTemplateJS(d):this.bodyJS=d)}.bind(this))}.bind(this))},k.prototype.setFooter=function(a){var c=this.getFooter();"string"==typeof a?c.html(a):b.render(j.LOADING,{}).done(function(d){c.html(d),a.done(function(a,d){c.html(a),d&&(this.isAttached?b.runTemplateJS(d):this.footerJS=d)}.bind(this))}.bind(this))},k.prototype.setLarge=function(){this.isLarge()||this.getRoot().addClass("large")},k.prototype.isLarge=function(){return this.getRoot().hasClass("large")},k.prototype.setSmall=function(){this.isSmall()||this.getRoot().removeClass("large")},k.prototype.isSmall=function(){return!this.getRoot().hasClass("large")},k.prototype.calculateZIndex=function(){var b=a(i.DIALOG+", "+i.MENU_BAR+", "+i.HAS_Z_INDEX),c=parseInt(this.root.css("z-index"));return b.each(function(b,d){d=a(d);var e=d.css("z-index")?parseInt(d.css("z-index")):0;e>c&&(c=e)}),c},k.prototype.isVisible=function(){return this.root.hasClass("show")},k.prototype.hasFocus=function(){var b=a(document.activeElement);return this.root.is(b)||this.root.has(b).length},k.prototype.hasTransitions=function(){return this.getRoot().hasClass("fade")},k.prototype.show=function(){this.isVisible()||(this.isAttached||this.attachToDOM(),this.getBackdrop().done(function(b){var c=this.calculateZIndex(),d=c+2,e=d-1;this.root.css("z-index",d),b.setZIndex(e),b.show(),this.root.removeClass("hide").addClass("show"),this.accessibilityShow(),this.getTitle().focus(),a("body").addClass("modal-open"),this.root.trigger(g.shown,this)}.bind(this)))},k.prototype.hide=function(){this.isVisible()&&this.getBackdrop().done(function(b){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(),this.hasTransitions()?this.getRoot().one("transitionend webkitTransitionEnd oTransitionEnd",function(){this.getRoot().removeClass("show").addClass("hide")}.bind(this)):this.getRoot().removeClass("show").addClass("hide"),this.root.trigger(g.hidden,this)}.bind(this))},k.prototype.destroy=function(){this.root.remove(),this.root.trigger(g.destroyed,this)},k.prototype.accessibilityShow=function(){a("body").children().each(function(b,c){if(!this.root.is(c)){c=a(c);var d=c.attr("aria-hidden");"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")},k.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");"undefined"==typeof d?c.removeAttr("aria-hidden"):c.attr("aria-hidden",d)}),this.hiddenSiblings=[]},k.prototype.handleTabLock=function(b){if(this.hasFocus()){var c=a(document.activeElement),d=this.modal.find(i.CAN_RECEIVE_FOCUS),e=d.first(),f=d.last();c.is(e)&&b.shiftKey?(f.focus(),b.preventDefault()):c.is(f)&&!b.shiftKey&&(e.focus(),b.preventDefault())}},k.prototype.registerEventListeners=function(){this.getRoot().on("keydown",function(a){this.isVisible()&&(a.keyCode==d.tab?this.handleTabLock(a):a.keyCode==d.escape&&this.hide())}.bind(this)),e.define(this.getModal(),[e.events.activate]),this.getModal().on(e.events.activate,i.HIDE,function(a,b){this.hide(),b.originalEvent.preventDefault()}.bind(this))},k}); \ No newline at end of file +define(["jquery","core/templates","core/notification","core/key_codes","core/custom_interaction_events","core/modal_backdrop","core/modal_events"],function(a,b,c,d,e,f,g){var h,i={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]",MENU_BAR:"[role=menubar]",HAS_Z_INDEX:".moodle-has-zindex",CAN_RECEIVE_FOCUS:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]'},j={LOADING:"core/loading",BACKDROP:"core/modal_backdrop"},k=function(b){this.root=a(b),this.modal=this.root.find(i.MODAL),this.header=this.modal.find(i.HEADER),this.title=this.header.find(i.TITLE),this.body=this.modal.find(i.BODY),this.footer=this.modal.find(i.FOOTER),this.hiddenSiblings=[],this.isAttached=!1,this.bodyJS=null,this.footerJS=null,this.root.is(i.CONTAINER)||c.exception({message:"Element is not a modal container"}),this.modal.length||c.exception({message:"Container does not contain a modal"}),this.header.length||c.exception({message:"Modal is missing a header region"}),this.title.length||c.exception({message:"Modal header is missing a title region"}),this.body.length||c.exception({message:"Modal is missing a body region"}),this.footer.length||c.exception({message:"Modal is missing a footer region"}),this.registerEventListeners()};return k.prototype.attachToDOM=function(){this.isAttached||(a("body").append(this.root),this.bodyJS&&(b.runTemplateJS(this.bodyJS),this.bodyJS=null),this.footerJS&&(b.runTemplateJS(this.footerJS),this.footerJS=null),this.isAttached=!0)},k.prototype.countOtherVisibleModals=function(){var b=0;return a("body").find(i.CONTAINER).each(function(c,d){d=a(d),!this.root.is(d)&&d.hasClass("show")&&b++}.bind(this)),b},k.prototype.getBackdrop=function(){return h||(h=b.render(j.BACKDROP,{}).then(function(b){var c=a(b);return new f(c)}).fail(c.exception)),h},k.prototype.getRoot=function(){return this.root},k.prototype.getModal=function(){return this.modal},k.prototype.getTitle=function(){return this.title},k.prototype.getBody=function(){return this.body},k.prototype.getFooter=function(){return this.footer},k.prototype.setTitle=function(a){var b=this.getTitle();"string"==typeof a?b.html(a):a.then(function(a){return b.html(a)})},k.prototype.setBody=function(a){var c=this.getBody();"string"==typeof a?c.html(a):b.render(j.LOADING,{}).done(function(d){c.html(d),a.done(function(a,d){c.html(a),d&&(this.isAttached?b.runTemplateJS(d):this.bodyJS=d)}.bind(this))}.bind(this))},k.prototype.setFooter=function(a){var c=this.getFooter();"string"==typeof a?c.html(a):b.render(j.LOADING,{}).done(function(d){c.html(d),a.done(function(a,d){c.html(a),d&&(this.isAttached?b.runTemplateJS(d):this.footerJS=d)}.bind(this))}.bind(this))},k.prototype.setLarge=function(){this.isLarge()||this.getRoot().addClass("large")},k.prototype.isLarge=function(){return this.getRoot().hasClass("large")},k.prototype.setSmall=function(){this.isSmall()||this.getRoot().removeClass("large")},k.prototype.isSmall=function(){return!this.getRoot().hasClass("large")},k.prototype.calculateZIndex=function(){var b=a(i.DIALOG+", "+i.MENU_BAR+", "+i.HAS_Z_INDEX),c=parseInt(this.root.css("z-index"));return b.each(function(b,d){d=a(d);var e=d.css("z-index")?parseInt(d.css("z-index")):0;e>c&&(c=e)}),c},k.prototype.isVisible=function(){return this.root.hasClass("show")},k.prototype.hasFocus=function(){var b=a(document.activeElement);return this.root.is(b)||this.root.has(b).length},k.prototype.hasTransitions=function(){return this.getRoot().hasClass("fade")},k.prototype.show=function(){this.isVisible()||(this.isAttached||this.attachToDOM(),this.getBackdrop().done(function(b){var c=this.calculateZIndex(),d=c+2,e=d-1;this.root.css("z-index",d),b.setZIndex(e),b.show(),this.root.removeClass("hide").addClass("show"),this.accessibilityShow(),this.getTitle().focus(),a("body").addClass("modal-open"),this.root.trigger(g.shown,this)}.bind(this)))},k.prototype.hide=function(){this.isVisible()&&this.getBackdrop().done(function(b){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(),this.hasTransitions()?this.getRoot().one("transitionend webkitTransitionEnd oTransitionEnd",function(){this.getRoot().removeClass("show").addClass("hide")}.bind(this)):this.getRoot().removeClass("show").addClass("hide"),this.root.trigger(g.hidden,this)}.bind(this))},k.prototype.destroy=function(){this.root.remove(),this.root.trigger(g.destroyed,this)},k.prototype.accessibilityShow=function(){a("body").children().each(function(b,c){if(!this.root.is(c)){c=a(c);var d=c.attr("aria-hidden");"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")},k.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");"undefined"==typeof d?c.removeAttr("aria-hidden"):c.attr("aria-hidden",d)}),this.hiddenSiblings=[]},k.prototype.handleTabLock=function(b){if(this.hasFocus()){var c=a(document.activeElement),d=this.modal.find(i.CAN_RECEIVE_FOCUS),e=d.first(),f=d.last();c.is(e)&&b.shiftKey?(f.focus(),b.preventDefault()):c.is(f)&&!b.shiftKey&&(e.focus(),b.preventDefault())}},k.prototype.registerEventListeners=function(){this.getRoot().on("keydown",function(a){this.isVisible()&&(a.keyCode==d.tab?this.handleTabLock(a):a.keyCode==d.escape&&this.hide())}.bind(this)),e.define(this.getModal(),[e.events.activate]),this.getModal().on(e.events.activate,i.HIDE,function(a,b){this.hide(),b.originalEvent.preventDefault()}.bind(this))},k}); \ No newline at end of file diff --git a/lib/amd/src/modal.js b/lib/amd/src/modal.js index b7e1a1adf7d..8485398d46c 100644 --- a/lib/amd/src/modal.js +++ b/lib/amd/src/modal.js @@ -215,23 +215,32 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes', /** * Set the modal title element. * + * This method is overloaded to take either a string value for the title or a jQuery promise that is resolved with + * HTML most commonly from a Str.get_string call. + * * @method setTitle - * @param {string} value The title string + * @param {(string|object)} value The title string or jQuery promise which resolve to the title. */ Modal.prototype.setTitle = function(value) { var title = this.getTitle(); - title.html(value); + + if (typeof value === 'string') { + title.html(value); + } else { + value.then(function(content) { + return title.html(content); + }); + } }; /** * Set the modal body element. * - * This method is overloaded to take either a string - * value for the body or a jQuery promise that is resolved with HTML and Javascript - * most commonly from a Templates.render call. + * This method is overloaded to take either a string value for the body or a jQuery promise that is resolved with + * HTML and Javascript most commonly from a Templates.render call. * * @method setBody - * @param {(string|object)} value The body string or jQuery promise + * @param {(string|object)} value The body string or jQuery promise which resolve to the body. */ Modal.prototype.setBody = function(value) { var body = this.getBody(); From 1896e257aafca9f1c17904bdb673a8b2d16fd8fa Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 16 Aug 2017 12:32:46 +0800 Subject: [PATCH 3/3] MDL-59784 core: Modal factory should listen before fetching templates --- lib/amd/build/modal_factory.min.js | 2 +- lib/amd/src/modal_factory.js | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/lib/amd/build/modal_factory.min.js b/lib/amd/build/modal_factory.min.js index 715247b49a4..b5c4a5893c0 100644 --- a/lib/amd/build/modal_factory.min.js +++ b/lib/amd/build/modal_factory.min.js @@ -1 +1 @@ -define(["jquery","core/modal_events","core/modal_registry","core/modal","core/modal_save_cancel","core/modal_confirm","core/modal_cancel","core/templates","core/notification","core/custom_interaction_events"],function(a,b,c,d,e,f,g,h,i,j){var k={DEFAULT:"core/modal",SAVE_CANCEL:"core/modal_save_cancel",CONFIRM:"core/modal_confirm",CANCEL:"core/modal_cancel"},l={DEFAULT:"DEFAULT",SAVE_CANCEL:"SAVE_CANCEL",CONFIRM:"CONFIRM",CANCEL:"CANCEL"};c.register(l.DEFAULT,d,k.DEFAULT),c.register(l.SAVE_CANCEL,e,k.SAVE_CANCEL),c.register(l.CONFIRM,f,k.CONFIRM),c.register(l.CANCEL,g,k.CANCEL);var m=function(a,c){"undefined"!=typeof c&&(j.define(c,[j.events.activate]),c.on(j.events.activate,function(b,c){a.show(),c.originalEvent.preventDefault()}),a.getRoot().on(b.hidden,function(){c.focus()}))},n=function(b,c,d){c=a(c);var e=b.module,f=new e(c);return m(f,d),f},o=function(b,c){var d=b.template;return h.render(d,{}).then(function(d){var e=a(d);return n(b,e,c)}).fail(i.exception)},p=function(a,b){var d=a.type||l.DEFAULT,e=!!a.large,f=null;return f=c.get(d),f||i.exception({message:"Unable to find modal of type: "+d}),o(f,b).then(function(b){return"undefined"!=typeof a.title&&b.setTitle(a.title),"undefined"!=typeof a.body&&b.setBody(a.body),"undefined"!=typeof a.footer&&b.setFooter(a.footer),e&&b.setLarge(),b})};return{create:p,types:l}}); \ No newline at end of file +define(["jquery","core/modal_events","core/modal_registry","core/modal","core/modal_save_cancel","core/modal_confirm","core/modal_cancel","core/templates","core/notification","core/custom_interaction_events"],function(a,b,c,d,e,f,g,h,i,j){var k={DEFAULT:"core/modal",SAVE_CANCEL:"core/modal_save_cancel",CONFIRM:"core/modal_confirm",CANCEL:"core/modal_cancel"},l={DEFAULT:"DEFAULT",SAVE_CANCEL:"SAVE_CANCEL",CONFIRM:"CONFIRM",CANCEL:"CANCEL"};c.register(l.DEFAULT,d,k.DEFAULT),c.register(l.SAVE_CANCEL,e,k.SAVE_CANCEL),c.register(l.CONFIRM,f,k.CONFIRM),c.register(l.CANCEL,g,k.CANCEL);var m=function(a,c){"undefined"!=typeof c&&(j.define(c,[j.events.activate]),c.on(j.events.activate,function(b,c){a.then(function(a){return a.show(),a}),c.originalEvent.preventDefault()}),a.then(function(a){return a.getRoot().on(b.hidden,function(){c.focus()}),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=h.render(d,{}).then(function(c){var d=a(c);return n(b,d)}).fail(i.exception);return m(e,c),e},p=function(a,b){var d=a.type||l.DEFAULT,e=!!a.large,f=null;return f=c.get(d),f||i.exception({message:"Unable to find modal of type: "+d}),o(f,b).then(function(b){return"undefined"!=typeof a.title&&b.setTitle(a.title),"undefined"!=typeof a.body&&b.setBody(a.body),"undefined"!=typeof a.footer&&b.setFooter(a.footer),e&&b.setLarge(),b})};return{create:p,types:l}}); \ No newline at end of file diff --git a/lib/amd/src/modal_factory.js b/lib/amd/src/modal_factory.js index 68dedf2c832..5339094c8ec 100644 --- a/lib/amd/src/modal_factory.js +++ b/lib/amd/src/modal_factory.js @@ -55,19 +55,27 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal', * is closed. * * @method setUpTrigger - * @param {object} modal The modal instance + * @param {Promise} modalPromise The modal instance * @param {object} triggerElement The jQuery element to open the modal */ - var setUpTrigger = function(modal, triggerElement) { + var setUpTrigger = function(modalPromise, triggerElement) { if (typeof triggerElement != 'undefined') { CustomEvents.define(triggerElement, [CustomEvents.events.activate]); triggerElement.on(CustomEvents.events.activate, function(e, data) { - modal.show(); + modalPromise.then(function(modal) { + modal.show(); + + return modal; + }); data.originalEvent.preventDefault(); }); - modal.getRoot().on(ModalEvents.hidden, function() { - triggerElement.focus(); + modalPromise.then(function(modal) { + modal.getRoot().on(ModalEvents.hidden, function() { + triggerElement.focus(); + }); + + return modal; }); } }; @@ -82,11 +90,10 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal', * @param {object} triggerElement The trigger HTML jQuery object * @return {object} Modal instance */ - var createFromElement = function(registryConf, modalElement, triggerElement) { + var createFromElement = function(registryConf, modalElement) { modalElement = $(modalElement); var module = registryConf.module; var modal = new module(modalElement); - setUpTrigger(modal, triggerElement); return modal; }; @@ -104,12 +111,16 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal', var createFromType = function(registryConf, triggerElement) { var templateName = registryConf.template; - return Templates.render(templateName, {}) + var modalPromise = Templates.render(templateName, {}) .then(function(html) { var modalElement = $(html); - return createFromElement(registryConf, modalElement, triggerElement); + return createFromElement(registryConf, modalElement); }) .fail(Notification.exception); + + setUpTrigger(modalPromise, triggerElement); + + return modalPromise; }; /**