(function(root,factory){if(typeof define==='function'&&define.amd){define(['jquery'],function($){return factory(root,$)})}else if(typeof exports==='object'){factory(root,require('jquery'))}else{factory(root,root.jQuery||root.Zepto)}})(this,function(global,$){'use strict';/** * Name of the plugin * @private * @type {String} */ var pluginName='remodal';/** * Namespace for CSS and events * @private * @type {String} */ var namespace=global.remodalGlobals&&global.remodalGlobals.namespace||pluginName;/** * Default settings * @private * @type {Object} */ var defaults=$.extend({hashTracking:!0,closeOnConfirm:!0,closeOnCancel:!0,closeOnEscape:!0,closeOnAnyClick:!0},global.remodalGlobals&&global.remodalGlobals.defaults);/** * Current modal * @private * @type {Remodal} */ var current;/** * Scrollbar position * @private * @type {Number} */ var scrollTop;/** * Get a transition duration in ms * @private * @param {jQuery} $elem * @return {Number} */ function getTransitionDuration($elem){var duration=$elem.css('transition-duration')||$elem.css('-webkit-transition-duration')||$elem.css('-moz-transition-duration')||$elem.css('-o-transition-duration')||$elem.css('-ms-transition-duration')||'0s';var delay=$elem.css('transition-delay')||$elem.css('-webkit-transition-delay')||$elem.css('-moz-transition-delay')||$elem.css('-o-transition-delay')||$elem.css('-ms-transition-delay')||'0s';var max;var len;var num;var i;duration=duration.split(', ');delay=delay.split(', '); for(i=0,len=duration.length,max=Number.NEGATIVE_INFINITY;imax){max=num}}return num*1000}/** * Get a scrollbar width * @private * @return {Number} */ function getScrollbarWidth(){if($(document.body).height()<=$(window).height()){return 0}var outer=document.createElement('div');var inner=document.createElement('div');var widthNoScroll;var widthWithScroll;outer.style.visibility='hidden';outer.style.width='100px';document.body.appendChild(outer);widthNoScroll=outer.offsetWidth; outer.style.overflow='scroll'; inner.style.width='100%';outer.appendChild(inner);widthWithScroll=inner.offsetWidth; outer.parentNode.removeChild(outer);return widthNoScroll-widthWithScroll}/** * Lock the screen * @private */ function lockScreen(){var $html=$('html');var lockedClass=namespace+'-is-locked';var paddingRight;var $body;if(!$html.hasClass(lockedClass)){$body=$(document.body); paddingRight=parseInt($body.css('padding-right'),10)+getScrollbarWidth();$body.css('padding-right',paddingRight+'px');$html.addClass(lockedClass)}}/** * Unlock the screen * @private */ function unlockScreen(){var $html=$('html');var lockedClass=namespace+'-is-locked';var paddingRight;var $body;if($html.hasClass(lockedClass)){$body=$(document.body); paddingRight=parseInt($body.css('padding-right'),10)-getScrollbarWidth();$body.css('padding-right',paddingRight+'px');$html.removeClass(lockedClass)}}/** * Parse a string with options * @private * @param str * @returns {Object} */ function parseOptions(str){var obj={};var arr;var len;var val;var i; str=str.replace(/\s*:\s*/g,':').replace(/\s*,\s*/g,','); arr=str.split(',');for(i=0,len=arr.length;i').addClass(namespace+'-overlay');remodal.$body.append(remodal.$overlay)}remodal.$bg=$('.'+namespace+'-bg');remodal.$closeButton=$('').addClass(namespace+'-close');remodal.$wrapper=$('
').addClass(namespace+'-wrapper');remodal.$modal=$modal;remodal.$modal.addClass(namespace);remodal.$modal.css('visibility','visible');remodal.$modal.append(remodal.$closeButton);remodal.$wrapper.append(remodal.$modal);remodal.$body.append(remodal.$wrapper);remodal.$confirmButton=remodal.$modal.find('.'+namespace+'-confirm');remodal.$cancelButton=remodal.$modal.find('.'+namespace+'-cancel'); tdOverlay=getTransitionDuration(remodal.$overlay);tdModal=getTransitionDuration(remodal.$modal);tdBg=getTransitionDuration(remodal.$bg);remodal.td=Math.max(tdOverlay,tdModal,tdBg); remodal.$wrapper.on('click.'+namespace,'.'+namespace+'-close',function(e){e.preventDefault();remodal.close()}); remodal.$wrapper.on('click.'+namespace,'.'+namespace+'-cancel',function(e){e.preventDefault();remodal.$modal.trigger('cancel');if(remodal.settings.closeOnCancel){remodal.close('cancellation')}}); remodal.$wrapper.on('click.'+namespace,'.'+namespace+'-confirm',function(e){e.preventDefault();remodal.$modal.trigger('confirm');if(remodal.settings.closeOnConfirm){remodal.close('confirmation')}}); $(document).on('keyup.'+namespace,function(e){if(e.keyCode===27&&remodal.settings.closeOnEscape){remodal.close()}}); remodal.$wrapper.on('click.'+namespace,function(e){var $target=$(e.target);if(!$target.hasClass(namespace+'-wrapper')){return}if(remodal.settings.closeOnAnyClick){remodal.close()}});remodal.index=$[pluginName].lookup.push(remodal)-1;remodal.busy=!1}/** * Open a modal window * @public */ Remodal.prototype.open=function(){ if(this.busy){return}var remodal=this;var id;remodal.busy=!0;remodal.$modal.trigger('open');id=remodal.$modal.attr('data-'+pluginName+'-id');if(id&&remodal.settings.hashTracking){scrollTop=$(window).scrollTop();location.hash=id}if(current&¤t!==remodal){current.$overlay.hide();current.$wrapper.hide();current.$body.removeClass(namespace+'-is-active')}current=remodal;lockScreen();remodal.$overlay.show();remodal.$wrapper.show();setTimeout(function(){remodal.$body.addClass(namespace+'-is-active');remodal.$wrapper.scrollTop(0);setTimeout(function(){remodal.busy=!1;remodal.$modal.trigger('opened')},remodal.td+50)},25)};/** * Close a modal window * @public * @param {String|undefined} reason A reason to close */ Remodal.prototype.close=function(reason){ if(this.busy){return}var remodal=this;remodal.busy=!0;remodal.$modal.trigger({type:'close',reason:reason});if(remodal.settings.hashTracking&&remodal.$modal.attr('data-'+pluginName+'-id')===location.hash.substr(1)){location.hash='';$(window).scrollTop(scrollTop)}remodal.$body.removeClass(namespace+'-is-active');setTimeout(function(){remodal.$overlay.hide();remodal.$wrapper.hide();unlockScreen();remodal.busy=!1;remodal.$modal.trigger({type:'closed',reason:reason})},remodal.td+50)};/** * Special plugin object for instances. * @public * @type {Object} */ $[pluginName]={lookup:[]};/** * Plugin constructor * @param {Object} options * @returns {JQuery} * @constructor */ $.fn[pluginName]=function(opts){var instance;var $elem;this.each(function(index,elem){$elem=$(elem);if($elem.data(pluginName)==null){instance=new Remodal($elem,opts);$elem.data(pluginName,instance.index);if(instance.settings.hashTracking&&$elem.attr('data-'+pluginName+'-id')===location.hash.substr(1)){instance.open()}}else{instance=$[pluginName].lookup[$elem.data(pluginName)]}});return instance};$(document).ready(function(){ $(document).on('click','[data-'+pluginName+'-target]',function(e){e.preventDefault();var elem=e.currentTarget;var id=elem.getAttribute('data-'+pluginName+'-target');var $target=$('[data-'+pluginName+'-id='+id+']');$[pluginName].lookup[$target.data(pluginName)].open()}); $(document).find('.'+namespace).each(function(i,container){var $container=$(container);var options=$container.data(pluginName+'-options');if(!options){options={}}else if(typeof options==='string'||options instanceof String){options=parseOptions(options)}$container[pluginName](options)})});/** * Hashchange handler * @private * @param {Event} e * @param {Boolean} [closeOnEmptyHash=true] */ function hashHandler(e,closeOnEmptyHash){var id=location.hash.replace('#','');var instance;var $elem;if(typeof closeOnEmptyHash==='undefined'){closeOnEmptyHash=!0}if(!id){if(closeOnEmptyHash){ if(current&&!current.busy&¤t.settings.hashTracking){current.close()}}}else{ try{$elem=$('[data-'+pluginName+'-id='+id.replace(new RegExp('/','g'),'\\/')+']')}catch(err){}if($elem&&$elem.length){instance=$[pluginName].lookup[$elem.data(pluginName)];if(instance&&instance.settings.hashTracking){instance.open()}}}}$(window).bind('hashchange.'+namespace,hashHandler)});