/*! magnific popup - v0.9.9 - 2013-11-15
* http://dimsemenov.com/plugins/magnific-popup/
* copyright (c) 2013 dmitry semenov; */
;(function($) {
/*>>core*/
/**
*
* magnific popup core js file
*
*/
/**
* private static constants
*/
var close_event = 'close',
before_close_event = 'beforeclose',
after_close_event = 'afterclose',
before_append_event = 'beforeappend',
markup_parse_event = 'markupparse',
open_event = 'open',
change_event = 'change',
ns = 'mfp',
event_ns = '.' + ns,
ready_class = 'mfp-ready',
removing_class = 'mfp-removing',
prevent_close_class = 'mfp-prevent-close';
/**
* private vars
*/
var mfp, // as we have only one instance of magnificpopup object, we define it locally to not to use 'this'
magnificpopup = function(){},
_isjq = !!(window.jquery),
_prevstatus,
_window = $(window),
_body,
_document,
_prevcontenttype,
_wrapclasses,
_currpopuptype;
/**
* private functions
*/
var _mfpon = function(name, f) {
mfp.ev.on(ns + name + event_ns, f);
},
_getel = function(classname, appendto, html, raw) {
var el = document.createelement('div');
el.classname = 'mfp-'+classname;
if(html) {
el.innerhtml = html;
}
if(!raw) {
el = $(el);
if(appendto) {
el.appendto(appendto);
}
} else if(appendto) {
appendto.appendchild(el);
}
return el;
},
_mfptrigger = function(e, data) {
mfp.ev.triggerhandler(ns + e, data);
if(mfp.st.callbacks) {
// converts "mfpeventname" to "eventname" callback and triggers it if it's present
e = e.charat(0).tolowercase() + e.slice(1);
if(mfp.st.callbacks[e]) {
mfp.st.callbacks[e].apply(mfp, $.isarray(data) ? data : [data]);
}
}
},
_getclosebtn = function(type) {
if(type !== _currpopuptype || !mfp.currtemplate.closebtn) {
mfp.currtemplate.closebtn = $( mfp.st.closemarkup.replace('%title%', mfp.st.tclose ) );
_currpopuptype = type;
}
return mfp.currtemplate.closebtn;
},
// initialize magnific popup only when called at least once
_checkinstance = function() {
if(!$.magnificpopup.instance) {
mfp = new magnificpopup();
mfp.init();
$.magnificpopup.instance = mfp;
}
},
// css transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
supportstransitions = function() {
var s = document.createelement('p').style, // 's' for style. better to create an element if body yet to exist
v = ['ms','o','moz','webkit']; // 'v' for vendor
if( s['transition'] !== undefined ) {
return true;
}
while( v.length ) {
if( v.pop() + 'transition' in s ) {
return true;
}
}
return false;
};
/**
* public functions
*/
magnificpopup.prototype = {
constructor: magnificpopup,
/**
* initializes magnific popup plugin.
* this function is triggered only once when $.fn.magnificpopup or $.magnificpopup is executed
*/
init: function() {
var appversion = navigator.appversion;
mfp.isie7 = appversion.indexof("msie 7.") !== -1;
mfp.isie8 = appversion.indexof("msie 8.") !== -1;
mfp.islowie = mfp.isie7 || mfp.isie8;
mfp.isandroid = (/android/gi).test(appversion);
mfp.isios = (/iphone|ipad|ipod/gi).test(appversion);
mfp.supportstransition = supportstransitions();
// we disable fixed positioned lightbox on devices that don't handle it nicely.
// if you know a better way of detecting this - let me know.
mfp.probablymobile = (mfp.isandroid || mfp.isios || /(opera mini)|kindle|webos|blackberry|(opera mobi)|(windows phone)|iemobile/i.test(navigator.useragent) );
_body = $(document.body);
_document = $(document);
mfp.popupscache = {};
},
/**
* opens popup
* @param data [description]
*/
open: function(data) {
var i;
if(data.isobj === false) {
// convert jquery collection to array to avoid conflicts later
mfp.items = data.items.toarray();
mfp.index = 0;
var items = data.items,
item;
for(i = 0; i < items.length; i++) {
item = items[i];
if(item.parsed) {
item = item.el[0];
}
if(item === data.el[0]) {
mfp.index = i;
break;
}
}
} else {
mfp.items = $.isarray(data.items) ? data.items : [data.items];
mfp.index = data.index || 0;
}
// if popup is already opened - we just update the content
if(mfp.isopen) {
mfp.updateitemhtml();
return;
}
mfp.types = [];
_wrapclasses = '';
if(data.mainel && data.mainel.length) {
mfp.ev = data.mainel.eq(0);
} else {
mfp.ev = _document;
}
if(data.key) {
if(!mfp.popupscache[data.key]) {
mfp.popupscache[data.key] = {};
}
mfp.currtemplate = mfp.popupscache[data.key];
} else {
mfp.currtemplate = {};
}
mfp.st = $.extend(true, {}, $.magnificpopup.defaults, data );
mfp.fixedcontentpos = mfp.st.fixedcontentpos === 'auto' ? !mfp.probablymobile : mfp.st.fixedcontentpos;
if(mfp.st.modal) {
mfp.st.closeoncontentclick = false;
mfp.st.closeonbgclick = false;
mfp.st.showclosebtn = false;
mfp.st.enableescapekey = false;
}
// building markup
// main containers are created only once
if(!mfp.bgoverlay) {
// dark overlay
mfp.bgoverlay = _getel('bg').on('click'+event_ns, function() {
mfp.close();
});
mfp.wrap = _getel('wrap').attr('tabindex', -1).on('click'+event_ns, function(e) {
if(mfp._checkifclose(e.target)) {
mfp.close();
}
});
mfp.container = _getel('container', mfp.wrap);
}
mfp.contentcontainer = _getel('content');
if(mfp.st.preloader) {
mfp.preloader = _getel('preloader', mfp.container, mfp.st.tloading);
}
// initializing modules
var modules = $.magnificpopup.modules;
for(i = 0; i < modules.length; i++) {
var n = modules[i];
n = n.charat(0).touppercase() + n.slice(1);
mfp['init'+n].call(mfp);
}
_mfptrigger('beforeopen');
if(mfp.st.showclosebtn) {
// close button
if(!mfp.st.closebtninside) {
mfp.wrap.append( _getclosebtn() );
} else {
_mfpon(markup_parse_event, function(e, template, values, item) {
values.close_replacewith = _getclosebtn(item.type);
});
_wrapclasses += ' mfp-close-btn-in';
}
}
if(mfp.st.aligntop) {
_wrapclasses += ' mfp-align-top';
}
if(mfp.fixedcontentpos) {
mfp.wrap.css({
overflow: mfp.st.overflowy,
overflowx: 'hidden',
overflowy: mfp.st.overflowy
});
} else {
mfp.wrap.css({
top: _window.scrolltop(),
position: 'absolute'
});
}
if( mfp.st.fixedbgpos === false || (mfp.st.fixedbgpos === 'auto' && !mfp.fixedcontentpos) ) {
mfp.bgoverlay.css({
height: _document.height(),
position: 'absolute'
});
}
if(mfp.st.enableescapekey) {
// close on esc key
_document.on('keyup' + event_ns, function(e) {
if(e.keycode === 27) {
mfp.close();
}
});
}
_window.on('resize' + event_ns, function() {
mfp.updatesize();
});
if(!mfp.st.closeoncontentclick) {
_wrapclasses += ' mfp-auto-cursor';
}
if(_wrapclasses)
mfp.wrap.addclass(_wrapclasses);
// this triggers recalculation of layout, so we get it once to not to trigger twice
var windowheight = mfp.wh = _window.height();
var windowstyles = {};
if( mfp.fixedcontentpos ) {
if(mfp._hasscrollbar(windowheight)){
var s = mfp._getscrollbarsize();
if(s) {
windowstyles.marginright = s;
}
}
}
if(mfp.fixedcontentpos) {
if(!mfp.isie7) {
windowstyles.overflow = 'hidden';
} else {
// ie7 double-scroll bug
$('body, html').css('overflow', 'hidden');
}
}
var classestoadd = mfp.st.mainclass;
if(mfp.isie7) {
classestoadd += ' mfp-ie7';
}
if(classestoadd) {
mfp._addclasstomfp( classestoadd );
}
// add content
mfp.updateitemhtml();
_mfptrigger('buildcontrols');
// remove scrollbar, add margin e.t.c
$('html').css(windowstyles);
// add everything to dom
mfp.bgoverlay.add(mfp.wrap).prependto( document.body );
// save last focused element
mfp._lastfocusedel = document.activeelement;
// wait for next cycle to allow css transition
settimeout(function() {
if(mfp.content) {
mfp._addclasstomfp(ready_class);
mfp._setfocus();
} else {
// if content is not defined (not loaded e.t.c) we add class only for bg
mfp.bgoverlay.addclass(ready_class);
}
// trap the focus in popup
_document.on('focusin' + event_ns, mfp._onfocusin);
}, 16);
mfp.isopen = true;
mfp.updatesize(windowheight);
_mfptrigger(open_event);
return data;
},
/**
* closes the popup
*/
close: function() {
if(!mfp.isopen) return;
_mfptrigger(before_close_event);
mfp.isopen = false;
// for css3 animation
if(mfp.st.removaldelay && !mfp.islowie && mfp.supportstransition ) {
mfp._addclasstomfp(removing_class);
settimeout(function() {
mfp._close();
}, mfp.st.removaldelay);
} else {
mfp._close();
}
},
/**
* helper for close() function
*/
_close: function() {
_mfptrigger(close_event);
var classestoremove = removing_class + ' ' + ready_class + ' ';
mfp.bgoverlay.detach();
mfp.wrap.detach();
mfp.container.empty();
if(mfp.st.mainclass) {
classestoremove += mfp.st.mainclass + ' ';
}
mfp._removeclassfrommfp(classestoremove);
if(mfp.fixedcontentpos) {
var windowstyles = {marginright: ''};
if(mfp.isie7) {
$('body, html').css('overflow', '');
} else {
windowstyles.overflow = '';
}
$('html').css(windowstyles);
}
_document.off('keyup' + event_ns + ' focusin' + event_ns);
mfp.ev.off(event_ns);
// clean up dom elements that aren't removed
mfp.wrap.attr('class', 'mfp-wrap').removeattr('style');
mfp.bgoverlay.attr('class', 'mfp-bg');
mfp.container.attr('class', 'mfp-container');
// remove close button from target element
if(mfp.st.showclosebtn &&
(!mfp.st.closebtninside || mfp.currtemplate[mfp.curritem.type] === true)) {
if(mfp.currtemplate.closebtn)
mfp.currtemplate.closebtn.detach();
}
if(mfp._lastfocusedel) {
$(mfp._lastfocusedel).focus(); // put tab focus back
}
mfp.curritem = null;
mfp.content = null;
mfp.currtemplate = null;
mfp.prevheight = 0;
_mfptrigger(after_close_event);
},
updatesize: function(winheight) {
if(mfp.isios) {
// fixes ios nav bars https://github.com/dimsemenov/magnific-popup/issues/2
var zoomlevel = document.documentelement.clientwidth / window.innerwidth;
var height = window.innerheight * zoomlevel;
mfp.wrap.css('height', height);
mfp.wh = height;
} else {
mfp.wh = winheight || _window.height();
}
// fixes #84: popup incorrectly positioned with position:relative on body
if(!mfp.fixedcontentpos) {
mfp.wrap.css('height', mfp.wh);
}
_mfptrigger('resize');
},
/**
* set content of popup based on current index
*/
updateitemhtml: function() {
var item = mfp.items[mfp.index];
// detach and perform modifications
mfp.contentcontainer.detach();
if(mfp.content)
mfp.content.detach();
if(!item.parsed) {
item = mfp.parseel( mfp.index );
}
var type = item.type;
_mfptrigger('beforechange', [mfp.curritem ? mfp.curritem.type : '', type]);
// beforechange event works like so:
// _mfpon('beforechange', function(e, prevtype, newtype) { });
mfp.curritem = item;
if(!mfp.currtemplate[type]) {
var markup = mfp.st[type] ? mfp.st[type].markup : false;
// allows to modify markup
_mfptrigger('firstmarkupparse', markup);
if(markup) {
mfp.currtemplate[type] = $(markup);
} else {
// if there is no markup found we just define that template is parsed
mfp.currtemplate[type] = true;
}
}
if(_prevcontenttype && _prevcontenttype !== item.type) {
mfp.container.removeclass('mfp-'+_prevcontenttype+'-holder');
}
var newcontent = mfp['get' + type.charat(0).touppercase() + type.slice(1)](item, mfp.currtemplate[type]);
mfp.appendcontent(newcontent, type);
item.preloaded = true;
_mfptrigger(change_event, item);
_prevcontenttype = item.type;
// append container back after its content changed
mfp.container.prepend(mfp.contentcontainer);
_mfptrigger('afterchange');
},
/**
* set html content of popup
*/
appendcontent: function(newcontent, type) {
mfp.content = newcontent;
if(newcontent) {
if(mfp.st.showclosebtn && mfp.st.closebtninside &&
mfp.currtemplate[type] === true) {
// if there is no markup, we just append close button element inside
if(!mfp.content.find('.mfp-close').length) {
mfp.content.append(_getclosebtn());
}
} else {
mfp.content = newcontent;
}
} else {
mfp.content = '';
}
_mfptrigger(before_append_event);
mfp.container.addclass('mfp-'+type+'-holder');
mfp.contentcontainer.append(mfp.content);
},
/**
* creates magnific popup data object based on given data
* @param {int} index index of item to parse
*/
parseel: function(index) {
var item = mfp.items[index],
type = item.type;
if(item.tagname) {
item = { el: $(item) };
} else {
item = { data: item, src: item.src };
}
if(item.el) {
var types = mfp.types;
// check for 'mfp-type' class
for(var i = 0; i < types.length; i++) {
if( item.el.hasclass('mfp-'+types[i]) ) {
type = types[i];
break;
}
}
item.src = item.el.attr('data-mfp-src');
if(!item.src) {
item.src = item.el.attr('href');
}
}
item.type = type || mfp.st.type || 'inline';
item.index = index;
item.parsed = true;
mfp.items[index] = item;
_mfptrigger('elementparse', item);
return mfp.items[index];
},
/**
* initializes single popup or a group of popups
*/
addgroup: function(el, options) {
var ehandler = function(e) {
e.mfpel = this;
mfp._openclick(e, el, options);
};
if(!options) {
options = {};
}
var ename = 'click.magnificpopup';
options.mainel = el;
if(options.items) {
options.isobj = true;
el.off(ename).on(ename, ehandler);
} else {
options.isobj = false;
if(options.delegate) {
el.off(ename).on(ename, options.delegate , ehandler);
} else {
options.items = el;
el.off(ename).on(ename, ehandler);
}
}
},
_openclick: function(e, el, options) {
var midclick = options.midclick !== undefined ? options.midclick : $.magnificpopup.defaults.midclick;
if(!midclick && ( e.which === 2 || e.ctrlkey || e.metakey ) ) {
return;
}
var disableon = options.disableon !== undefined ? options.disableon : $.magnificpopup.defaults.disableon;
if(disableon) {
if($.isfunction(disableon)) {
if( !disableon.call(mfp) ) {
return true;
}
} else { // else it's number
if( _window.width() < disableon ) {
return true;
}
}
}
if(e.type) {
e.preventdefault();
// this will prevent popup from closing if element is inside and popup is already opened
if(mfp.isopen) {
e.stoppropagation();
}
}
options.el = $(e.mfpel);
if(options.delegate) {
options.items = el.find(options.delegate);
}
mfp.open(options);
},
/**
* updates text on preloader
*/
updatestatus: function(status, text) {
if(mfp.preloader) {
if(_prevstatus !== status) {
mfp.container.removeclass('mfp-s-'+_prevstatus);
}
if(!text && status === 'loading') {
text = mfp.st.tloading;
}
var data = {
status: status,
text: text
};
// allows to modify status
_mfptrigger('updatestatus', data);
status = data.status;
text = data.text;
mfp.preloader.html(text);
mfp.preloader.find('a').on('click', function(e) {
e.stopimmediatepropagation();
});
mfp.container.addclass('mfp-s-'+status);
_prevstatus = status;
}
},
/*
"private" helpers that aren't private at all
*/
// check to close popup or not
// "target" is an element that was clicked
_checkifclose: function(target) {
if($(target).hasclass(prevent_close_class)) {
return;
}
var closeoncontent = mfp.st.closeoncontentclick;
var closeonbg = mfp.st.closeonbgclick;
if(closeoncontent && closeonbg) {
return true;
} else {
// we close the popup if click is on close button or on preloader. or if there is no content.
if(!mfp.content || $(target).hasclass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {
return true;
}
// if click is outside the content
if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) {
if(closeonbg) {
// last check, if the clicked element is in dom, (in case it's removed onclick)
if( $.contains(document, target) ) {
return true;
}
}
} else if(closeoncontent) {
return true;
}
}
return false;
},
_addclasstomfp: function(cname) {
mfp.bgoverlay.addclass(cname);
mfp.wrap.addclass(cname);
},
_removeclassfrommfp: function(cname) {
this.bgoverlay.removeclass(cname);
mfp.wrap.removeclass(cname);
},
_hasscrollbar: function(winheight) {
return ( (mfp.isie7 ? _document.height() : document.body.scrollheight) > (winheight || _window.height()) );
},
_setfocus: function() {
(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
},
_onfocusin: function(e) {
if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
mfp._setfocus();
return false;
}
},
_parsemarkup: function(template, values, item) {
var arr;
if(item.data) {
values = $.extend(item.data, values);
}
_mfptrigger(markup_parse_event, [template, values, item] );
$.each(values, function(key, value) {
if(value === undefined || value === false) {
return true;
}
arr = key.split('_');
if(arr.length > 1) {
var el = template.find(event_ns + '-'+arr[0]);
if(el.length > 0) {
var attr = arr[1];
if(attr === 'replacewith') {
if(el[0] !== value[0]) {
el.replacewith(value);
}
} else if(attr === 'img') {
if(el.is('img')) {
el.attr('src', value);
} else {
el.replacewith( '' );
}
} else {
el.attr(arr[1], value);
}
}
} else {
template.find(event_ns + '-'+key).html(value);
}
});
},
_getscrollbarsize: function() {
// thx david
if(mfp.scrollbarsize === undefined) {
var scrolldiv = document.createelement("div");
scrolldiv.id = "mfp-sbm";
scrolldiv.style.csstext = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
document.body.appendchild(scrolldiv);
mfp.scrollbarsize = scrolldiv.offsetwidth - scrolldiv.clientwidth;
document.body.removechild(scrolldiv);
}
return mfp.scrollbarsize;
}
}; /* magnificpopup core prototype end */
/**
* public static functions
*/
$.magnificpopup = {
instance: null,
proto: magnificpopup.prototype,
modules: [],
open: function(options, index) {
_checkinstance();
if(!options) {
options = {};
} else {
options = $.extend(true, {}, options);
}
options.isobj = true;
options.index = index || 0;
return this.instance.open(options);
},
close: function() {
return $.magnificpopup.instance && $.magnificpopup.instance.close();
},
registermodule: function(name, module) {
if(module.options) {
$.magnificpopup.defaults[name] = module.options;
}
$.extend(this.proto, module.proto);
this.modules.push(name);
},
defaults: {
// info about options is in docs:
// http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
disableon: 0,
key: null,
midclick: false,
mainclass: '',
preloader: true,
focus: '', // css selector of input to focus after popup is opened
closeoncontentclick: false,
closeonbgclick: true,
closebtninside: true,
showclosebtn: true,
enableescapekey: true,
modal: false,
aligntop: false,
removaldelay: 0,
fixedcontentpos: 'auto',
fixedbgpos: 'auto',
overflowy: 'auto',
closemarkup: '',
tclose: 'close (esc)',
tloading: 'loading...'
}
};
$.fn.magnificpopup = function(options) {
_checkinstance();
var jqel = $(this);
// we call some api method of first param is a string
if (typeof options === "string" ) {
if(options === 'open') {
var items,
itemopts = _isjq ? jqel.data('magnificpopup') : jqel[0].magnificpopup,
index = parseint(arguments[1], 10) || 0;
if(itemopts.items) {
items = itemopts.items[index];
} else {
items = jqel;
if(itemopts.delegate) {
items = items.find(itemopts.delegate);
}
items = items.eq( index );
}
mfp._openclick({mfpel:items}, jqel, itemopts);
} else {
if(mfp.isopen)
mfp[options].apply(mfp, array.prototype.slice.call(arguments, 1));
}
} else {
// clone options obj
options = $.extend(true, {}, options);
/*
* as zepto doesn't support .data() method for objects
* and it works only in normal browsers
* we assign "options" object directly to the dom element. ftw!
*/
if(_isjq) {
jqel.data('magnificpopup', options);
} else {
jqel[0].magnificpopup = options;
}
mfp.addgroup(jqel, options);
}
return jqel;
};
//quick benchmark
/*
var start = performance.now(),
i,
rounds = 1000;
for(i = 0; i < rounds; i++) {
}
console.log('test #1:', performance.now() - start);
start = performance.now();
for(i = 0; i < rounds; i++) {
}
console.log('test #2:', performance.now() - start);
*/
/*>>core*/
/*>>inline*/
var inline_ns = 'inline',
_hiddenclass,
_inlineplaceholder,
_lastinlineelement,
_putinlineelementsback = function() {
if(_lastinlineelement) {
_inlineplaceholder.after( _lastinlineelement.addclass(_hiddenclass) ).detach();
_lastinlineelement = null;
}
};
$.magnificpopup.registermodule(inline_ns, {
options: {
hiddenclass: 'hide', // will be appended with `mfp-` prefix
markup: '',
tnotfound: 'content not found'
},
proto: {
initinline: function() {
mfp.types.push(inline_ns);
_mfpon(close_event+'.'+inline_ns, function() {
_putinlineelementsback();
});
},
getinline: function(item, template) {
_putinlineelementsback();
if(item.src) {
var inlinest = mfp.st.inline,
el = $(item.src);
if(el.length) {
// if target element has parent - we replace it with placeholder and put it back after popup is closed
var parent = el[0].parentnode;
if(parent && parent.tagname) {
if(!_inlineplaceholder) {
_hiddenclass = inlinest.hiddenclass;
_inlineplaceholder = _getel(_hiddenclass);
_hiddenclass = 'mfp-'+_hiddenclass;
}
// replace target inline element with placeholder
_lastinlineelement = el.after(_inlineplaceholder).detach().removeclass(_hiddenclass);
}
mfp.updatestatus('ready');
} else {
mfp.updatestatus('error', inlinest.tnotfound);
el = $('