Guenni007

jquery.magnific-popup

Mar 22nd, 2021 (edited)
623
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*! Magnific Popup - v1.2.0 - 2020-12-22
  2. * http://dimsemenov.com/plugins/magnific-popup/
  3. * Copyright (c) 2016 Dmitry Semenov; */
  4. ;(function (factory) {
  5. if (typeof define === 'function' && define.amd) {
  6.  // AMD. Register as an anonymous module.
  7.  define(['jquery'], factory);
  8.  } else if (typeof exports === 'object') {
  9.  // Node/CommonJS
  10.  factory(require('jquery'));
  11.  } else {
  12.  // Browser globals
  13.  factory(window.jQuery || window.Zepto);
  14.  }
  15.  }(function($) {
  16.  
  17. /*>>core*/
  18. /**
  19.  *
  20.  * Magnific Popup Core JS file
  21.  *
  22.  */
  23.  
  24.  
  25. /**
  26.  * Private static constants
  27.  */
  28. var CLOSE_EVENT = 'Close',
  29.     BEFORE_CLOSE_EVENT = 'BeforeClose',
  30.     AFTER_CLOSE_EVENT = 'AfterClose',
  31.     BEFORE_APPEND_EVENT = 'BeforeAppend',
  32.     MARKUP_PARSE_EVENT = 'MarkupParse',
  33.     OPEN_EVENT = 'Open',
  34.     CHANGE_EVENT = 'Change',
  35.     NS = 'mfp',
  36.     EVENT_NS = '.' + NS,
  37.     READY_CLASS = 'mfp-ready',
  38.     REMOVING_CLASS = 'mfp-removing',
  39.     PREVENT_CLOSE_CLASS = 'mfp-prevent-close';
  40.  
  41.  
  42. /**
  43.  * Private vars
  44.  */
  45. /*jshint -W079 */
  46. var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'
  47.     MagnificPopup = function(){},
  48.     _isJQ = !!(window.jQuery),
  49.     _prevStatus,
  50.     _window = $(window),
  51.     _document,
  52.     _prevContentType,
  53.     _wrapClasses,
  54.     _currPopupType;
  55.  
  56.  
  57. /**
  58.  * Private functions
  59.  */
  60. var _mfpOn = function(name, f) {
  61.         mfp.ev.on(NS + name + EVENT_NS, f);
  62.     },
  63.     _getEl = function(className, appendTo, html, raw) {
  64.         var el = document.createElement('div');
  65.         el.className = 'mfp-'+className;
  66.         if(html) {
  67.             el.innerHTML = html;
  68.         }
  69.         if(!raw) {
  70.             el = $(el);
  71.             if(appendTo) {
  72.                 el.appendTo(appendTo);
  73.             }
  74.         } else if(appendTo) {
  75.             appendTo.appendChild(el);
  76.         }
  77.         return el;
  78.     },
  79.     _mfpTrigger = function(e, data) {
  80.         mfp.ev.triggerHandler(NS + e, data);
  81.  
  82.         if(mfp.st.callbacks) {
  83.             // converts "mfpEventName" to "eventName" callback and triggers it if it's present
  84.             e = e.charAt(0).toLowerCase() + e.slice(1);
  85.             if(mfp.st.callbacks[e]) {
  86.                 mfp.st.callbacks[e].apply(mfp, Array.isArray(data) ? data : [data]);
  87.             }
  88.         }
  89.     },
  90.     _getCloseBtn = function(type) {
  91.         if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {
  92.             mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );
  93.             _currPopupType = type;
  94.         }
  95.         return mfp.currTemplate.closeBtn;
  96.     },
  97.     // Initialize Magnific Popup only when called at least once
  98.     _checkInstance = function() {
  99.         if(!$.magnificPopup.instance) {
  100.             /*jshint -W020 */
  101.             mfp = new MagnificPopup();
  102.             mfp.init();
  103.             $.magnificPopup.instance = mfp;
  104.         }
  105.     },
  106.     // CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
  107.     supportsTransitions = function() {
  108.         var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist
  109.             v = ['ms','O','Moz','Webkit']; // 'v' for vendor
  110.  
  111.         if( s['transition'] !== undefined ) {
  112.             return true;
  113.         }
  114.            
  115.         while( v.length ) {
  116.             if( v.pop() + 'Transition' in s ) {
  117.                 return true;
  118.             }
  119.         }
  120.                
  121.         return false;
  122.     };
  123.  
  124.  
  125.  
  126. /**
  127.  * Public functions
  128.  */
  129. MagnificPopup.prototype = {
  130.  
  131.     constructor: MagnificPopup,
  132.  
  133.     /**
  134.      * Initializes Magnific Popup plugin.
  135.      * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed
  136.      */
  137.     init: function() {
  138.         var appVersion = navigator.appVersion;
  139.         mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener;
  140.         mfp.isAndroid = (/android/gi).test(appVersion);
  141.         mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
  142.         mfp.supportsTransition = supportsTransitions();
  143.  
  144.         // We disable fixed positioned lightbox on devices that don't handle it nicely.
  145.         // If you know a better way of detecting this - let me know.
  146.         mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );
  147.         _document = $(document);
  148.  
  149.         mfp.popupsCache = {};
  150.     },
  151.  
  152.     /**
  153.      * Opens popup
  154.      * @param  data [description]
  155.      */
  156.     open: function(data) {
  157.  
  158.         var i;
  159.  
  160.         if(data.isObj === false) {
  161.             // convert jQuery collection to array to avoid conflicts later
  162.             mfp.items = data.items.toArray();
  163.  
  164.             mfp.index = 0;
  165.             var items = data.items,
  166.                 item;
  167.             for(i = 0; i < items.length; i++) {
  168.                 item = items[i];
  169.                 if(item.parsed) {
  170.                     item = item.el[0];
  171.                 }
  172.                 if(item === data.el[0]) {
  173.                     mfp.index = i;
  174.                     break;
  175.                 }
  176.             }
  177.         } else {
  178.             mfp.items = Array.isArray(data.items) ? data.items : [data.items];
  179.             mfp.index = data.index || 0;
  180.         }
  181.  
  182.         // if popup is already opened - we just update the content
  183.         if(mfp.isOpen) {
  184.             mfp.updateItemHTML();
  185.             return;
  186.         }
  187.        
  188.         mfp.types = [];
  189.         _wrapClasses = '';
  190.         if(data.mainEl && data.mainEl.length) {
  191.             mfp.ev = data.mainEl.eq(0);
  192.         } else {
  193.             mfp.ev = _document;
  194.         }
  195.  
  196.         if(data.key) {
  197.             if(!mfp.popupsCache[data.key]) {
  198.                 mfp.popupsCache[data.key] = {};
  199.             }
  200.             mfp.currTemplate = mfp.popupsCache[data.key];
  201.         } else {
  202.             mfp.currTemplate = {};
  203.         }
  204.  
  205.  
  206.  
  207.         mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data );
  208.         mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;
  209.  
  210.         if(mfp.st.modal) {
  211.             mfp.st.closeOnContentClick = false;
  212.             mfp.st.closeOnBgClick = false;
  213.             mfp.st.showCloseBtn = false;
  214.             mfp.st.enableEscapeKey = false;
  215.         }
  216.        
  217.  
  218.         // Building markup
  219.         // main containers are created only once
  220.         if(!mfp.bgOverlay) {
  221.  
  222.             // Dark overlay
  223.             mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {
  224.                 mfp.close();
  225.             });
  226.  
  227.             mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {
  228.                 if(mfp._checkIfClose(e.target)) {
  229.                     mfp.close();
  230.                 }
  231.             });
  232.  
  233.             mfp.container = _getEl('container', mfp.wrap);
  234.         }
  235.  
  236.         mfp.contentContainer = _getEl('content');
  237.         if(mfp.st.preloader) {
  238.             mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);
  239.         }
  240.  
  241.  
  242.         // Initializing modules
  243.         var modules = $.magnificPopup.modules;
  244.         for(i = 0; i < modules.length; i++) {
  245.             var n = modules[i];
  246.             n = n.charAt(0).toUpperCase() + n.slice(1);
  247.             mfp['init'+n].call(mfp);
  248.         }
  249.         _mfpTrigger('BeforeOpen');
  250.  
  251.  
  252.         if(mfp.st.showCloseBtn) {
  253.             // Close button
  254.             if(!mfp.st.closeBtnInside) {
  255.                 mfp.wrap.append( _getCloseBtn() );
  256.             } else {
  257.                 _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
  258.                     values.close_replaceWith = _getCloseBtn(item.type);
  259.                 });
  260.                 _wrapClasses += ' mfp-close-btn-in';
  261.             }
  262.         }
  263.  
  264.         if(mfp.st.alignTop) {
  265.             _wrapClasses += ' mfp-align-top';
  266.         }
  267.  
  268.    
  269.  
  270.         if(mfp.fixedContentPos) {
  271.             mfp.wrap.css({
  272.                 overflow: mfp.st.overflowY,
  273.                 overflowX: 'hidden',
  274.                 overflowY: mfp.st.overflowY
  275.             });
  276.         } else {
  277.             mfp.wrap.css({
  278.                 top: _window.scrollTop(),
  279.                 position: 'absolute'
  280.             });
  281.         }
  282.         if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {
  283.             mfp.bgOverlay.css({
  284.                 height: _document.height(),
  285.                 position: 'absolute'
  286.             });
  287.         }
  288.  
  289.        
  290.  
  291.         if(mfp.st.enableEscapeKey) {
  292.             // Close on ESC key
  293.             _document.on('keyup' + EVENT_NS, function(e) {
  294.                 if(e.keyCode === 27) {
  295.                     mfp.close();
  296.                 }
  297.             });
  298.         }
  299.  
  300.         _window.on('resize' + EVENT_NS, function() {
  301.             mfp.updateSize();
  302.         });
  303.  
  304.  
  305.         if(!mfp.st.closeOnContentClick) {
  306.             _wrapClasses += ' mfp-auto-cursor';
  307.         }
  308.        
  309.         if(_wrapClasses)
  310.             mfp.wrap.addClass(_wrapClasses);
  311.  
  312.  
  313.         // this triggers recalculation of layout, so we get it once to not to trigger twice
  314.         var windowHeight = mfp.wH = _window.height();
  315.  
  316.        
  317.         var windowStyles = {};
  318.  
  319.         if( mfp.fixedContentPos ) {
  320.             if(mfp._hasScrollBar(windowHeight)){
  321.                 var s = mfp._getScrollbarSize();
  322.                 if(s) {
  323.                     windowStyles.marginRight = s;
  324.                 }
  325.             }
  326.         }
  327.  
  328.         if(mfp.fixedContentPos) {
  329.             if(!mfp.isIE7) {
  330.                 windowStyles.overflow = 'hidden';
  331.             } else {
  332.                 // ie7 double-scroll bug
  333.                 $('body, html').css('overflow', 'hidden');
  334.             }
  335.         }
  336.  
  337.        
  338.        
  339.         var classesToadd = mfp.st.mainClass;
  340.         if(mfp.isIE7) {
  341.             classesToadd += ' mfp-ie7';
  342.         }
  343.         if(classesToadd) {
  344.             mfp._addClassToMFP( classesToadd );
  345.         }
  346.  
  347.         // add content
  348.         mfp.updateItemHTML();
  349.  
  350.         _mfpTrigger('BuildControls');
  351.  
  352.         // remove scrollbar, add margin e.t.c
  353.         $('html').css(windowStyles);
  354.        
  355.         // add everything to DOM
  356.         mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );
  357.  
  358.         // Save last focused element
  359.         mfp._lastFocusedEl = document.activeElement;
  360.        
  361.         // Wait for next cycle to allow CSS transition
  362.         setTimeout(function() {
  363.            
  364.             if(mfp.content) {
  365.                 mfp._addClassToMFP(READY_CLASS);
  366.                 mfp._setFocus();
  367.             } else {
  368.                 // if content is not defined (not loaded e.t.c) we add class only for BG
  369.                 mfp.bgOverlay.addClass(READY_CLASS);
  370.             }
  371.            
  372.             // Trap the focus in popup
  373.             _document.on('focusin' + EVENT_NS, mfp._onFocusIn);
  374.  
  375.         }, 16);
  376.  
  377.         mfp.isOpen = true;
  378.         mfp.updateSize(windowHeight);
  379.         _mfpTrigger(OPEN_EVENT);
  380.  
  381.         return data;
  382.     },
  383.  
  384.     /**
  385.      * Closes the popup
  386.      */
  387.     close: function() {
  388.         if(!mfp.isOpen) return;
  389.         _mfpTrigger(BEFORE_CLOSE_EVENT);
  390.  
  391.         mfp.isOpen = false;
  392.         // for CSS3 animation
  393.         if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition )  {
  394.             mfp._addClassToMFP(REMOVING_CLASS);
  395.             setTimeout(function() {
  396.                 mfp._close();
  397.             }, mfp.st.removalDelay);
  398.         } else {
  399.             mfp._close();
  400.         }
  401.     },
  402.  
  403.     /**
  404.      * Helper for close() function
  405.      */
  406.     _close: function() {
  407.         _mfpTrigger(CLOSE_EVENT);
  408.  
  409.         var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';
  410.  
  411.         mfp.bgOverlay.detach();
  412.         mfp.wrap.detach();
  413.         mfp.container.empty();
  414.  
  415.         if(mfp.st.mainClass) {
  416.             classesToRemove += mfp.st.mainClass + ' ';
  417.         }
  418.  
  419.         mfp._removeClassFromMFP(classesToRemove);
  420.  
  421.         if(mfp.fixedContentPos) {
  422.             var windowStyles = {marginRight: ''};
  423.             if(mfp.isIE7) {
  424.                 $('body, html').css('overflow', '');
  425.             } else {
  426.                 windowStyles.overflow = '';
  427.             }
  428.             $('html').css(windowStyles);
  429.         }
  430.        
  431.         _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);
  432.         mfp.ev.off(EVENT_NS);
  433.  
  434.         // clean up DOM elements that aren't removed
  435.         mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');
  436.         mfp.bgOverlay.attr('class', 'mfp-bg');
  437.         mfp.container.attr('class', 'mfp-container');
  438.  
  439.         // remove close button from target element
  440.         if(mfp.st.showCloseBtn &&
  441.         (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {
  442.             if(mfp.currTemplate.closeBtn)
  443.                 mfp.currTemplate.closeBtn.detach();
  444.         }
  445.  
  446.  
  447.         if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
  448.             $(mfp._lastFocusedEl).focus(); // put tab focus back
  449.         }
  450.         mfp.currItem = null;   
  451.         mfp.content = null;
  452.         mfp.currTemplate = null;
  453.         mfp.prevHeight = 0;
  454.  
  455.         _mfpTrigger(AFTER_CLOSE_EVENT);
  456.     },
  457.    
  458.     updateSize: function(winHeight) {
  459.  
  460.         if(mfp.isIOS) {
  461.             // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
  462.             var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
  463.             var height = window.innerHeight * zoomLevel;
  464.             mfp.wrap.css('height', height);
  465.             mfp.wH = height;
  466.         } else {
  467.             mfp.wH = winHeight || _window.height();
  468.         }
  469.         // Fixes #84: popup incorrectly positioned with position:relative on body
  470.         if(!mfp.fixedContentPos) {
  471.             mfp.wrap.css('height', mfp.wH);
  472.         }
  473.  
  474.         _mfpTrigger('Resize');
  475.  
  476.     },
  477.  
  478.     /**
  479.      * Set content of popup based on current index
  480.      */
  481.     updateItemHTML: function() {
  482.         var item = mfp.items[mfp.index];
  483.  
  484.         // Detach and perform modifications
  485.         mfp.contentContainer.detach();
  486.  
  487.         if(mfp.content)
  488.             mfp.content.detach();
  489.  
  490.         if(!item.parsed) {
  491.             item = mfp.parseEl( mfp.index );
  492.         }
  493.  
  494.         var type = item.type;
  495.  
  496.         _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
  497.         // BeforeChange event works like so:
  498.         // _mfpOn('BeforeChange', function(e, prevType, newType) { });
  499.  
  500.         mfp.currItem = item;
  501.  
  502.         if(!mfp.currTemplate[type]) {
  503.             var markup = mfp.st[type] ? mfp.st[type].markup : false;
  504.  
  505.             // allows to modify markup
  506.             _mfpTrigger('FirstMarkupParse', markup);
  507.  
  508.             if(markup) {
  509.                 mfp.currTemplate[type] = $(markup);
  510.             } else {
  511.                 // if there is no markup found we just define that template is parsed
  512.                 mfp.currTemplate[type] = true;
  513.             }
  514.         }
  515.  
  516.         if(_prevContentType && _prevContentType !== item.type) {
  517.             mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
  518.         }
  519.  
  520.         var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
  521.         mfp.appendContent(newContent, type);
  522.  
  523.         item.preloaded = true;
  524.  
  525.         _mfpTrigger(CHANGE_EVENT, item);
  526.         _prevContentType = item.type;
  527.  
  528.         // Append container back after its content changed
  529.         mfp.container.prepend(mfp.contentContainer);
  530.  
  531.         _mfpTrigger('AfterChange');
  532.     },
  533.  
  534.  
  535.     /**
  536.      * Set HTML content of popup
  537.      */
  538.     appendContent: function(newContent, type) {
  539.         mfp.content = newContent;
  540.  
  541.         if(newContent) {
  542.             if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
  543.                 mfp.currTemplate[type] === true) {
  544.                 // if there is no markup, we just append close button element inside
  545.                 if(!mfp.content.find('.mfp-close').length) {
  546.                     mfp.content.append(_getCloseBtn());
  547.                 }
  548.             } else {
  549.                 mfp.content = newContent;
  550.             }
  551.         } else {
  552.             mfp.content = '';
  553.         }
  554.  
  555.         _mfpTrigger(BEFORE_APPEND_EVENT);
  556.         mfp.container.addClass('mfp-'+type+'-holder');
  557.  
  558.         mfp.contentContainer.append(mfp.content);
  559.     },
  560.  
  561.  
  562.     /**
  563.      * Creates Magnific Popup data object based on given data
  564.      * @param  {int} index Index of item to parse
  565.      */
  566.     parseEl: function(index) {
  567.         var item = mfp.items[index],
  568.             type;
  569.  
  570.         if(item.tagName) {
  571.             item = { el: $(item) };
  572.         } else {
  573.             type = item.type;
  574.             item = { data: item, src: item.src };
  575.         }
  576.  
  577.         if(item.el) {
  578.             var types = mfp.types;
  579.  
  580.             // check for 'mfp-TYPE' class
  581.             for(var i = 0; i < types.length; i++) {
  582.                 if( item.el.hasClass('mfp-'+types[i]) ) {
  583.                     type = types[i];
  584.                     break;
  585.                 }
  586.             }
  587.  
  588.             item.src = item.el.attr('data-mfp-src');
  589.             if(!item.src) {
  590.                 item.src = item.el.attr('href');
  591.             }
  592.         }
  593.  
  594.         item.type = type || mfp.st.type || 'inline';
  595.         item.index = index;
  596.         item.parsed = true;
  597.         mfp.items[index] = item;
  598.         _mfpTrigger('ElementParse', item);
  599.  
  600.         return mfp.items[index];
  601.     },
  602.  
  603.  
  604.     /**
  605.      * Initializes single popup or a group of popups
  606.      */
  607.     addGroup: function(el, options) {
  608.         var eHandler = function(e) {
  609.             e.mfpEl = this;
  610.             mfp._openClick(e, el, options);
  611.         };
  612.  
  613.         if(!options) {
  614.             options = {};
  615.         }
  616.  
  617.         var eName = 'click.magnificPopup';
  618.         options.mainEl = el;
  619.  
  620.         if(options.items) {
  621.             options.isObj = true;
  622.             el.off(eName).on(eName, eHandler);
  623.         } else {
  624.             options.isObj = false;
  625.             if(options.delegate) {
  626.                 el.off(eName).on(eName, options.delegate , eHandler);
  627.             } else {
  628.                 options.items = el;
  629.                 el.off(eName).on(eName, eHandler);
  630.             }
  631.         }
  632.     },
  633.     _openClick: function(e, el, options) {
  634.         var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;
  635.  
  636.  
  637.         if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {
  638.             return;
  639.         }
  640.  
  641.         var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;
  642.  
  643.         if(disableOn) {
  644.             if('function' === typeof disableOn) {
  645.                 if( !disableOn.call(mfp) ) {
  646.                     return true;
  647.                 }
  648.             } else { // else it's number
  649.                 if( _window.width() < disableOn ) {
  650.                     return true;
  651.                 }
  652.             }
  653.         }
  654.  
  655.         if(e.type) {
  656.             e.preventDefault();
  657.  
  658.             // This will prevent popup from closing if element is inside and popup is already opened
  659.             if(mfp.isOpen) {
  660.                 e.stopPropagation();
  661.             }
  662.         }
  663.  
  664.         options.el = $(e.mfpEl);
  665.         if(options.delegate) {
  666.             options.items = el.find(options.delegate);
  667.         }
  668.         mfp.open(options);
  669.     },
  670.  
  671.  
  672.     /**
  673.      * Updates text on preloader
  674.      */
  675.     updateStatus: function(status, text) {
  676.  
  677.         if(mfp.preloader) {
  678.             if(_prevStatus !== status) {
  679.                 mfp.container.removeClass('mfp-s-'+_prevStatus);
  680.             }
  681.  
  682.             if(!text && status === 'loading') {
  683.                 text = mfp.st.tLoading;
  684.             }
  685.  
  686.             var data = {
  687.                 status: status,
  688.                 text: text
  689.             };
  690.             // allows to modify status
  691.             _mfpTrigger('UpdateStatus', data);
  692.  
  693.             status = data.status;
  694.             text = data.text;
  695.  
  696.             mfp.preloader.html(text);
  697.  
  698.             mfp.preloader.find('a').on('click', function(e) {
  699.                 e.stopImmediatePropagation();
  700.             });
  701.  
  702.             mfp.container.addClass('mfp-s-'+status);
  703.             _prevStatus = status;
  704.         }
  705.     },
  706.  
  707.  
  708.     /*
  709.         "Private" helpers that aren't private at all
  710.      */
  711.     // Check to close popup or not
  712.     // "target" is an element that was clicked
  713.     _checkIfClose: function(target) {
  714.  
  715.         if($(target).hasClass(PREVENT_CLOSE_CLASS)) {
  716.             return;
  717.         }
  718.  
  719.         var closeOnContent = mfp.st.closeOnContentClick;
  720.         var closeOnBg = mfp.st.closeOnBgClick;
  721.  
  722.         if(closeOnContent && closeOnBg) {
  723.             return true;
  724.         } else {
  725.  
  726.             // We close the popup if click is on close button or on preloader. Or if there is no content.
  727.             if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {
  728.                 return true;
  729.             }
  730.  
  731.             // if click is outside the content
  732.             if(  (target !== mfp.content[0] && !$.contains(mfp.content[0], target))  ) {
  733.                 if(closeOnBg) {
  734.                     // last check, if the clicked element is in DOM, (in case it's removed onclick)
  735.                     if( $.contains(document, target) ) {
  736.                         return true;
  737.                     }
  738.                 }
  739.             } else if(closeOnContent) {
  740.                 return true;
  741.             }
  742.  
  743.         }
  744.         return false;
  745.     },
  746.     _addClassToMFP: function(cName) {
  747.         mfp.bgOverlay.addClass(cName);
  748.         mfp.wrap.addClass(cName);
  749.     },
  750.     _removeClassFromMFP: function(cName) {
  751.         this.bgOverlay.removeClass(cName);
  752.         mfp.wrap.removeClass(cName);
  753.     },
  754.     _hasScrollBar: function(winHeight) {
  755.         return (  (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );
  756.     },
  757.     _setFocus: function() {
  758.         (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
  759.     },
  760.     _onFocusIn: function(e) {
  761.         if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
  762.             mfp._setFocus();
  763.             return false;
  764.         }
  765.     },
  766.     _parseMarkup: function(template, values, item) {
  767.         var arr;
  768.         if(item.data) {
  769.             values = $.extend(item.data, values);
  770.         }
  771.         _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
  772.  
  773.         $.each(values, function(key, value) {
  774.             if(value === undefined || value === false) {
  775.                 return true;
  776.             }
  777.             arr = key.split('_');
  778.             if(arr.length > 1) {
  779.                 var el = template.find(EVENT_NS + '-'+arr[0]);
  780.  
  781.                 if(el.length > 0) {
  782.                     var attr = arr[1];
  783.                     if(attr === 'replaceWith') {
  784.                         if(el[0] !== value[0]) {
  785.                             el.replaceWith(value);
  786.                         }
  787.                     } else if(attr === 'img') {
  788.                         if(el.is('img')) {
  789.                             el.attr('src', value);
  790.                         } else {
  791.                             el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) );
  792.                         }
  793.                     } else {
  794.                         el.attr(arr[1], value);
  795.                     }
  796.                 }
  797.  
  798.             } else {
  799.                 template.find(EVENT_NS + '-'+key).html(value);
  800.             }
  801.         });
  802.     },
  803.  
  804.     _getScrollbarSize: function() {
  805.         // thx David
  806.         if(mfp.scrollbarSize === undefined) {
  807.             var scrollDiv = document.createElement("div");
  808.             scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
  809.             document.body.appendChild(scrollDiv);
  810.             mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
  811.             document.body.removeChild(scrollDiv);
  812.         }
  813.         return mfp.scrollbarSize;
  814.     }
  815.  
  816. }; /* MagnificPopup core prototype end */
  817.  
  818.  
  819.  
  820.  
  821. /**
  822.  * Public static functions
  823.  */
  824. $.magnificPopup = {
  825.     instance: null,
  826.     proto: MagnificPopup.prototype,
  827.     modules: [],
  828.  
  829.     open: function(options, index) {
  830.         _checkInstance();
  831.  
  832.         if(!options) {
  833.             options = {};
  834.         } else {
  835.             options = $.extend(true, {}, options);
  836.         }
  837.  
  838.         options.isObj = true;
  839.         options.index = index || 0;
  840.         return this.instance.open(options);
  841.     },
  842.  
  843.     close: function() {
  844.         return $.magnificPopup.instance && $.magnificPopup.instance.close();
  845.     },
  846.  
  847.     registerModule: function(name, module) {
  848.         if(module.options) {
  849.             $.magnificPopup.defaults[name] = module.options;
  850.         }
  851.         $.extend(this.proto, module.proto);
  852.         this.modules.push(name);
  853.     },
  854.  
  855.     defaults: {
  856.  
  857.         // Info about options is in docs:
  858.         // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
  859.  
  860.         disableOn: 0,
  861.  
  862.         key: null,
  863.  
  864.         midClick: false,
  865.  
  866.         mainClass: '',
  867.  
  868.         preloader: true,
  869.  
  870.         focus: '', // CSS selector of input to focus after popup is opened
  871.  
  872.         closeOnContentClick: false,
  873.  
  874.         closeOnBgClick: true,
  875.  
  876.         closeBtnInside: true,
  877.  
  878.         showCloseBtn: true,
  879.  
  880.         enableEscapeKey: true,
  881.  
  882.         modal: false,
  883.  
  884.         alignTop: false,
  885.  
  886.         removalDelay: 0,
  887.  
  888.         prependTo: null,
  889.  
  890.         fixedContentPos: 'auto',
  891.  
  892.         fixedBgPos: 'auto',
  893.  
  894.         overflowY: 'auto',
  895.  
  896.         closeMarkup: '<button title="%title%" type="button" class="mfp-close">&#215;</button>',
  897.  
  898.         tClose: 'Close (Esc)',
  899.  
  900.         tLoading: 'Loading...',
  901.  
  902.         autoFocusLast: true
  903.  
  904.     }
  905. };
  906.  
  907.  
  908.  
  909. $.fn.magnificPopup = function(options) {
  910.     _checkInstance();
  911.  
  912.     var jqEl = $(this);
  913.  
  914.     // We call some API method of first param is a string
  915.     if (typeof options === "string" ) {
  916.  
  917.         if(options === 'open') {
  918.             var items,
  919.                 itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,
  920.                 index = parseInt(arguments[1], 10) || 0;
  921.  
  922.             if(itemOpts.items) {
  923.                 items = itemOpts.items[index];
  924.             } else {
  925.                 items = jqEl;
  926.                 if(itemOpts.delegate) {
  927.                     items = items.find(itemOpts.delegate);
  928.                 }
  929.                 items = items.eq( index );
  930.             }
  931.             mfp._openClick({mfpEl:items}, jqEl, itemOpts);
  932.         } else {
  933.             if(mfp.isOpen)
  934.                 mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
  935.         }
  936.  
  937.     } else {
  938.         // clone options obj
  939.         options = $.extend(true, {}, options);
  940.  
  941.         /*
  942.          * As Zepto doesn't support .data() method for objects
  943.          * and it works only in normal browsers
  944.          * we assign "options" object directly to the DOM element. FTW!
  945.          */
  946.         if(_isJQ) {
  947.             jqEl.data('magnificPopup', options);
  948.         } else {
  949.             jqEl[0].magnificPopup = options;
  950.         }
  951.  
  952.         mfp.addGroup(jqEl, options);
  953.  
  954.     }
  955.     return jqEl;
  956. };
  957.  
  958. /*>>core*/
  959.  
  960. /*>>inline*/
  961.  
  962. var INLINE_NS = 'inline',
  963.     _hiddenClass,
  964.     _inlinePlaceholder,
  965.     _lastInlineElement,
  966.     _putInlineElementsBack = function() {
  967.         if(_lastInlineElement) {
  968.             _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();
  969.             _lastInlineElement = null;
  970.         }
  971.     };
  972.  
  973. $.magnificPopup.registerModule(INLINE_NS, {
  974.     options: {
  975.         hiddenClass: 'hide', // will be appended with `mfp-` prefix
  976.         markup: '',
  977.         tNotFound: 'Content not found'
  978.     },
  979.     proto: {
  980.  
  981.         initInline: function() {
  982.             mfp.types.push(INLINE_NS);
  983.  
  984.             _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
  985.                 _putInlineElementsBack();
  986.             });
  987.         },
  988.  
  989.         getInline: function(item, template) {
  990.  
  991.             _putInlineElementsBack();
  992.  
  993.             if(item.src) {
  994.                 var inlineSt = mfp.st.inline,
  995.                     el = $(item.src);
  996.  
  997.                 if(el.length) {
  998.  
  999.                     // If target element has parent - we replace it with placeholder and put it back after popup is closed
  1000.                     var parent = el[0].parentNode;
  1001.                     if(parent && parent.tagName) {
  1002.                         if(!_inlinePlaceholder) {
  1003.                             _hiddenClass = inlineSt.hiddenClass;
  1004.                             _inlinePlaceholder = _getEl(_hiddenClass);
  1005.                             _hiddenClass = 'mfp-'+_hiddenClass;
  1006.                         }
  1007.                         // replace target inline element with placeholder
  1008.                         _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
  1009.                     }
  1010.  
  1011.                     mfp.updateStatus('ready');
  1012.                 } else {
  1013.                     mfp.updateStatus('error', inlineSt.tNotFound);
  1014.                     el = $('<div>');
  1015.                 }
  1016.  
  1017.                 item.inlineElement = el;
  1018.                 return el;
  1019.             }
  1020.  
  1021.             mfp.updateStatus('ready');
  1022.             mfp._parseMarkup(template, {}, item);
  1023.             return template;
  1024.         }
  1025.     }
  1026. });
  1027.  
  1028. /*>>inline*/
  1029.  
  1030. /*>>ajax*/
  1031. var AJAX_NS = 'ajax',
  1032.     _ajaxCur,
  1033.     _removeAjaxCursor = function() {
  1034.         if(_ajaxCur) {
  1035.             $(document.body).removeClass(_ajaxCur);
  1036.         }
  1037.     },
  1038.     _destroyAjaxRequest = function() {
  1039.         _removeAjaxCursor();
  1040.         if(mfp.req) {
  1041.             mfp.req.abort();
  1042.         }
  1043.     };
  1044.  
  1045. $.magnificPopup.registerModule(AJAX_NS, {
  1046.  
  1047.     options: {
  1048.         settings: null,
  1049.         cursor: 'mfp-ajax-cur',
  1050.         tError: '<a href="%url%">The content</a> could not be loaded.'
  1051.     },
  1052.  
  1053.     proto: {
  1054.         initAjax: function() {
  1055.             mfp.types.push(AJAX_NS);
  1056.             _ajaxCur = mfp.st.ajax.cursor;
  1057.  
  1058.             _mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);
  1059.             _mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);
  1060.         },
  1061.         getAjax: function(item) {
  1062.  
  1063.             if(_ajaxCur) {
  1064.                 $(document.body).addClass(_ajaxCur);
  1065.             }
  1066.  
  1067.             mfp.updateStatus('loading');
  1068.  
  1069.             var opts = $.extend({
  1070.                 url: item.src,
  1071.                 success: function(data, textStatus, jqXHR) {
  1072.                     var temp = {
  1073.                         data:data,
  1074.                         xhr:jqXHR
  1075.                     };
  1076.  
  1077.                     _mfpTrigger('ParseAjax', temp);
  1078.  
  1079.                     mfp.appendContent( $(temp.data), AJAX_NS );
  1080.  
  1081.                     item.finished = true;
  1082.  
  1083.                     _removeAjaxCursor();
  1084.  
  1085.                     mfp._setFocus();
  1086.  
  1087.                     setTimeout(function() {
  1088.                         mfp.wrap.addClass(READY_CLASS);
  1089.                     }, 16);
  1090.  
  1091.                     mfp.updateStatus('ready');
  1092.  
  1093.                     _mfpTrigger('AjaxContentAdded');
  1094.                 },
  1095.                 error: function() {
  1096.                     _removeAjaxCursor();
  1097.                     item.finished = item.loadError = true;
  1098.                     mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));
  1099.                 }
  1100.             }, mfp.st.ajax.settings);
  1101.  
  1102.             mfp.req = $.ajax(opts);
  1103.  
  1104.             return '';
  1105.         }
  1106.     }
  1107. });
  1108.  
  1109. /*>>ajax*/
  1110.  
  1111. /*>>image*/
  1112. var _imgInterval,
  1113.     _getTitle = function(item) {
  1114.         if(item.data && item.data.title !== undefined)
  1115.             return item.data.title;
  1116.  
  1117.         var src = mfp.st.image.titleSrc;
  1118.  
  1119.         if(src) {
  1120.             if('function' === typeof src) {
  1121.                 return src.call(mfp, item);
  1122.             } else if(item.el) {
  1123.                 return item.el.attr(src) || '';
  1124.             }
  1125.         }
  1126.         return '';
  1127.     };
  1128.  
  1129. $.magnificPopup.registerModule('image', {
  1130.  
  1131.     options: {
  1132.         markup: '<div class="mfp-figure">'+
  1133.                     '<div class="mfp-close"></div>'+
  1134.                     '<figure>'+
  1135.                         '<div class="mfp-img"></div>'+
  1136.                         '<figcaption>'+
  1137.                             '<div class="mfp-bottom-bar">'+
  1138.                                 '<div class="mfp-title"></div>'+
  1139.                                 '<div class="mfp-counter"></div>'+
  1140.                             '</div>'+
  1141.                         '</figcaption>'+
  1142.                     '</figure>'+
  1143.                 '</div>',
  1144.         cursor: 'mfp-zoom-out-cur',
  1145.         titleSrc: 'title',
  1146.         verticalFit: true,
  1147.         tError: '<a href="%url%">The image</a> could not be loaded.'
  1148.     },
  1149.  
  1150.     proto: {
  1151.         initImage: function() {
  1152.             var imgSt = mfp.st.image,
  1153.                 ns = '.image';
  1154.  
  1155.             mfp.types.push('image');
  1156.  
  1157.             _mfpOn(OPEN_EVENT+ns, function() {
  1158.                 if(mfp.currItem.type === 'image' && imgSt.cursor) {
  1159.                     $(document.body).addClass(imgSt.cursor);
  1160.                 }
  1161.             });
  1162.  
  1163.             _mfpOn(CLOSE_EVENT+ns, function() {
  1164.                 if(imgSt.cursor) {
  1165.                     $(document.body).removeClass(imgSt.cursor);
  1166.                 }
  1167.                 _window.off('resize' + EVENT_NS);
  1168.             });
  1169.  
  1170.             _mfpOn('Resize'+ns, mfp.resizeImage);
  1171.             if(mfp.isLowIE) {
  1172.                 _mfpOn('AfterChange', mfp.resizeImage);
  1173.             }
  1174.         },
  1175.         resizeImage: function() {
  1176.             var item = mfp.currItem;
  1177.             if(!item || !item.img) return;
  1178.  
  1179.             if(mfp.st.image.verticalFit) {
  1180.                 var decr = 0;
  1181.                 // fix box-sizing in ie7/8
  1182.                 if(mfp.isLowIE) {
  1183.                     decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);
  1184.                 }
  1185.                 item.img.css('max-height', mfp.wH-decr);
  1186.             }
  1187.         },
  1188.         _onImageHasSize: function(item) {
  1189.             if(item.img) {
  1190.  
  1191.                 item.hasSize = true;
  1192.  
  1193.                 if(_imgInterval) {
  1194.                     clearInterval(_imgInterval);
  1195.                 }
  1196.  
  1197.                 item.isCheckingImgSize = false;
  1198.  
  1199.                 _mfpTrigger('ImageHasSize', item);
  1200.  
  1201.                 if(item.imgHidden) {
  1202.                     if(mfp.content)
  1203.                         mfp.content.removeClass('mfp-loading');
  1204.  
  1205.                     item.imgHidden = false;
  1206.                 }
  1207.  
  1208.             }
  1209.         },
  1210.  
  1211.         /**
  1212.          * Function that loops until the image has size to display elements that rely on it asap
  1213.          */
  1214.         findImageSize: function(item) {
  1215.  
  1216.             var counter = 0,
  1217.                 img = item.img[0],
  1218.                 mfpSetInterval = function(delay) {
  1219.  
  1220.                     if(_imgInterval) {
  1221.                         clearInterval(_imgInterval);
  1222.                     }
  1223.                     // decelerating interval that checks for size of an image
  1224.                     _imgInterval = setInterval(function() {
  1225.                         if(img.naturalWidth > 0) {
  1226.                             mfp._onImageHasSize(item);
  1227.                             return;
  1228.                         }
  1229.  
  1230.                         if(counter > 200) {
  1231.                             clearInterval(_imgInterval);
  1232.                         }
  1233.  
  1234.                         counter++;
  1235.                         if(counter === 3) {
  1236.                             mfpSetInterval(10);
  1237.                         } else if(counter === 40) {
  1238.                             mfpSetInterval(50);
  1239.                         } else if(counter === 100) {
  1240.                             mfpSetInterval(500);
  1241.                         }
  1242.                     }, delay);
  1243.                 };
  1244.  
  1245.             mfpSetInterval(1);
  1246.         },
  1247.  
  1248.         getImage: function(item, template) {
  1249.  
  1250.             var guard = 0,
  1251.  
  1252.                 // image load complete handler
  1253.                 onLoadComplete = function() {
  1254.                     if(item) {
  1255.                         if (item.img[0].complete) {
  1256.                             item.img.off('.mfploader');
  1257.  
  1258.                             if(item === mfp.currItem){
  1259.                                 mfp._onImageHasSize(item);
  1260.  
  1261.                                 mfp.updateStatus('ready');
  1262.                             }
  1263.  
  1264.                             item.hasSize = true;
  1265.                             item.loaded = true;
  1266.  
  1267.                             _mfpTrigger('ImageLoadComplete');
  1268.  
  1269.                         }
  1270.                         else {
  1271.                             // if image complete check fails 200 times (20 sec), we assume that there was an error.
  1272.                             guard++;
  1273.                             if(guard < 200) {
  1274.                                 setTimeout(onLoadComplete,100);
  1275.                             } else {
  1276.                                 onLoadError();
  1277.                             }
  1278.                         }
  1279.                     }
  1280.                 },
  1281.  
  1282.                 // image error handler
  1283.                 onLoadError = function() {
  1284.                     if(item) {
  1285.                         item.img.off('.mfploader');
  1286.                         if(item === mfp.currItem){
  1287.                             mfp._onImageHasSize(item);
  1288.                             mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
  1289.                         }
  1290.  
  1291.                         item.hasSize = true;
  1292.                         item.loaded = true;
  1293.                         item.loadError = true;
  1294.                     }
  1295.                 },
  1296.                 imgSt = mfp.st.image;
  1297.  
  1298.  
  1299.             var el = template.find('.mfp-img');
  1300.             if(el.length) {
  1301.                 var img = document.createElement('img');
  1302.                 img.className = 'mfp-img';
  1303.                 if(item.el && item.el.find('img').length) {
  1304.                     img.alt = item.el.find('img').attr('alt');
  1305.                     img.srcset = item.el.find('img').attr('srcset');
  1306.                 }
  1307.                 item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
  1308.                 img.src = item.src;
  1309.  
  1310.                 // without clone() "error" event is not firing when IMG is replaced by new IMG
  1311.                 // TODO: find a way to avoid such cloning
  1312.                 if(el.is('img')) {
  1313.                     item.img = item.img.clone();
  1314.                 }
  1315.  
  1316.                 img = item.img[0];
  1317.                 if(img.naturalWidth > 0) {
  1318.                     item.hasSize = true;
  1319.                 } else if(!img.width) {
  1320.                     item.hasSize = false;
  1321.                 }
  1322.             }
  1323.  
  1324.             mfp._parseMarkup(template, {
  1325.                 title: _getTitle(item),
  1326.                 img_replaceWith: item.img
  1327.             }, item);
  1328.  
  1329.             mfp.resizeImage();
  1330.  
  1331.             if(item.hasSize) {
  1332.                 if(_imgInterval) clearInterval(_imgInterval);
  1333.  
  1334.                 if(item.loadError) {
  1335.                     template.addClass('mfp-loading');
  1336.                     mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
  1337.                 } else {
  1338.                     template.removeClass('mfp-loading');
  1339.                     mfp.updateStatus('ready');
  1340.                 }
  1341.                 return template;
  1342.             }
  1343.  
  1344.             mfp.updateStatus('loading');
  1345.             item.loading = true;
  1346.  
  1347.             if(!item.hasSize) {
  1348.                 item.imgHidden = true;
  1349.                 template.addClass('mfp-loading');
  1350.                 mfp.findImageSize(item);
  1351.             }
  1352.  
  1353.             return template;
  1354.         }
  1355.     }
  1356. });
  1357.  
  1358. /*>>image*/
  1359.  
  1360. /*>>zoom*/
  1361. var hasMozTransform,
  1362.     getHasMozTransform = function() {
  1363.         if(hasMozTransform === undefined) {
  1364.             hasMozTransform = document.createElement('p').style.MozTransform !== undefined;
  1365.         }
  1366.         return hasMozTransform;
  1367.     };
  1368.  
  1369. $.magnificPopup.registerModule('zoom', {
  1370.  
  1371.     options: {
  1372.         enabled: false,
  1373.         easing: 'ease-in-out',
  1374.         duration: 300,
  1375.         opener: function(element) {
  1376.             return element.is('img') ? element : element.find('img');
  1377.         }
  1378.     },
  1379.  
  1380.     proto: {
  1381.  
  1382.         initZoom: function() {
  1383.             var zoomSt = mfp.st.zoom,
  1384.                 ns = '.zoom',
  1385.                 image;
  1386.  
  1387.             if(!zoomSt.enabled || !mfp.supportsTransition) {
  1388.                 return;
  1389.             }
  1390.  
  1391.             var duration = zoomSt.duration,
  1392.                 getElToAnimate = function(image) {
  1393.                     var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
  1394.                         transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,
  1395.                         cssObj = {
  1396.                             position: 'fixed',
  1397.                             zIndex: 9999,
  1398.                             left: 0,
  1399.                             top: 0,
  1400.                             '-webkit-backface-visibility': 'hidden'
  1401.                         },
  1402.                         t = 'transition';
  1403.  
  1404.                     cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;
  1405.  
  1406.                     newImg.css(cssObj);
  1407.                     return newImg;
  1408.                 },
  1409.                 showMainContent = function() {
  1410.                     mfp.content.css('visibility', 'visible');
  1411.                 },
  1412.                 openTimeout,
  1413.                 animatedImg;
  1414.  
  1415.             _mfpOn('BuildControls'+ns, function() {
  1416.                 if(mfp._allowZoom()) {
  1417.  
  1418.                     clearTimeout(openTimeout);
  1419.                     mfp.content.css('visibility', 'hidden');
  1420.  
  1421.                     // Basically, all code below does is clones existing image, puts in on top of the current one and animated it
  1422.  
  1423.                     image = mfp._getItemToZoom();
  1424.  
  1425.                     if(!image) {
  1426.                         showMainContent();
  1427.                         return;
  1428.                     }
  1429.  
  1430.                     animatedImg = getElToAnimate(image);
  1431.  
  1432.                     animatedImg.css( mfp._getOffset() );
  1433.  
  1434.                     mfp.wrap.append(animatedImg);
  1435.  
  1436.                     openTimeout = setTimeout(function() {
  1437.                         animatedImg.css( mfp._getOffset( true ) );
  1438.                         openTimeout = setTimeout(function() {
  1439.  
  1440.                             showMainContent();
  1441.  
  1442.                             setTimeout(function() {
  1443.                                 animatedImg.remove();
  1444.                                 image = animatedImg = null;
  1445.                                 _mfpTrigger('ZoomAnimationEnded');
  1446.                             }, 16); // avoid blink when switching images
  1447.  
  1448.                         }, duration); // this timeout equals animation duration
  1449.  
  1450.                     }, 16); // by adding this timeout we avoid short glitch at the beginning of animation
  1451.  
  1452.  
  1453.                     // Lots of timeouts...
  1454.                 }
  1455.             });
  1456.             _mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
  1457.                 if(mfp._allowZoom()) {
  1458.  
  1459.                     clearTimeout(openTimeout);
  1460.  
  1461.                     mfp.st.removalDelay = duration;
  1462.  
  1463.                     if(!image) {
  1464.                         image = mfp._getItemToZoom();
  1465.                         if(!image) {
  1466.                             return;
  1467.                         }
  1468.                         animatedImg = getElToAnimate(image);
  1469.                     }
  1470.  
  1471.                     animatedImg.css( mfp._getOffset(true) );
  1472.                     mfp.wrap.append(animatedImg);
  1473.                     mfp.content.css('visibility', 'hidden');
  1474.  
  1475.                     setTimeout(function() {
  1476.                         animatedImg.css( mfp._getOffset() );
  1477.                     }, 16);
  1478.                 }
  1479.  
  1480.             });
  1481.  
  1482.             _mfpOn(CLOSE_EVENT+ns, function() {
  1483.                 if(mfp._allowZoom()) {
  1484.                     showMainContent();
  1485.                     if(animatedImg) {
  1486.                         animatedImg.remove();
  1487.                     }
  1488.                     image = null;
  1489.                 }
  1490.             });
  1491.         },
  1492.  
  1493.         _allowZoom: function() {
  1494.             return mfp.currItem.type === 'image';
  1495.         },
  1496.  
  1497.         _getItemToZoom: function() {
  1498.             if(mfp.currItem.hasSize) {
  1499.                 return mfp.currItem.img;
  1500.             } else {
  1501.                 return false;
  1502.             }
  1503.         },
  1504.  
  1505.         // Get element postion relative to viewport
  1506.         _getOffset: function(isLarge) {
  1507.             var el;
  1508.             if(isLarge) {
  1509.                 el = mfp.currItem.img;
  1510.             } else {
  1511.                 el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
  1512.             }
  1513.  
  1514.             var offset = el.offset();
  1515.             var paddingTop = parseInt(el.css('padding-top'),10);
  1516.             var paddingBottom = parseInt(el.css('padding-bottom'),10);
  1517.             offset.top -= ( $(window).scrollTop() - paddingTop );
  1518.  
  1519.  
  1520.             /*
  1521.  
  1522.             Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.
  1523.  
  1524.              */
  1525.             var obj = {
  1526.                 width: el.width(),
  1527.                 // fix Zepto height+padding issue
  1528.                 height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop
  1529.             };
  1530.  
  1531.             // I hate to do this, but there is no another option
  1532.             if( getHasMozTransform() ) {
  1533.                 obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';
  1534.             } else {
  1535.                 obj.left = offset.left;
  1536.                 obj.top = offset.top;
  1537.             }
  1538.             return obj;
  1539.         }
  1540.  
  1541.     }
  1542. });
  1543.  
  1544.  
  1545.  
  1546. /*>>zoom*/
  1547.  
  1548. /*>>iframe*/
  1549.  
  1550. var IFRAME_NS = 'iframe',
  1551.     _emptyPage = '//about:blank',
  1552.  
  1553.     _fixIframeBugs = function(isShowing) {
  1554.         if(mfp.currTemplate[IFRAME_NS]) {
  1555.             var el = mfp.currTemplate[IFRAME_NS].find('iframe');
  1556.             if(el.length) {
  1557.                 // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug
  1558.                 if(!isShowing) {
  1559.                     el[0].src = _emptyPage;
  1560.                 }
  1561.  
  1562.                 // IE8 black screen bug fix
  1563.                 if(mfp.isIE8) {
  1564.                     el.css('display', isShowing ? 'block' : 'none');
  1565.                 }
  1566.             }
  1567.         }
  1568.     };
  1569.  
  1570. $.magnificPopup.registerModule(IFRAME_NS, {
  1571.  
  1572.     options: {
  1573.         markup: '<div class="mfp-iframe-scaler">'+
  1574.                     '<div class="mfp-close"></div>'+
  1575.                     '<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+
  1576.                 '</div>',
  1577.  
  1578.         srcAction: 'iframe_src',
  1579.  
  1580.         // we don't care and support only one default type of URL by default
  1581.         patterns: {
  1582.             youtube: {
  1583.                 index: 'youtube.com',
  1584.                 id: 'v=',
  1585.                 src: '//www.youtube.com/embed/%id%?autoplay=1'
  1586.             },
  1587.             vimeo: {
  1588.                 index: 'vimeo.com/',
  1589.                 id: '/',
  1590.                 src: '//player.vimeo.com/video/%id%?autoplay=1'
  1591.             },
  1592.             gmaps: {
  1593.                 index: '//maps.google.',
  1594.                 src: '%id%&output=embed'
  1595.             }
  1596.         }
  1597.     },
  1598.  
  1599.     proto: {
  1600.         initIframe: function() {
  1601.             mfp.types.push(IFRAME_NS);
  1602.  
  1603.             _mfpOn('BeforeChange', function(e, prevType, newType) {
  1604.                 if(prevType !== newType) {
  1605.                     if(prevType === IFRAME_NS) {
  1606.                         _fixIframeBugs(); // iframe if removed
  1607.                     } else if(newType === IFRAME_NS) {
  1608.                         _fixIframeBugs(true); // iframe is showing
  1609.                     }
  1610.                 }// else {
  1611.                     // iframe source is switched, don't do anything
  1612.                 //}
  1613.             });
  1614.  
  1615.             _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
  1616.                 _fixIframeBugs();
  1617.             });
  1618.         },
  1619.  
  1620.         getIframe: function(item, template) {
  1621.             var embedSrc = item.src;
  1622.             var iframeSt = mfp.st.iframe;
  1623.  
  1624.             $.each(iframeSt.patterns, function() {
  1625.                 if(embedSrc.indexOf( this.index ) > -1) {
  1626.                     if(this.id) {
  1627.                         if(typeof this.id === 'string') {
  1628.                             embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);
  1629.                         } else {
  1630.                             embedSrc = this.id.call( this, embedSrc );
  1631.                         }
  1632.                     }
  1633.                     embedSrc = this.src.replace('%id%', embedSrc );
  1634.                     return false; // break;
  1635.                 }
  1636.             });
  1637.  
  1638.             var dataObj = {};
  1639.             if(iframeSt.srcAction) {
  1640.                 dataObj[iframeSt.srcAction] = embedSrc;
  1641.             }
  1642.             mfp._parseMarkup(template, dataObj, item);
  1643.  
  1644.             mfp.updateStatus('ready');
  1645.  
  1646.             return template;
  1647.         }
  1648.     }
  1649. });
  1650.  
  1651.  
  1652.  
  1653. /*>>iframe*/
  1654.  
  1655. /*>>gallery*/
  1656. /**
  1657.  * Get looped index depending on number of slides
  1658.  */
  1659. var _getLoopedId = function(index) {
  1660.         var numSlides = mfp.items.length;
  1661.         if(index > numSlides - 1) {
  1662.             return index - numSlides;
  1663.         } else  if(index < 0) {
  1664.             return numSlides + index;
  1665.         }
  1666.         return index;
  1667.     },
  1668.     _replaceCurrTotal = function(text, curr, total) {
  1669.         return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
  1670.     };
  1671.  
  1672. $.magnificPopup.registerModule('gallery', {
  1673.  
  1674.     options: {
  1675.         enabled: false,
  1676.         arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',
  1677.         preload: [0,2],
  1678.         navigateByImgClick: true,
  1679.         arrows: true,
  1680.  
  1681.         tPrev: 'Previous (Left arrow key)',
  1682.         tNext: 'Next (Right arrow key)',
  1683.         tCounter: '%curr% of %total%'
  1684.     },
  1685.  
  1686.     proto: {
  1687.         initGallery: function() {
  1688.  
  1689.             var gSt = mfp.st.gallery,
  1690.                 ns = '.mfp-gallery';
  1691.  
  1692.             mfp.direction = true; // true - next, false - prev
  1693.  
  1694.             if(!gSt || !gSt.enabled ) return false;
  1695.  
  1696.             _wrapClasses += ' mfp-gallery';
  1697.  
  1698.             _mfpOn(OPEN_EVENT+ns, function() {
  1699.  
  1700.                 if(gSt.navigateByImgClick) {
  1701.                     mfp.wrap.on('click'+ns, '.mfp-img', function() {
  1702.                         if(mfp.items.length > 1) {
  1703.                             mfp.next();
  1704.                             return false;
  1705.                         }
  1706.                     });
  1707.                 }
  1708.  
  1709.                 _document.on('keydown'+ns, function(e) {
  1710.                     if (e.keyCode === 37) {
  1711.                         mfp.prev();
  1712.                     } else if (e.keyCode === 39) {
  1713.                         mfp.next();
  1714.                     }
  1715.                 });
  1716.             });
  1717.  
  1718.             _mfpOn('UpdateStatus'+ns, function(e, data) {
  1719.                 if(data.text) {
  1720.                     data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);
  1721.                 }
  1722.             });
  1723.  
  1724.             _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
  1725.                 var l = mfp.items.length;
  1726.                 values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';
  1727.             });
  1728.  
  1729.             _mfpOn('BuildControls' + ns, function() {
  1730.                 if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {
  1731.                     var markup = gSt.arrowMarkup,
  1732.                         arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),
  1733.                         arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);
  1734.  
  1735.                     arrowLeft.on('click', function() {
  1736.                         mfp.prev();
  1737.                     });
  1738.                     arrowRight.on('click', function() {
  1739.                         mfp.next();
  1740.                     });
  1741.  
  1742.                     mfp.container.append(arrowLeft.add(arrowRight));
  1743.                 }
  1744.             });
  1745.  
  1746.             _mfpOn(CHANGE_EVENT+ns, function() {
  1747.                 if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
  1748.  
  1749.                 mfp._preloadTimeout = setTimeout(function() {
  1750.                     mfp.preloadNearbyImages();
  1751.                     mfp._preloadTimeout = null;
  1752.                 }, 16);
  1753.             });
  1754.  
  1755.  
  1756.             _mfpOn(CLOSE_EVENT+ns, function() {
  1757.                 _document.off(ns);
  1758.                 mfp.wrap.off('click'+ns);
  1759.                 mfp.arrowRight = mfp.arrowLeft = null;
  1760.             });
  1761.  
  1762.         },
  1763.         next: function() {
  1764.             mfp.direction = true;
  1765.             mfp.index = _getLoopedId(mfp.index + 1);
  1766.             mfp.updateItemHTML();
  1767.         },
  1768.         prev: function() {
  1769.             mfp.direction = false;
  1770.             mfp.index = _getLoopedId(mfp.index - 1);
  1771.             mfp.updateItemHTML();
  1772.         },
  1773.         goTo: function(newIndex) {
  1774.             mfp.direction = (newIndex >= mfp.index);
  1775.             mfp.index = newIndex;
  1776.             mfp.updateItemHTML();
  1777.         },
  1778.         preloadNearbyImages: function() {
  1779.             var p = mfp.st.gallery.preload,
  1780.                 preloadBefore = Math.min(p[0], mfp.items.length),
  1781.                 preloadAfter = Math.min(p[1], mfp.items.length),
  1782.                 i;
  1783.  
  1784.             for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {
  1785.                 mfp._preloadItem(mfp.index+i);
  1786.             }
  1787.             for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {
  1788.                 mfp._preloadItem(mfp.index-i);
  1789.             }
  1790.         },
  1791.         _preloadItem: function(index) {
  1792.             index = _getLoopedId(index);
  1793.  
  1794.             if(mfp.items[index].preloaded) {
  1795.                 return;
  1796.             }
  1797.  
  1798.             var item = mfp.items[index];
  1799.             if(!item.parsed) {
  1800.                 item = mfp.parseEl( index );
  1801.             }
  1802.  
  1803.             _mfpTrigger('LazyLoad', item);
  1804.  
  1805.             if(item.type === 'image') {
  1806.                 item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {
  1807.                     item.hasSize = true;
  1808.                 }).on('error.mfploader', function() {
  1809.                     item.hasSize = true;
  1810.                     item.loadError = true;
  1811.                     _mfpTrigger('LazyLoadError', item);
  1812.                 }).attr('src', item.src);
  1813.             }
  1814.  
  1815.  
  1816.             item.preloaded = true;
  1817.         }
  1818.     }
  1819. });
  1820.  
  1821. /*>>gallery*/
  1822.  
  1823. /*>>retina*/
  1824.  
  1825. var RETINA_NS = 'retina';
  1826.  
  1827. $.magnificPopup.registerModule(RETINA_NS, {
  1828.     options: {
  1829.         replaceSrc: function(item) {
  1830.             return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });
  1831.         },
  1832.         ratio: 1 // Function or number.  Set to 1 to disable.
  1833.     },
  1834.     proto: {
  1835.         initRetina: function() {
  1836.             if(window.devicePixelRatio > 1) {
  1837.  
  1838.                 var st = mfp.st.retina,
  1839.                     ratio = st.ratio;
  1840.  
  1841.                 ratio = !isNaN(ratio) ? ratio : ratio();
  1842.  
  1843.                 if(ratio > 1) {
  1844.                     _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {
  1845.                         item.img.css({
  1846.                             'max-width': item.img[0].naturalWidth / ratio,
  1847.                             'width': '100%'
  1848.                         });
  1849.                     });
  1850.                     _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {
  1851.                         item.src = st.replaceSrc(item, ratio);
  1852.                     });
  1853.                 }
  1854.             }
  1855.  
  1856.         }
  1857.     }
  1858. });
  1859.  
  1860. /*>>retina*/
  1861.  _checkInstance(); }));
  1862.  
Add Comment
Please, Sign In to add comment