MDL-62171 Theme boost: modal accessibility focus
[moodle.git] / lib / amd / build / modal.min.js
1 define(["jquery","core/templates","core/notification","core/key_codes","core/custom_interaction_events","core/modal_backdrop","core/event","core/modal_events"],function(a,b,c,d,e,f,g,h){var i,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]",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=0,m=function(b){this.root=a(b),this.modal=this.root.find(j.MODAL),this.header=this.modal.find(j.HEADER),this.title=this.header.find(j.TITLE),this.body=this.modal.find(j.BODY),this.footer=this.modal.find(j.FOOTER),this.hiddenSiblings=[],this.isAttached=!1,this.bodyJS=null,this.footerJS=null,this.modalCount=l++,this.root.is(j.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 m.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)},m.prototype.countOtherVisibleModals=function(){var b=0;return a("body").find(j.CONTAINER).each(function(c,d){d=a(d),!this.root.is(d)&&d.hasClass("show")&&b++}.bind(this)),b},m.prototype.getBackdrop=function(){return i||(i=b.render(k.BACKDROP,{}).then(function(b){var c=a(b);return new f(c)}).fail(c.exception)),i},m.prototype.getRoot=function(){return this.root},m.prototype.getModal=function(){return this.modal},m.prototype.getTitle=function(){return this.title},m.prototype.getBody=function(){return this.body},m.prototype.getFooter=function(){return this.footer},m.prototype.getModalCount=function(){return this.modalCount},m.prototype.setTitle=function(a){var b=this.getTitle();this.asyncSet(a,b.html.bind(b))},m.prototype.setBody=function(d){var e=this.getBody();if("string"==typeof d)e.html(d),g.notifyFilterContentUpdated(e),this.getRoot().trigger(h.bodyRendered,this);else{var f="amd-modal-js-pending-id-"+this.getModalCount();M.util.js_pending(f);var i=null;if(e.css("overflow","hidden"),"pending"==d.state()){var j=e.innerHeight();j<100&&(j=100),e.animate({height:j+"px"},150),e.html(""),i=b.render(k.LOADING,{}).then(function(b){var c=a(b).hide();return e.html(c),c.fadeIn(150),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 i=e.innerHeight();e.css("height",f+"px"),d=e.animate({height:i+"px",opacity:1},{duration:150,queue:!1}).promise()}else e.html(a);return c&&(this.isAttached?b.runTemplateJS(c):this.bodyJS=c),g.notifyFilterContentUpdated(e),this.getRoot().trigger(h.bodyRendered,this),d}.bind(this)).fail(c.exception).always(function(){e.css("height",""),e.css("overflow",""),e.css("opacity",""),M.util.js_complete(f)}).fail(c.exception)}},m.prototype.setFooter=function(a){this.showFooter();var c=this.getFooter();"string"==typeof a?c.html(a):b.render(k.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))},m.prototype.hasFooterContent=function(){return!!this.getFooter().children().length},m.prototype.hideFooter=function(){this.getFooter().addClass("hidden")},m.prototype.showFooter=function(){this.getFooter().removeClass("hidden")},m.prototype.setLarge=function(){this.isLarge()||this.getModal().addClass("modal-lg")},m.prototype.isLarge=function(){return this.getModal().hasClass("modal-lg")},m.prototype.setSmall=function(){this.isSmall()||this.getModal().removeClass("modal-lg")},m.prototype.isSmall=function(){return!this.getModal().hasClass("modal-lg")},m.prototype.calculateZIndex=function(){var b=a(j.DIALOG+", "+j.MENU_BAR+", "+j.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},m.prototype.isVisible=function(){return this.root.hasClass("show")},m.prototype.hasFocus=function(){var b=a(document.activeElement);return this.root.is(b)||this.root.has(b).length},m.prototype.hasTransitions=function(){return this.getRoot().hasClass("fade")},m.prototype.show=function(){this.isVisible()||(this.hasFooterContent()?this.showFooter():this.hideFooter(),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.getModal().focus(),a("body").addClass("modal-open"),this.root.trigger(h.shown,this)}.bind(this)))},m.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(h.hidden,this)}.bind(this))},m.prototype.destroy=function(){this.root.remove(),this.root.trigger(h.destroyed,this)},m.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")},m.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=[]},m.prototype.handleTabLock=function(b){if(this.hasFocus()){var c=a(document.activeElement),d=this.modal.find(j.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())}},m.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,j.HIDE,function(a,b){this.hide(),b.originalEvent.preventDefault()}.bind(this))},m.prototype.asyncSet=function(b,d){var e=b;return"object"==typeof b&&b.hasOwnProperty("then")||(e=a.Deferred(),e.resolve(b)),e.then(function(a){d(a)}).fail(c.exception),e},m});