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