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