Advertisement
Guest User

magnific.js

a guest
Dec 31st, 2018
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*! Magnific Popup - v1.1.0 - 2016-02-20
  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, $.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 = $.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($.isFunction(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($.isFunction(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.                     }
  1306.                     item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
  1307.                     img.src = item.src;
  1308.  
  1309.                     // without clone() "error" event is not firing when IMG is replaced by new IMG
  1310.                     // TODO: find a way to avoid such cloning
  1311.                     if(el.is('img')) {
  1312.                         item.img = item.img.clone();
  1313.                     }
  1314.  
  1315.                     img = item.img[0];
  1316.                     if(img.naturalWidth > 0) {
  1317.                         item.hasSize = true;
  1318.                     } else if(!img.width) {
  1319.                         item.hasSize = false;
  1320.                     }
  1321.                 }
  1322.  
  1323.                 mfp._parseMarkup(template, {
  1324.                     title: _getTitle(item),
  1325.                     img_replaceWith: item.img
  1326.                 }, item);
  1327.  
  1328.                 mfp.resizeImage();
  1329.  
  1330.                 if(item.hasSize) {
  1331.                     if(_imgInterval) clearInterval(_imgInterval);
  1332.  
  1333.                     if(item.loadError) {
  1334.                         template.addClass('mfp-loading');
  1335.                         mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
  1336.                     } else {
  1337.                         template.removeClass('mfp-loading');
  1338.                         mfp.updateStatus('ready');
  1339.                     }
  1340.                     return template;
  1341.                 }
  1342.  
  1343.                 mfp.updateStatus('loading');
  1344.                 item.loading = true;
  1345.  
  1346.                 if(!item.hasSize) {
  1347.                     item.imgHidden = true;
  1348.                     template.addClass('mfp-loading');
  1349.                     mfp.findImageSize(item);
  1350.                 }
  1351.  
  1352.                 return template;
  1353.             }
  1354.         }
  1355.     });
  1356.  
  1357.     /*>>image*/
  1358.  
  1359.     /*>>zoom*/
  1360.     var hasMozTransform,
  1361.         getHasMozTransform = function() {
  1362.             if(hasMozTransform === undefined) {
  1363.                 hasMozTransform = document.createElement('p').style.MozTransform !== undefined;
  1364.             }
  1365.             return hasMozTransform;
  1366.         };
  1367.  
  1368.     $.magnificPopup.registerModule('zoom', {
  1369.  
  1370.         options: {
  1371.             enabled: false,
  1372.             easing: 'ease-in-out',
  1373.             duration: 300,
  1374.             opener: function(element) {
  1375.                 return element.is('img') ? element : element.find('img');
  1376.             }
  1377.         },
  1378.  
  1379.         proto: {
  1380.  
  1381.             initZoom: function() {
  1382.                 var zoomSt = mfp.st.zoom,
  1383.                     ns = '.zoom',
  1384.                     image;
  1385.  
  1386.                 if(!zoomSt.enabled || !mfp.supportsTransition) {
  1387.                     return;
  1388.                 }
  1389.  
  1390.                 var duration = zoomSt.duration,
  1391.                     getElToAnimate = function(image) {
  1392.                         var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
  1393.                             transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,
  1394.                             cssObj = {
  1395.                                 position: 'fixed',
  1396.                                 zIndex: 9999,
  1397.                                 left: 0,
  1398.                                 top: 0,
  1399.                                 '-webkit-backface-visibility': 'hidden'
  1400.                             },
  1401.                             t = 'transition';
  1402.  
  1403.                         cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;
  1404.  
  1405.                         newImg.css(cssObj);
  1406.                         return newImg;
  1407.                     },
  1408.                     showMainContent = function() {
  1409.                         mfp.content.css('visibility', 'visible');
  1410.                     },
  1411.                     openTimeout,
  1412.                     animatedImg;
  1413.  
  1414.                 _mfpOn('BuildControls'+ns, function() {
  1415.                     if(mfp._allowZoom()) {
  1416.  
  1417.                         clearTimeout(openTimeout);
  1418.                         mfp.content.css('visibility', 'hidden');
  1419.  
  1420.                         // Basically, all code below does is clones existing image, puts in on top of the current one and animated it
  1421.  
  1422.                         image = mfp._getItemToZoom();
  1423.  
  1424.                         if(!image) {
  1425.                             showMainContent();
  1426.                             return;
  1427.                         }
  1428.  
  1429.                         animatedImg = getElToAnimate(image);
  1430.  
  1431.                         animatedImg.css( mfp._getOffset() );
  1432.  
  1433.                         mfp.wrap.append(animatedImg);
  1434.  
  1435.                         openTimeout = setTimeout(function() {
  1436.                             animatedImg.css( mfp._getOffset( true ) );
  1437.                             openTimeout = setTimeout(function() {
  1438.  
  1439.                                 showMainContent();
  1440.  
  1441.                                 setTimeout(function() {
  1442.                                     animatedImg.remove();
  1443.                                     image = animatedImg = null;
  1444.                                     _mfpTrigger('ZoomAnimationEnded');
  1445.                                 }, 16); // avoid blink when switching images
  1446.  
  1447.                             }, duration); // this timeout equals animation duration
  1448.  
  1449.                         }, 16); // by adding this timeout we avoid short glitch at the beginning of animation
  1450.  
  1451.  
  1452.                         // Lots of timeouts...
  1453.                     }
  1454.                 });
  1455.                 _mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
  1456.                     if(mfp._allowZoom()) {
  1457.  
  1458.                         clearTimeout(openTimeout);
  1459.  
  1460.                         mfp.st.removalDelay = duration;
  1461.  
  1462.                         if(!image) {
  1463.                             image = mfp._getItemToZoom();
  1464.                             if(!image) {
  1465.                                 return;
  1466.                             }
  1467.                             animatedImg = getElToAnimate(image);
  1468.                         }
  1469.  
  1470.                         animatedImg.css( mfp._getOffset(true) );
  1471.                         mfp.wrap.append(animatedImg);
  1472.                         mfp.content.css('visibility', 'hidden');
  1473.  
  1474.                         setTimeout(function() {
  1475.                             animatedImg.css( mfp._getOffset() );
  1476.                         }, 16);
  1477.                     }
  1478.  
  1479.                 });
  1480.  
  1481.                 _mfpOn(CLOSE_EVENT+ns, function() {
  1482.                     if(mfp._allowZoom()) {
  1483.                         showMainContent();
  1484.                         if(animatedImg) {
  1485.                             animatedImg.remove();
  1486.                         }
  1487.                         image = null;
  1488.                     }
  1489.                 });
  1490.             },
  1491.  
  1492.             _allowZoom: function() {
  1493.                 return mfp.currItem.type === 'image';
  1494.             },
  1495.  
  1496.             _getItemToZoom: function() {
  1497.                 if(mfp.currItem.hasSize) {
  1498.                     return mfp.currItem.img;
  1499.                 } else {
  1500.                     return false;
  1501.                 }
  1502.             },
  1503.  
  1504.             // Get element postion relative to viewport
  1505.             _getOffset: function(isLarge) {
  1506.                 var el;
  1507.                 if(isLarge) {
  1508.                     el = mfp.currItem.img;
  1509.                 } else {
  1510.                     el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
  1511.                 }
  1512.  
  1513.                 var offset = el.offset();
  1514.                 var paddingTop = parseInt(el.css('padding-top'),10);
  1515.                 var paddingBottom = parseInt(el.css('padding-bottom'),10);
  1516.                 offset.top -= ( $(window).scrollTop() - paddingTop );
  1517.  
  1518.  
  1519.                 /*
  1520.  
  1521.                 Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.
  1522.  
  1523.                  */
  1524.                 var obj = {
  1525.                     width: el.width(),
  1526.                     // fix Zepto height+padding issue
  1527.                     height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop
  1528.                 };
  1529.  
  1530.                 // I hate to do this, but there is no another option
  1531.                 if( getHasMozTransform() ) {
  1532.                     obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';
  1533.                 } else {
  1534.                     obj.left = offset.left;
  1535.                     obj.top = offset.top;
  1536.                 }
  1537.                 return obj;
  1538.             }
  1539.  
  1540.         }
  1541.     });
  1542.  
  1543.  
  1544.  
  1545.     /*>>zoom*/
  1546.  
  1547.     /*>>iframe*/
  1548.  
  1549.     var IFRAME_NS = 'iframe',
  1550.         _emptyPage = '//about:blank',
  1551.  
  1552.         _fixIframeBugs = function(isShowing) {
  1553.             if(mfp.currTemplate[IFRAME_NS]) {
  1554.                 var el = mfp.currTemplate[IFRAME_NS].find('iframe');
  1555.                 if(el.length) {
  1556.                     // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug
  1557.                     if(!isShowing) {
  1558.                         el[0].src = _emptyPage;
  1559.                     }
  1560.  
  1561.                     // IE8 black screen bug fix
  1562.                     if(mfp.isIE8) {
  1563.                         el.css('display', isShowing ? 'block' : 'none');
  1564.                     }
  1565.                 }
  1566.             }
  1567.         };
  1568.  
  1569.     $.magnificPopup.registerModule(IFRAME_NS, {
  1570.  
  1571.         options: {
  1572.             markup: '<div class="mfp-iframe-scaler">'+
  1573.                 '<div class="mfp-close"></div>'+
  1574.                 '<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+
  1575.                 '</div>',
  1576.  
  1577.             srcAction: 'iframe_src',
  1578.  
  1579.             // we don't care and support only one default type of URL by default
  1580.             patterns: {
  1581.                 youtube: {
  1582.                     index: 'youtube.com',
  1583.                     id: 'v=',
  1584.                     src: '//www.youtube.com/embed/%id%?autoplay=1'
  1585.                 },
  1586.                 vimeo: {
  1587.                     index: 'vimeo.com/',
  1588.                     id: '/',
  1589.                     src: '//player.vimeo.com/video/%id%?autoplay=1'
  1590.                 },
  1591.                 gmaps: {
  1592.                     index: '//maps.google.',
  1593.                     src: '%id%&output=embed'
  1594.                 }
  1595.             }
  1596.         },
  1597.  
  1598.         proto: {
  1599.             initIframe: function() {
  1600.                 mfp.types.push(IFRAME_NS);
  1601.  
  1602.                 _mfpOn('BeforeChange', function(e, prevType, newType) {
  1603.                     if(prevType !== newType) {
  1604.                         if(prevType === IFRAME_NS) {
  1605.                             _fixIframeBugs(); // iframe if removed
  1606.                         } else if(newType === IFRAME_NS) {
  1607.                             _fixIframeBugs(true); // iframe is showing
  1608.                         }
  1609.                     }// else {
  1610.                     // iframe source is switched, don't do anything
  1611.                     //}
  1612.                 });
  1613.  
  1614.                 _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
  1615.                     _fixIframeBugs();
  1616.                 });
  1617.             },
  1618.  
  1619.             getIframe: function(item, template) {
  1620.                 var embedSrc = item.src;
  1621.                 var iframeSt = mfp.st.iframe;
  1622.  
  1623.                 $.each(iframeSt.patterns, function() {
  1624.                     if(embedSrc.indexOf( this.index ) > -1) {
  1625.                         if(this.id) {
  1626.                             if(typeof this.id === 'string') {
  1627.                                 embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);
  1628.                             } else {
  1629.                                 embedSrc = this.id.call( this, embedSrc );
  1630.                             }
  1631.                         }
  1632.                         embedSrc = this.src.replace('%id%', embedSrc );
  1633.                         return false; // break;
  1634.                     }
  1635.                 });
  1636.  
  1637.                 var dataObj = {};
  1638.                 if(iframeSt.srcAction) {
  1639.                     dataObj[iframeSt.srcAction] = embedSrc;
  1640.                 }
  1641.                 mfp._parseMarkup(template, dataObj, item);
  1642.  
  1643.                 mfp.updateStatus('ready');
  1644.  
  1645.                 return template;
  1646.             }
  1647.         }
  1648.     });
  1649.  
  1650.  
  1651.  
  1652.     /*>>iframe*/
  1653.  
  1654.     /*>>gallery*/
  1655.     /**
  1656.      * Get looped index depending on number of slides
  1657.      */
  1658.     var _getLoopedId = function(index) {
  1659.             var numSlides = mfp.items.length;
  1660.             if(index > numSlides - 1) {
  1661.                 return index - numSlides;
  1662.             } else  if(index < 0) {
  1663.                 return numSlides + index;
  1664.             }
  1665.             return index;
  1666.         },
  1667.         _replaceCurrTotal = function(text, curr, total) {
  1668.             return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
  1669.         };
  1670.  
  1671.     $.magnificPopup.registerModule('gallery', {
  1672.  
  1673.         options: {
  1674.             enabled: false,
  1675.             arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',
  1676.             preload: [0,2],
  1677.             navigateByImgClick: true,
  1678.             arrows: true,
  1679.  
  1680.             tPrev: 'Previous (Left arrow key)',
  1681.             tNext: 'Next (Right arrow key)',
  1682.             tCounter: '%curr% of %total%'
  1683.         },
  1684.  
  1685.         proto: {
  1686.             initGallery: function() {
  1687.  
  1688.                 var gSt = mfp.st.gallery,
  1689.                     ns = '.mfp-gallery';
  1690.  
  1691.                 mfp.direction = true; // true - next, false - prev
  1692.  
  1693.                 if(!gSt || !gSt.enabled ) return false;
  1694.  
  1695.                 _wrapClasses += ' mfp-gallery';
  1696.  
  1697.                 _mfpOn(OPEN_EVENT+ns, function() {
  1698.  
  1699.                     if(gSt.navigateByImgClick) {
  1700.                         mfp.wrap.on('click'+ns, '.mfp-img', function() {
  1701.                             if(mfp.items.length > 1) {
  1702.                                 mfp.next();
  1703.                                 return false;
  1704.                             }
  1705.                         });
  1706.                     }
  1707.  
  1708.                     _document.on('keydown'+ns, function(e) {
  1709.                         if (e.keyCode === 37) {
  1710.                             mfp.prev();
  1711.                         } else if (e.keyCode === 39) {
  1712.                             mfp.next();
  1713.                         }
  1714.                     });
  1715.                 });
  1716.  
  1717.                 _mfpOn('UpdateStatus'+ns, function(e, data) {
  1718.                     if(data.text) {
  1719.                         data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);
  1720.                     }
  1721.                 });
  1722.  
  1723.                 _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
  1724.                     var l = mfp.items.length;
  1725.                     values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';
  1726.                 });
  1727.  
  1728.                 _mfpOn('BuildControls' + ns, function() {
  1729.                     if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {
  1730.                         var markup = gSt.arrowMarkup,
  1731.                             arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),
  1732.                             arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);
  1733.  
  1734.                         arrowLeft.click(function() {
  1735.                             mfp.prev();
  1736.                         });
  1737.                         arrowRight.click(function() {
  1738.                             mfp.next();
  1739.                         });
  1740.  
  1741.                         mfp.container.append(arrowLeft.add(arrowRight));
  1742.                     }
  1743.                 });
  1744.  
  1745.                 _mfpOn(CHANGE_EVENT+ns, function() {
  1746.                     if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
  1747.  
  1748.                     mfp._preloadTimeout = setTimeout(function() {
  1749.                         mfp.preloadNearbyImages();
  1750.                         mfp._preloadTimeout = null;
  1751.                     }, 16);
  1752.                 });
  1753.  
  1754.  
  1755.                 _mfpOn(CLOSE_EVENT+ns, function() {
  1756.                     _document.off(ns);
  1757.                     mfp.wrap.off('click'+ns);
  1758.                     mfp.arrowRight = mfp.arrowLeft = null;
  1759.                 });
  1760.  
  1761.             },
  1762.             next: function() {
  1763.                 mfp.direction = true;
  1764.                 mfp.index = _getLoopedId(mfp.index + 1);
  1765.                 mfp.updateItemHTML();
  1766.             },
  1767.             prev: function() {
  1768.                 mfp.direction = false;
  1769.                 mfp.index = _getLoopedId(mfp.index - 1);
  1770.                 mfp.updateItemHTML();
  1771.             },
  1772.             goTo: function(newIndex) {
  1773.                 mfp.direction = (newIndex >= mfp.index);
  1774.                 mfp.index = newIndex;
  1775.                 mfp.updateItemHTML();
  1776.             },
  1777.             preloadNearbyImages: function() {
  1778.                 var p = mfp.st.gallery.preload,
  1779.                     preloadBefore = Math.min(p[0], mfp.items.length),
  1780.                     preloadAfter = Math.min(p[1], mfp.items.length),
  1781.                     i;
  1782.  
  1783.                 for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {
  1784.                     mfp._preloadItem(mfp.index+i);
  1785.                 }
  1786.                 for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {
  1787.                     mfp._preloadItem(mfp.index-i);
  1788.                 }
  1789.             },
  1790.             _preloadItem: function(index) {
  1791.                 index = _getLoopedId(index);
  1792.  
  1793.                 if(mfp.items[index].preloaded) {
  1794.                     return;
  1795.                 }
  1796.  
  1797.                 var item = mfp.items[index];
  1798.                 if(!item.parsed) {
  1799.                     item = mfp.parseEl( index );
  1800.                 }
  1801.  
  1802.                 _mfpTrigger('LazyLoad', item);
  1803.  
  1804.                 if(item.type === 'image') {
  1805.                     item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {
  1806.                         item.hasSize = true;
  1807.                     }).on('error.mfploader', function() {
  1808.                         item.hasSize = true;
  1809.                         item.loadError = true;
  1810.                         _mfpTrigger('LazyLoadError', item);
  1811.                     }).attr('src', item.src);
  1812.                 }
  1813.  
  1814.  
  1815.                 item.preloaded = true;
  1816.             }
  1817.         }
  1818.     });
  1819.  
  1820.     /*>>gallery*/
  1821.  
  1822.     /*>>retina*/
  1823.  
  1824.     var RETINA_NS = 'retina';
  1825.  
  1826.     $.magnificPopup.registerModule(RETINA_NS, {
  1827.         options: {
  1828.             replaceSrc: function(item) {
  1829.                 return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });
  1830.             },
  1831.             ratio: 1 // Function or number.  Set to 1 to disable.
  1832.         },
  1833.         proto: {
  1834.             initRetina: function() {
  1835.                 if(window.devicePixelRatio > 1) {
  1836.  
  1837.                     var st = mfp.st.retina,
  1838.                         ratio = st.ratio;
  1839.  
  1840.                     ratio = !isNaN(ratio) ? ratio : ratio();
  1841.  
  1842.                     if(ratio > 1) {
  1843.                         _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {
  1844.                             item.img.css({
  1845.                                 'max-width': item.img[0].naturalWidth / ratio,
  1846.                                 'width': '100%'
  1847.                             });
  1848.                         });
  1849.                         _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {
  1850.                             item.src = st.replaceSrc(item, ratio);
  1851.                         });
  1852.                     }
  1853.                 }
  1854.  
  1855.             }
  1856.         }
  1857.     });
  1858.  
  1859.     /*>>retina*/
  1860.     _checkInstance(); }));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement