vendor: 6,764 bytes, lines 1-230
1/** 2 * fancyBox - jQuery Plugin 3 * version: 2.2.0 (Tue, 16 Sep 2022) 4 * requires jQuery v1.6 or later 5 * 6 * Licensed GPLv3 for open source use 7 * or fancyBox Commercial License for commercial use 8 * 9 * Examples at http://fancyapps.com/fancybox/ 10 * License: www.fancyapps.com/fancybox/#license 11 * 12 * Copyright 2017 fancyapps.com 13 */ 14 15;(function (window, document, $, undefined) { 16 "use strict"; 17 18 var H = $("html"), 19 W = $(window), 20 D = $(document), 21 F = $.fancybox = function () { 22 F.open.apply( this, arguments ); 23 }, 24 IE = navigator.userAgent.match(/msie/i), 25 didUpdate = null, 26 isTouch = 'ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0, 27 28 isQuery = function(obj) { 29 return obj && obj.hasOwnProperty && obj instanceof $; 30 }, 31 isString = function(str) { 32 return str && $.type(str) === "string"; 33 }, 34 isPercentage = function(str) { 35 return isString(str) && str.indexOf('%') > 0; 36 }, 37 isScrollable = function(el) { 38 return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight))); 39 }, 40 getScalar = function(orig, dim) { 41 var value = parseInt(orig, 10) || 0; 42 43 if (dim && isPercentage(orig)) { 44 value = F.getViewport()[ dim ] / 100 * value; 45 } 46 47 return Math.ceil(value); 48 }, 49 getValue = function(value, dim) { 50 return getScalar(value, dim) + 'px'; 51 }; 52 53 $.extend(F, { 54 // The current version of fancyBox 55 version: '2.2.0', 56 57 defaults: { 58 padding : 15, 59 margin : 20, 60 61 width : 800, 62 height : 600, 63 minWidth : 100, 64 minHeight : 100, 65 maxWidth : 9999, 66 maxHeight : 9999, 67 pixelRatio: window.devicePixelRatio || 1, // Set to 2 for retina display support 68 69 autoSize : true, 70 autoHeight : false, 71 autoWidth : false, 72 73 autoResize : true, 74 autoCenter : !isTouch, 75 fitToView : true, 76 aspectRatio : false, 77 topRatio : 0.5, 78 leftRatio : 0.5, 79 minVpWidth : 320, 80 minVpHeight : 320, 81 82 scrolling : 'auto', // 'auto', 'yes' or 'no' 83 wrapCSS : '', 84 85 arrows : true, 86 closeBtn : true, 87 closeClick : false, 88 nextClick : false, 89 zoomClick : false, 90 mouseWheel : true, 91 swipe : isTouch, 92 autoPlay : false, 93 playSpeed : 3000, 94 preload : 3, 95 modal : false, 96 loop : true, 97 98 ajax : { 99 dataType : 'html', 100 headers : { 'X-fancyBox': true } 101 }, 102 iframe : { 103 scrolling : 'auto', 104 allowfullscreen : true, 105 preload : true 106 }, 107 svg : {}, 108 109 keys : { 110 next : { 111 13 : 'left', // enter 112 34 : 'up', // page down 113 39 : 'left', // right arrow 114 40 : 'up' // down arrow 115 }, 116 prev : { 117 8 : 'right', // backspace 118 33 : 'down', // page up 119 37 : 'right', // left arrow 120 38 : 'down' // up arrow 121 }, 122 close : [27], // escape key 123 play : [32], // space - start/stop slideshow 124 toggle : [70] // letter "f" - toggle fullscreen 125 }, 126 127 direction : { 128 next : 'left', 129 prev : 'right' 130 }, 131 132 scrollOutside : true, 133 134 // Override some properties 135 index : 0, 136 type : null, 137 href : null, 138 content : null, 139 title : null, 140 141 // HTML templates 142 tpl: { 143 wrap : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 144 image : '<img class="fancybox-image" src="{href}" alt="" />', 145 iframe : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" allow="autoplay; encrypted-media;"' + (IE ? ' allowtransparency="true"' : '') + '></iframe>', 146 error : '<p class="fancybox-error">{error}</p>', 147 close : `<a title="${DOMPurify.sanitize((window.efb_i18n && window.efb_i18n.close) || 'Close')}" class="fancybox-item fancybox-close" href="javascript:;"></a>`, 148 next : `<a title="${DOMPurify.sanitize((window.efb_i18n && window.efb_i18n.next) || 'Next')}" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>`, 149 prev : `<a title="${DOMPurify.sanitize((window.efb_i18n && window.efb_i18n.prev) || 'Previous')}" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>`, 150 loading : '<div id="fancybox-loading"><div></div></div>' 151 }, 152 153 // Texts 154 txt: { 155 error : { 156 content : 'The requested content cannot be loaded.<br/>Please try again later.', 157 image : 'The requested image cannot be loaded.<br/>Please try again later.', 158 ajax : 'An AJAX error occurred.<br/>Please contact the site administrator.', 159 href : 'Missing media target URL.<br/>Please contact the site administrator.', 160 }, 161 close : (window.efb_i18n && window.efb_i18n.close) || 'Close', 162 next : (window.efb_i18n && window.efb_i18n.next) || 'Next', 163 prev : (window.efb_i18n && window.efb_i18n.prev) || 'Previous' 164 }, 165 166 // Properties for each animation type 167 // Opening fancyBox 168 openEffect : 'fade', // 'elastic', 'fade' or 'none' 169 openSpeed : 250, 170 openEasing : 'swing', 171 openOpacity : true, 172 openMethod : 'zoomIn', 173 174 // Closing fancyBox 175 closeEffect : 'fade', // 'elastic', 'fade' or 'none' 176 closeSpeed : 250, 177 closeEasing : 'swing', 178 closeOpacity : true, 179 closeMethod : 'zoomOut', 180 181 // Changing next gallery item 182 nextEffect : 'elastic', // 'elastic', 'fade' or 'none' 183 nextSpeed : 250, 184 nextEasing : 'swing', 185 nextMethod : 'changeIn', 186 187 // Changing previous gallery item 188 prevEffect : 'elastic', // 'elastic', 'fade' or 'none' 189 prevSpeed : 250, 190 prevEasing : 'swing', 191 prevMethod : 'changeOut', 192 193 // Enable default helpers 194 helpers : { 195 overlay : true, 196 title : true 197 }, 198 199 // Callbacks 200 onCancel : $.noop, // If canceling 201 beforeLoad : $.noop, // Before loading 202 afterLoad : $.noop, // After loading 203 beforeShow : $.noop, // Before changing in current item 204 afterShow : $.noop, // After opening 205 beforeChange : $.noop, // Before changing gallery item 206 beforeClose : $.noop, // Before closing 207 afterClose : $.noop // After closing 208 }, 209 210 //Current state 211 group : {}, // Selected group 212 opts : {}, // Group options 213 previous : null, // Previous element 214 coming : null, // Element being loaded 215 current : null, // Currently loaded element 216 isActive : false, // Is activated 217 isOpen : false, // Is currently open 218 isOpened : false, // Have been fully opened at least once 219 220 wrap : null, 221 skin : null, 222 outer : null, 223 inner : null, 224 225 player : { 226 timer : null, 227 isActive : false 228 }, 229 230 // Loaders
vendor: 9,913 bytes, lines 231-679
231 ajaxLoad : null, 232 imgPreload : null, 233 234 // Some collections 235 transitions : {}, 236 helpers : {}, 237 238 /* 239 * Static methods 240 */ 241 242 open: function (group, opts) { 243 if (!group) { 244 return; 245 } 246 247 if (!$.isPlainObject(opts)) { 248 opts = {}; 249 } 250 251 // Close if already active 252 if (false === F.close(true)) { 253 return; 254 } 255 256 // Normalize group 257 if (!$.isArray(group)) { 258 group = isQuery(group) ? $(group).get() : [group]; 259 } 260 261 // Recheck if the type of each element is `object` and set content type (image, ajax, etc) 262 $.each(group, function(i, element) { 263 var obj = {}, 264 href, 265 title, 266 content, 267 type, 268 rez, 269 hrefParts, 270 selector; 271 272 if ($.type(element) === "object") { 273 // Check if is DOM element 274 if (element.nodeType) { 275 element = $(element); 276 } 277 278 if (isQuery(element)) { 279 obj = { 280 href : element.data('fancybox-href') || element.attr('href'), 281 title : $('<div/>').text(DOMPurify.sanitize( 282 element.is('img') ? element.attr('title') : element.find('img').attr('title') || '' 283 )).html(), 284 isDom : true, 285 element : element 286 }; 287 console.log( element.find('img') ); 288 console.log('title: '); 289 console.log( element.find('img').attr('title') ); 290 291 if ($.metadata) { 292 $.extend(true, obj, element.metadata()); 293 } 294 } 295 else { 296 obj = element; 297 } 298 } 299 300 href = opts.href || obj.href || (isString(element) ? element : null); 301 title = DOMPurify.sanitize(opts.title !== undefined ? opts.title : obj.title || ''); 302 303 content = opts.content || obj.content; 304 type = content ? 'html' : (opts.type || obj.type); 305 306 if (!type && obj.isDom) { 307 type = element.data('fancybox-type'); 308 309 if (!type) { 310 rez = element.prop('class').match(/fancybox\.(\w+)/); 311 type = rez ? rez[1] : null; 312 } 313 } 314 315 if (isString(href)) { 316 // Try to guess the content type 317 if (!type) { 318 if (F.isImage(href)) { 319 type = 'image'; 320 } 321 else if (F.isSVG(href)) { 322 type = 'svg'; 323 } 324 else if (href.charAt(0) === '#') { 325 type = 'inline'; 326 } 327 else if (isString(element)) { 328 type = 'html'; 329 content = element; 330 } 331 } 332 333 // Split url into two pieces with source url and content selector, e.g, 334 // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id" 335 if (type === 'ajax') { 336 hrefParts = href.split(/\s+/, 2); 337 href = hrefParts.shift(); 338 selector = hrefParts.shift(); 339 } 340 } 341 342 if (!content) { 343 if (type === 'inline') { 344 if (href) { 345 content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7 346 } 347 else if (obj.isDom) { 348 content = element; 349 } 350 } 351 else if (type === 'html') { 352 content = href; 353 } 354 else if (!type && !href && obj.isDom) { 355 type = 'inline'; 356 content = element; 357 } 358 } 359 360 $.extend(obj, { 361 href : href, 362 type : type, 363 content : content, 364 title : title, 365 selector : selector 366 }); 367 368 group[ i ] = obj; 369 }); 370 371 // Extend the defaults 372 F.opts = $.extend(true, {}, F.defaults, opts); 373 374 // All options are merged recursive except keys 375 if (opts.keys !== undefined) { 376 F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false; 377 } 378 379 F.group = group; 380 381 return F._start(F.opts.index); 382 }, 383 384 // Cancel image loading or abort ajax request 385 cancel: function () { 386 var coming = F.coming; 387 388 if (coming && false === F.trigger('onCancel')) { 389 return; 390 } 391 392 F.hideLoading(); 393 394 if (!coming) { 395 return; 396 } 397 398 if (F.ajaxLoad) { 399 F.ajaxLoad.abort(); 400 } 401 402 F.ajaxLoad = null; 403 404 if (F.imgPreload) { 405 F.imgPreload.onload = F.imgPreload.onerror = null; 406 } 407 408 if (coming.wrap) { 409 coming.wrap.stop(true, true).trigger('onReset').remove(); 410 } 411 412 F.coming = null; 413 414 // If the first item has been canceled, then clear everything 415 if (!F.current) { 416 F._afterZoomOut( coming ); 417 } 418 }, 419 420 // Start closing animation if is open; remove immediately if opening/closing 421 close: function (event) { 422 F.cancel(); 423 424 if (false === F.trigger('beforeClose')) { 425 return; 426 } 427 428 F.unbindEvents(); 429 430 if (!F.isActive) { 431 return; 432 } 433 434 if (!F.isOpen || event === true) { 435 $('.fancybox-wrap').stop(true).trigger('onReset').remove(); 436 437 F._afterZoomOut(); 438 } 439 else { 440 F.isOpen = F.isOpened = false; 441 F.isClosing = true; 442 443 $('.fancybox-item, .fancybox-nav').remove(); 444 445 F.wrap.stop(true, true).removeClass('fancybox-opened'); 446 447 F.transitions[ F.current.closeMethod ](); 448 } 449 }, 450 451 // Manage slideshow: 452 // $.fancybox.play(); - toggle slideshow 453 // $.fancybox.play( true ); - start 454 // $.fancybox.play( false ); - stop 455 play: function ( action ) { 456 var clear = function () { 457 clearTimeout(F.player.timer); 458 }, 459 set = function () { 460 clear(); 461 462 if (F.current && F.player.isActive) { 463 F.player.timer = setTimeout(F.next, F.current.playSpeed); 464 } 465 }, 466 stop = function () { 467 clear(); 468 469 D.off('.player'); 470 471 F.player.isActive = false; 472 473 F.trigger('onPlayEnd'); 474 }, 475 start = function () { 476 if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) { 477 F.player.isActive = true; 478 479 D.on({ 480 'onCancel.player beforeClose.player' : stop, 481 'onUpdate.player' : set, 482 'beforeLoad.player' : clear 483 }); 484 485 set(); 486 487 F.trigger('onPlayStart'); 488 } 489 }; 490 491 if (action === true || (!F.player.isActive && action !== false)) { 492 start(); 493 } 494 else { 495 stop(); 496 } 497 }, 498 499 // Navigate on mousewheel, swipe or drag 500 swipe: function ( deltaX, deltaY, threshold ) { 501 if ( deltaX > threshold || deltaY > threshold ) { 502 F.wrap.off('touchstart.fb touchmove.fb touchend.fb mouseup.fb mousedown.fb mousemove.fb mousewheel.fb'); 503 F.next( deltaY > threshold ? 'up' : 'left' ); 504 } 505 else if ( deltaX < -threshold || deltaY < -threshold ) { 506 F.wrap.off('touchstart.fb touchmove.fb touchend.fb mouseup.fb mousedown.fb mousemove.fb mousewheel.fb'); 507 F.prev( deltaY < -threshold ? 'down' : 'right' ); 508 } 509 }, 510 511 // Navigate to next gallery item 512 next: function ( direction ) { 513 var current = F.current; 514 515 if (current) { 516 if (!isString(direction)) { 517 direction = current.direction.next; 518 } 519 520 F.jumpto(current.index + 1, direction, 'next'); 521 } 522 }, 523 524 // Navigate to previous gallery item 525 prev: function ( direction ) { 526 var current = F.current; 527 528 if (current) { 529 if (!isString(direction)) { 530 direction = current.direction.prev; 531 } 532 533 F.jumpto(current.index - 1, direction, 'prev'); 534 } 535 }, 536 537 // Navigate to gallery item by index 538 jumpto: function ( index, direction, router ) { 539 var current = F.current; 540 541 if (!current) { 542 return; 543 } 544 545 index = getScalar(index); 546 547 F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ]; 548 F.router = router || 'jumpto'; 549 550 if (current.loop) { 551 if (index < 0) { 552 index = current.group.length + (index % current.group.length); 553 } 554 555 index = index % current.group.length; 556 } 557 558 if (current.group[ index ] !== undefined) { 559 F.cancel(); 560 F.isJumping = true; 561 F._start(index); 562 } 563 }, 564 565 canScroll: function ( target ) { 566 let canScroll = false, 567 parent = $(target); 568 569 while (parent.length) { 570 if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) { 571 break; 572 } 573 canScroll = isScrollable( parent[0] ); 574 parent = $(parent).parent(); 575 } 576 577 return canScroll; 578 }, 579 580 // Center inside viewport and toggle position type to fixed or absolute if needed 581 reposition: function (e, onlyAbsolute) { 582 var current = F.current, 583 wrap = current ? current.wrap : null, 584 pos; 585 586 if (wrap) { 587 pos = F._getPosition(onlyAbsolute); 588 589 if (e && e.type === 'scroll') { 590 delete pos.position; 591 592 wrap.stop(true, true).animate(pos, 200); 593 } 594 else { 595 wrap.css(pos); 596 597 current.pos = $.extend({}, current.dim, pos); 598 } 599 } 600 }, 601 602 update: function (e) { 603 var type = (e && e.originalEvent && e.originalEvent.type), 604 anyway = !type || type === 'orientationchange'; 605 606 if (anyway) { 607 clearTimeout(didUpdate); 608 609 didUpdate = null; 610 } 611 612 if (!F.isOpen || didUpdate) { 613 return; 614 } 615 616 didUpdate = setTimeout(function() { 617 var current = F.current; 618 619 if (!current || F.isClosing) { 620 return; 621 } 622 623 F.wrap.removeClass('fancybox-tmp'); 624 625 if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) { 626 F._setDimension(); 627 } 628 629 if (!(type === 'scroll' && current.canShrink)) { 630 F.reposition(e); 631 } 632 633 if (current.zoomClick) { 634 F.inner.css('cursor', current.canExpand ? 'zoom-in' : 'zoom-out'); 635 } 636 637 F.trigger('onUpdate'); 638 639 didUpdate = null; 640 641 }, (anyway && !isTouch ? 0 : 300)); 642 }, 643 644 // Shrink content to fit inside viewport or restore if resized 645 toggle: function ( action ) { 646 if (F.isOpen) { 647 F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView; 648 649 // Help browser to restore document dimensions 650 if (isTouch) { 651 F.wrap.removeAttr('style').addClass('fancybox-tmp'); 652 653 F.trigger('onUpdate'); 654 } 655 656 F.update(); 657 } 658 }, 659 660 hideLoading: function () { 661 D.off('.loading'); 662 663 $('#fancybox-loading').remove(); 664 }, 665 666 showLoading: function () { 667 var el, viewport; 668 669 F.hideLoading(); 670 671 el = $(F.opts.tpl.loading).on('click',F.cancel).appendTo('body'); 672 673 // If user will press the escape-button, the request will be canceled 674 D.on('keydown.loading', function(e) { 675 if ((e.which || e.keyCode) === 27) { 676 F.cancel(); 677 678 e.preventDefault(); 679 return false;
680 } 681 }); 682 683 if (!F.defaults.fixed) { 684 viewport = F.getViewport(); 685 686 el.css({ 687 position : 'absolute', 688 top : (viewport.h * 0.5) + viewport.y, 689 left : (viewport.w * 0.5) + viewport.x 690 }); 691 } 692 693 F.trigger('onLoading'); 694 }, 695 696 getViewport: function () { 697 var locked = (F.current && F.current.locked) || false, 698 rez = { 699 x: W.scrollLeft(), 700 y: W.scrollTop() 701 }; 702 703 if (locked && locked.length) { 704 rez.w = locked[0].clientWidth; 705 rez.h = locked[0].clientHeight; 706 } 707 else { 708 // See http://bugs.jquery.com/ticket/6724 709 rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width(); 710 rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height(); 711 } 712 713 return rez; 714 }, 715 716 // Unbind the keyboard / clicking actions 717 unbindEvents: function () { 718 if (F.wrap && isQuery(F.wrap)) { 719 F.wrap.off('.fb'); 720 } 721 722 D.off('.fb'); 723 W.off('.fb'); 724 }, 725 726 bindEvents: function () { 727 var current = F.current, 728 keys; 729 730 if (!current) { 731 return; 732 } 733 734 // Changing document height on iOS devices triggers a 'resize' event, 735 // that can change document height... repeating infinitely 736 W.on('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update); 737 738 keys = current.keys; 739 740 if (keys) { 741 D.on('keydown.fb', function (e) { 742 var code = e.which || e.keyCode, 743 target = e.target || e.srcElement; 744 745 // Skip esc key if loading, because showLoading will cancel preloading 746 if (code === 27 && F.coming) { 747 return false; 748 } 749 750 // Ignore key combinations and key events within form elements 751 if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) { 752 $.each(keys, function(i, val) { 753 if (current.group.length > 1 && val[ code ] !== undefined) { 754 F[ i ]( val[ code ] ); 755 756 e.preventDefault(); 757 return false; 758 } 759 760 if ($.inArray(code, val) > -1) { 761 F[ i ] (); 762 763 e.preventDefault(); 764 return false; 765 } 766 }); 767 } 768 }); 769 } 770 771 if (current.group.length > 1) { 772 F.wrap.css('cursor','move'); 773 F.wrap.on('mousedown.fb', function(e){ 774 let drag = {}; 775 776 e.preventDefault(); 777 778 drag.startX = typeof e.clientX !== 'undefined' ? e.clientX : e.originalEvent.clientX; 779 drag.startY = typeof e.clientY !== 'undefined' ? e.clientY : e.originalEvent.clientY; 780 781 F.wrap.on('mousemove.fb',function(e) { 782 e.preventDefault(); 783 784 drag.endX = typeof e.clientX !== 'undefined' ? e.clientX : e.originalEvent.clientX; 785 drag.endY = typeof e.clientY !== 'undefined' ? e.clientY : e.originalEvent.clientY; 786 }); 787 788 F.wrap.on('mouseup.fb', function(){ 789 F.wrap.off('mousemove.fb'); 790 F.swipe(drag.startX - drag.endX, drag.startY - drag.endY, 100); 791 }); 792 }); 793 794 if (current.swipe) { 795 F.wrap.on('touchstart.fb', function(e){ 796 let target = e.target || null, 797 touch = {}, 798 fingers = typeof e.touches !== 'undefined' ? e.touches.length : e.originalEvent.touches.length; 799 800 if ( current.canShrink || fingers > 1 || F.canScroll( target ) ) { 801 return; 802 } 803 804 e.preventDefault(); 805 806 touch.startX = typeof e.touches !== 'undefined' ? e.touches[0].clientX : e.originalEvent.touches[0].clientX; 807 touch.startY = typeof e.touches !== 'undefined' ? e.touches[0].clientY : e.originalEvent.touches[0].clientY; 808 809 F.wrap.on('touchmove.fb',function(e) { 810 fingers = typeof e.touches !== 'undefined' ? e.touches.length : e.originalEvent.touches.length; 811 if ( fingers > 1 ) { 812 return; 813 } 814 e.preventDefault(); 815 816 let x = typeof e.touches !== 'undefined' ? e.touches[0].clientX : e.originalEvent.touches[0].clientX, 817 y = typeof e.touches !== 'undefined' ? e.touches[0].clientY : e.originalEvent.touches[0].clientY; 818 819 F.swipe(touch.startX - x, touch.startY - y, 100); 820 }); 821 }); 822 F.wrap.on('touchend.fb', function(){ 823 F.wrap.off('touchmove.fb'); 824 }); 825 } 826 827 if ($.fn.mousewheel && current.mouseWheel) { 828 F.wrap.on('mousewheel.fb', function (e, delta, deltaX, deltaY) { 829 let target = e.target || null; 830 831 if (current.canShrink || delta === 0 || F.canScroll(target)) { 832 return; 833 } 834 835 e.preventDefault(); 836 837 F.swipe(-deltaX, -deltaY, 0); 838 }); 839 } 840 } 841 }, 842 843 trigger: function (event, o) { 844 var ret, obj = o || F.coming || F.current; 845 846 if (obj) { 847 if ($.isFunction( obj[event] )) { 848 ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1)); 849 } 850 851 if (ret === false) { 852 return false;
vendor: 28,838 bytes, lines 853-2002
853 } 854 855 if (obj.helpers) { 856 $.each(obj.helpers, function (helper, opts) { 857 if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) { 858 F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj); 859 } 860 }); 861 } 862 } 863 864 D.trigger(event); 865 }, 866 867 isImage: function (str) { 868 return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i); 869 }, 870 871 isSVG: function (str) { 872 return isString(str) && str.match(/\.(svg)((\?|#).*)?$/i); 873 }, 874 875 _start: function (index) { 876 var coming = {}, 877 obj, 878 href, 879 type, 880 margin, 881 padding; 882 883 index = getScalar( index ); 884 obj = F.group[ index ] || null; 885 886 if (!obj) { 887 return false; 888 } 889 890 coming = $.extend(true, {}, F.opts, obj); 891 892 // Convert margin and padding properties to array - top, right, bottom, left 893 margin = coming.margin; 894 padding = coming.padding; 895 896 if ($.type(margin) === 'number') { 897 coming.margin = [margin, margin, margin, margin]; 898 } 899 900 if ($.type(padding) === 'number') { 901 coming.padding = [padding, padding, padding, padding]; 902 } 903 904 // 'modal' propery is just a shortcut 905 if (coming.modal) { 906 $.extend(true, coming, { 907 closeBtn : false, 908 closeClick : false, 909 nextClick : false, 910 zoomClick : false, 911 arrows : false, 912 mouseWheel : false, 913 keys : null, 914 helpers: { 915 overlay : { 916 closeClick : false 917 } 918 } 919 }); 920 } 921 922 // 'autoSize' property is a shortcut, too 923 if (coming.autoSize) { 924 coming.autoWidth = coming.autoHeight = true; 925 } 926 927 if (coming.width === 'auto') { 928 coming.autoWidth = true; 929 } 930 931 if (coming.height === 'auto') { 932 coming.autoHeight = true; 933 } 934 935 /* 936 * Add reference to the group, so it`s possible to access from callbacks, example: 937 * afterLoad : function() { 938 * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : ''); 939 * } 940 */ 941 942 coming.group = F.group; 943 coming.index = index; 944 945 // Give a chance for callback or helpers to update coming item (type, title, etc) 946 F.coming = coming; 947 948 if (false === F.trigger('beforeLoad')) { 949 F.coming = null; 950 951 return; 952 } 953 954 type = coming.type; 955 href = coming.href; 956 957 if (!type) { 958 F.coming = null; 959 960 //If we can not determine content type then drop silently or display next/prev item if looping through gallery 961 if (F.current && F.router && F.router !== 'jumpto') { 962 F.current.index = index; 963 964 return F[ F.router ]( F.direction ); 965 } 966 967 return false; 968 } 969 970 F.isActive = true; 971 972 if (type === 'image' || type === 'svg') { 973 coming.autoHeight = coming.autoWidth = false; 974 coming.scrolling = 'visible'; 975 coming.aspectRatio = true; 976 } 977 978 if (type === 'iframe' && isTouch) { 979 coming.scrolling = 'scroll'; 980 } 981 982 // Build the neccessary markup 983 coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' ); 984 985 $.extend(coming, { 986 skin : $('.fancybox-skin', coming.wrap), 987 outer : $('.fancybox-outer', coming.wrap), 988 inner : $('.fancybox-inner', coming.wrap) 989 }); 990 991 $.each(["Top", "Right", "Bottom", "Left"], function(i, v) { 992 coming.skin.css('padding' + v, getValue(coming.padding[ i ])); 993 }); 994 995 F.trigger('onReady'); 996 997 // Check before try to load; 'inline' and 'html' types need content, others - href 998 if (type === 'inline' || type === 'html') { 999 if (!coming.content || !coming.content.length) { 1000 return F._error( 'content' ); 1001 } 1002 } 1003 else if (!href) { 1004 return F._error( 'href' ); 1005 } 1006 1007 if (type === 'image') { 1008 F._loadImage(); 1009 } 1010 else if (type === 'ajax') { 1011 F._loadAjax(); 1012 } 1013 else if (type === 'iframe') { 1014 F._loadIframe(); 1015 } 1016 else { 1017 F._afterLoad(); 1018 } 1019 }, 1020 1021 _error: function ( type ) { 1022 let msg = F.coming.txt.error[type] || F.coming.txt.error['content']; 1023 if( arguments.length > 1 ) { 1024 msg = msg + '<br/><br/>' + arguments[1]; 1025 } 1026 $.extend(F.coming, { 1027 type : 'html', 1028 autoWidth : true, 1029 autoHeight : true, 1030 minWidth : 0, 1031 minHeight : 0, 1032 scrolling : 'no', 1033 content : F.coming.tpl.error.replace(/\{error\}/g, msg) 1034 }); 1035 1036 F._afterLoad(); 1037 }, 1038 1039 _loadImage: function () { 1040 // Reset preload image so it is later possible to check "complete" property 1041 var img = F.imgPreload = new Image(); 1042 1043 img.onload = function () { 1044 this.onload = this.onerror = null; 1045 1046 F.coming.width = this.width / F.opts.pixelRatio; 1047 F.coming.height = this.height / F.opts.pixelRatio; 1048 1049 F._afterLoad(); 1050 }; 1051 1052 img.onerror = function () { 1053 this.onload = this.onerror = null; 1054 1055 F._error( 'image' ); 1056 }; 1057 1058 img.src = F.coming.href; 1059 1060 if (img.complete !== true) { 1061 F.showLoading(); 1062 } 1063 }, 1064 1065 _loadAjax: function () { 1066 var coming = F.coming; 1067 1068 F.showLoading(); 1069 1070 F.ajaxLoad = $.ajax($.extend({}, coming.ajax, { 1071 url: coming.href, 1072 error: function (jqXHR, textStatus) { 1073 if (F.coming && textStatus !== 'abort') { 1074 F._error( 'ajax', jqXHR ); 1075 } 1076 else { 1077 F.hideLoading(); 1078 } 1079 }, 1080 success: function (data, textStatus) { 1081 if (textStatus === 'success') { 1082 coming.content = data; 1083 1084 F._afterLoad(); 1085 } 1086 } 1087 })); 1088 }, 1089 1090 _loadIframe: function() { 1091 var coming = F.coming, 1092 iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime())) 1093 .attr({ 1094 'scrolling' : (isTouch ? 'auto' : coming.iframe.scrolling), 1095 'src' : coming.href, 1096 'webkitallowfullscreen' : coming.iframe.allowfullscreen, 1097 'mozallowfullscreen' : coming.iframe.allowfullscreen, 1098 'allowfullscreen' : coming.iframe.allowfullscreen 1099 }); 1100 1101 // This helps IE 1102 $(coming.wrap).on('onReset', function () { 1103 try { 1104 $(this).find('iframe').hide().attr('src', '//about:blank').end().empty(); 1105 } catch (e) {} 1106 }); 1107 1108 if (coming.iframe.preload) { 1109 F.showLoading(); 1110 1111 iframe.one('load', function() { 1112 $(this).data('ready', 1); 1113 1114 // iOS will lose scrolling if we resize 1115 if (!isTouch) { 1116 $(this).on('load.fb', F.update); 1117 } 1118 1119 // Without this trick: 1120 // - iframe won't scroll on iOS devices 1121 // - IE7 sometimes displays empty iframe 1122 $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show(); 1123 1124 F._afterLoad(); 1125 }); 1126 } 1127 1128 coming.content = iframe.appendTo( coming.inner ); 1129 1130 if (!coming.iframe.preload) { 1131 F._afterLoad(); 1132 } 1133 }, 1134 1135 _preloadImages: function() { 1136 var group = F.group, 1137 current = F.current, 1138 len = group.length, 1139 cnt = current.preload ? Math.min(current.preload, len - 1) : 0, 1140 item, 1141 i; 1142 1143 for (i = 1; i <= cnt; i += 1) { 1144 item = group[ (current.index + i ) % len ]; 1145 1146 if (item.type === 'image' && item.href) { 1147 new Image().src = item.href; 1148 } 1149 } 1150 }, 1151 1152 _afterLoad: function () { 1153 var coming = F.coming, 1154 previous = F.current, 1155 placeholder = 'fancybox-placeholder', 1156 current, 1157 content, 1158 type, 1159 scrolling, 1160 href, 1161 embed; 1162 1163 F.hideLoading(); 1164 1165 if (!coming || F.isActive === false) { 1166 return; 1167 } 1168 1169 if (false === F.trigger('afterLoad', coming, previous)) { 1170 coming.wrap.stop(true).trigger('onReset').remove(); 1171 1172 F.coming = null; 1173 1174 return; 1175 } 1176 1177 if (previous) { 1178 F.trigger('beforeChange', previous); 1179 1180 previous.wrap.stop(true).removeClass('fancybox-opened') 1181 .find('.fancybox-item, .fancybox-nav') 1182 .remove(); 1183 } 1184 1185 F.unbindEvents(); 1186 1187 current = coming; 1188 content = coming.content; 1189 type = coming.type; 1190 scrolling = coming.scrolling; 1191 1192 $.extend(F, { 1193 wrap : current.wrap, 1194 skin : current.skin, 1195 outer : current.outer, 1196 inner : current.inner, 1197 current : current, 1198 previous : previous 1199 }); 1200 1201 href = current.href; 1202 1203 switch (type) { 1204 case 'image': 1205 // Build the <img> via DOM APIs and set src with .attr() so an entity-decoded 1206 // href cannot break out of the src="{href}" attribute (also covers auto-detected 1207 // SVG, which is routed through isImage()). 1208 content = $( current.tpl.image.replace(/\{href\}/g, '') ).attr('src', href); 1209 break; 1210 1211 case 'svg': 1212 content = $('<object/>', { 1213 type : 'image/svg+xml', 1214 width : '100%', 1215 height : '100%' 1216 }).attr('data', href); 1217 break; 1218 1219 case 'inline': 1220 case 'ajax': 1221 case 'html': 1222 if (current.selector) { 1223 content = $('<div>').html(content).find(current.selector); 1224 } 1225 else if (isQuery(content)) { 1226 if (!content.data(placeholder)) { 1227 content.data(placeholder, content.clone().removeAttr('id').addClass(placeholder).insertAfter( content ) ); 1228 } 1229 1230 content = content.detach(); 1231 1232 current.wrap.on('onReset', function () { 1233 if ($(this).find(content).length) { 1234 content.replaceAll( content.data(placeholder) ).data(placeholder, false); 1235 } 1236 }); 1237 } 1238 break; 1239 } 1240 1241 if (!(isQuery(content) && content.parent().is(current.inner))) { 1242 current.inner.append( content ); 1243 } 1244 1245 // Give a chance for helpers or callbacks to update elements 1246 F.trigger('beforeShow'); 1247 1248 // Set scrolling before calculating dimensions 1249 current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling)); 1250 1251 // Set initial dimensions and start position 1252 F._setDimension(); 1253 1254 F.reposition(); 1255 1256 F.isOpen = false; 1257 F.coming = null; 1258 1259 F.bindEvents(); 1260 1261 if (!F.isOpened) { 1262 $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove(); 1263 } 1264 else if (previous.prevMethod) { 1265 F.transitions[ previous.prevMethod ](); 1266 } 1267 1268 F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ](); 1269 1270 F._preloadImages(); 1271 }, 1272 1273 _setDimension: function () { 1274 var viewport = F.getViewport(), 1275 steps = 0, 1276 canShrink = false, 1277 canExpand = false, 1278 wrap = F.wrap, 1279 skin = F.skin, 1280 inner = F.inner, 1281 current = F.current, 1282 width = current.width, 1283 height = current.height, 1284 minWidth = current.minWidth, 1285 minHeight = current.minHeight, 1286 maxWidth = current.maxWidth, 1287 maxHeight = current.maxHeight, 1288 scrolling = current.scrolling, 1289 scrollOut = current.scrollOutside ? current.scrollbarWidth : 0, 1290 margin = current.margin, 1291 wMargin = getScalar(margin[1] + margin[3]), 1292 hMargin = getScalar(margin[0] + margin[2]), 1293 wPadding, 1294 hPadding, 1295 wSpace, 1296 hSpace, 1297 origWidth, 1298 origHeight, 1299 origMaxWidth, 1300 origMaxHeight, 1301 ratio, 1302 width_, 1303 height_, 1304 maxWidth_, 1305 maxHeight_, 1306 iframe, 1307 body; 1308 1309 // Reset dimensions so we could re-check actual size 1310 wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp'); 1311 1312 wPadding = getScalar(skin.outerWidth(true) - skin.width()); 1313 hPadding = getScalar(skin.outerHeight(true) - skin.height()); 1314 1315 // Any space between content and viewport (margin, padding, border, title) 1316 wSpace = wMargin + wPadding; 1317 hSpace = hMargin + hPadding; 1318 1319 origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width; 1320 origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height; 1321 1322 if (current.type === 'iframe') { 1323 iframe = current.content; 1324 1325 if (current.autoHeight && iframe && iframe.data('ready') === 1) { 1326 try { 1327 if (iframe[0].contentWindow.document.location) { 1328 inner.width( origWidth ).height(9999); 1329 1330 body = iframe.contents().find('body'); 1331 1332 if (scrollOut) { 1333 body.css('overflow-x', 'hidden'); 1334 } 1335 1336 origHeight = body.outerHeight(true); 1337 } 1338 1339 } catch (e) {} 1340 } 1341 } 1342 else if (current.autoWidth || current.autoHeight) { 1343 inner.addClass( 'fancybox-tmp' ); 1344 1345 // Set width or height in case we need to calculate only one dimension 1346 if (!current.autoWidth) { 1347 inner.width( origWidth ); 1348 } 1349 1350 if (!current.autoHeight) { 1351 inner.height( origHeight ); 1352 } 1353 1354 if (current.autoWidth) { 1355 origWidth = inner.width(); 1356 } 1357 1358 if (current.autoHeight) { 1359 origHeight = inner.height(); 1360 } 1361 1362 inner.removeClass( 'fancybox-tmp' ); 1363 } 1364 1365 width = getScalar( origWidth ); 1366 height = getScalar( origHeight ); 1367 1368 ratio = origWidth / origHeight; 1369 1370 // Calculations for the content 1371 minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth); 1372 maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth); 1373 1374 minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight); 1375 maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight); 1376 1377 // These will be used to determine if wrap can fit in the viewport 1378 origMaxWidth = maxWidth; 1379 origMaxHeight = maxHeight; 1380 1381 if (current.fitToView) { 1382 maxWidth = Math.min(viewport.w - wSpace, maxWidth); 1383 maxHeight = Math.min(viewport.h - hSpace, maxHeight); 1384 } 1385 1386 maxWidth_ = viewport.w - wMargin; 1387 maxHeight_ = viewport.h - hMargin; 1388 1389 if (current.aspectRatio) { 1390 if (width > maxWidth) { 1391 width = maxWidth; 1392 height = getScalar(width / ratio); 1393 } 1394 1395 if (height > maxHeight) { 1396 height = maxHeight; 1397 width = getScalar(height * ratio); 1398 } 1399 1400 if (width < minWidth) { 1401 width = minWidth; 1402 height = getScalar(width / ratio); 1403 } 1404 1405 if (height < minHeight) { 1406 height = minHeight; 1407 width = getScalar(height * ratio); 1408 } 1409 } 1410 else { 1411 width = Math.max(minWidth, Math.min(width, maxWidth)); 1412 1413 if (current.autoHeight && current.type !== 'iframe') { 1414 inner.width( width ); 1415 1416 height = inner.height(); 1417 } 1418 1419 height = Math.max(minHeight, Math.min(height, maxHeight)); 1420 } 1421 1422 // Try to fit inside viewport (including the title) 1423 if (current.fitToView) { 1424 inner.width( width ).height( height ); 1425 1426 wrap.width( width + wPadding ); 1427 1428 // Real wrap dimensions 1429 width_ = wrap.width(); 1430 height_ = wrap.height(); 1431 1432 if (current.aspectRatio) { 1433 while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) { 1434 if (steps++ > 19) { 1435 break; 1436 } 1437 1438 height = Math.max(minHeight, Math.min(maxHeight, height - 10)); 1439 width = getScalar(height * ratio); 1440 1441 if (width < minWidth) { 1442 width = minWidth; 1443 height = getScalar(width / ratio); 1444 } 1445 1446 if (width > maxWidth) { 1447 width = maxWidth; 1448 height = getScalar(width / ratio); 1449 } 1450 1451 inner.width( width ).height( height ); 1452 1453 wrap.width( width + wPadding ); 1454 1455 width_ = wrap.width(); 1456 height_ = wrap.height(); 1457 } 1458 } 1459 else { 1460 width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_))); 1461 height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_))); 1462 } 1463 } 1464 1465 if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) { 1466 width += scrollOut; 1467 } 1468 1469 inner.width( width ).height( height ); 1470 1471 wrap.width( width + wPadding ); 1472 1473 width_ = wrap.width(); 1474 height_ = wrap.height(); 1475 1476 canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight; 1477 canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight)); 1478 1479 $.extend(current, { 1480 dim : { 1481 width : getValue( width_ ), 1482 height : getValue( height_ ) 1483 }, 1484 origWidth : origWidth, 1485 origHeight : origHeight, 1486 canShrink : canShrink, 1487 canExpand : canExpand, 1488 wPadding : wPadding, 1489 hPadding : hPadding, 1490 wrapSpace : height_ - skin.outerHeight(true), 1491 skinSpace : skin.height() - height 1492 }); 1493 1494 if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) { 1495 inner.height('auto'); 1496 } 1497 }, 1498 1499 _getPosition: function (onlyAbsolute) { 1500 var current = F.current, 1501 viewport = F.getViewport(), 1502 margin = current.margin, 1503 width = F.wrap.width() + margin[1] + margin[3], 1504 height = F.wrap.height() + margin[0] + margin[2], 1505 rez = { 1506 position: 'absolute', 1507 top : margin[0], 1508 left : margin[3] 1509 }; 1510 1511 if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) { 1512 rez.position = 'fixed'; 1513 } 1514 else if (!current.locked) { 1515 rez.top += viewport.y; 1516 rez.left += viewport.x; 1517 } 1518 1519 rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))); 1520 rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio))); 1521 1522 return rez; 1523 }, 1524 1525 _afterZoomIn: function () { 1526 var current = F.current; 1527 1528 if (!current) { 1529 return; 1530 } 1531 1532 F.isOpen = F.isOpened = true; 1533 1534 F.wrap.css('overflow', 'visible').addClass('fancybox-opened').hide().show(0); 1535 1536 F.update(); 1537 1538 // Assign a click event 1539 if ( current.zoomClick || current.closeClick || (current.nextClick && F.group.length > 1) ) { 1540 F.inner.css('cursor', !current.zoomClick ? 'pointer' : (current.canExpand ? 'zoom-in' : 'zoom-out')).on('click.fb', function(e) { 1541 if (!$(e.target).is('a') && !$(e.target).parent().is('a')) { 1542 e.preventDefault(); 1543 1544 F[ current.zoomClick && (current.canExpand || current.canShrink) ? 'toggle' : ( current.closeClick ? 'close' : 'next' ) ](); 1545 } 1546 }); 1547 } 1548 1549 // Create a close button 1550 if (current.closeBtn) { 1551 $(current.tpl.close.replace(/\{close\}/g, current.txt.close)).appendTo(F.skin).on('click.fb touchend', function(e) { 1552 e.preventDefault(); 1553 F.close(); 1554 }); 1555 } 1556 1557 // Create navigation arrows 1558 if (current.arrows && F.group.length > 1) { 1559 if (current.loop || current.index > 0) { 1560 $(current.tpl.prev.replace(/\{prev\}/g, current.txt.prev)).appendTo(F.outer).on('click.fb touchend', F.prev); 1561 } 1562 1563 if (current.loop || current.index < F.group.length - 1) { 1564 $(current.tpl.next.replace(/\{next\}/g, current.txt.next)).appendTo(F.outer).on('click.fb touchend', F.next); 1565 } 1566 } 1567 1568 F.trigger('afterShow'); 1569 1570 // Stop the slideshow if this is the last item 1571 if (!current.loop && current.index === current.group.length - 1) { 1572 1573 F.play( false ); 1574 } 1575 else if (F.opts.autoPlay && !F.player.isActive) { 1576 F.opts.autoPlay = false; 1577 1578 F.play(true); 1579 } 1580 }, 1581 1582 _afterZoomOut: function ( obj ) { 1583 obj = obj || F.current; 1584 1585 $('.fancybox-wrap').trigger('onReset').remove(); 1586 1587 $.extend(F, { 1588 group : {}, 1589 opts : {}, 1590 router : false, 1591 current : null, 1592 isActive : false, 1593 isOpened : false, 1594 isOpen : false, 1595 isClosing : false, 1596 wrap : null, 1597 skin : null, 1598 outer : null, 1599 inner : null 1600 }); 1601 1602 F.trigger('afterClose', obj); 1603 } 1604 }); 1605 1606 /* 1607 * Default transitions 1608 */ 1609 1610 F.transitions = { 1611 getOrigPosition: function () { 1612 var current = F.current, 1613 element = current.element, 1614 orig = current.orig, 1615 pos = {}, 1616 width = 50, 1617 height = 50, 1618 hPadding = current.hPadding, 1619 wPadding = current.wPadding, 1620 viewport = F.getViewport(); 1621 1622 if (!orig && current.isDom && element.is(':visible')) { 1623 orig = element.find('img:first'); 1624 1625 if (!orig.length) { 1626 orig = element; 1627 } 1628 } 1629 1630 if (isQuery(orig)) { 1631 pos = orig.offset(); 1632 1633 if (orig.is('img')) { 1634 width = orig.outerWidth(); 1635 height = orig.outerHeight(); 1636 } 1637 } 1638 else { 1639 pos.top = viewport.y + (viewport.h - height) * current.topRatio; 1640 pos.left = viewport.x + (viewport.w - width) * current.leftRatio; 1641 } 1642 1643 if (F.wrap.css('position') === 'fixed' || current.locked) { 1644 pos.top -= viewport.y; 1645 pos.left -= viewport.x; 1646 } 1647 1648 pos = { 1649 top : getValue(pos.top - hPadding * current.topRatio), 1650 left : getValue(pos.left - wPadding * current.leftRatio), 1651 width : getValue(width + wPadding), 1652 height : getValue(height + hPadding) 1653 }; 1654 1655 return pos; 1656 }, 1657 1658 step: function (now, fx) { 1659 var ratio, 1660 padding, 1661 value, 1662 prop = fx.prop, 1663 current = F.current, 1664 wrapSpace = current.wrapSpace, 1665 skinSpace = current.skinSpace; 1666 1667 if (prop === 'width' || prop === 'height') { 1668 ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start); 1669 1670 if (F.isClosing) { 1671 ratio = 1 - ratio; 1672 } 1673 1674 padding = prop === 'width' ? current.wPadding : current.hPadding; 1675 value = now - padding; 1676 1677 F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) ); 1678 F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) ); 1679 } 1680 }, 1681 1682 zoomIn: function () { 1683 var current = F.current, 1684 startPos = current.pos, 1685 effect = current.openEffect, 1686 elastic = effect === 'elastic', 1687 endPos = $.extend({opacity : 1}, startPos); 1688 1689 // Remove "position" property that breaks older IE 1690 delete endPos.position; 1691 1692 if (elastic) { 1693 startPos = this.getOrigPosition(); 1694 1695 if (current.openOpacity) { 1696 startPos.opacity = 0.1; 1697 } 1698 } 1699 else if (effect === 'fade') { 1700 startPos.opacity = 0.1; 1701 } 1702 1703 F.wrap.css(startPos).animate(endPos, { 1704 duration : effect === 'none' ? 0 : current.openSpeed, 1705 easing : current.openEasing, 1706 step : elastic ? this.step : null, 1707 complete : F._afterZoomIn 1708 }); 1709 }, 1710 1711 zoomOut: function () { 1712 var current = F.current, 1713 effect = current.closeEffect, 1714 elastic = effect === 'elastic', 1715 endPos = {opacity : 0.1}; 1716 1717 if (elastic) { 1718 endPos = this.getOrigPosition(); 1719 1720 if (current.closeOpacity) { 1721 endPos.opacity = 0.1; 1722 } 1723 } 1724 1725 F.wrap.animate(endPos, { 1726 duration : effect === 'none' ? 0 : current.closeSpeed, 1727 easing : current.closeEasing, 1728 step : elastic ? this.step : null, 1729 complete : F._afterZoomOut 1730 }); 1731 }, 1732 1733 changeIn: function () { 1734 var current = F.current, 1735 effect = current.nextEffect, 1736 startPos = current.pos, 1737 endPos = { opacity : 1 }, 1738 direction = F.direction, 1739 distance = 200, 1740 field; 1741 1742 startPos.opacity = 0.1; 1743 1744 if (effect === 'elastic') { 1745 field = direction === 'down' || direction === 'up' ? 'top' : 'left'; 1746 1747 if (direction === 'down' || direction === 'right') { 1748 startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance); 1749 endPos[ field ] = '+=' + distance + 'px'; 1750 } 1751 else { 1752 startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance); 1753 endPos[ field ] = '-=' + distance + 'px'; 1754 } 1755 } 1756 1757 // Workaround for http://bugs.jquery.com/ticket/12273 1758 if (effect === 'none') { 1759 F._afterZoomIn(); 1760 } 1761 else { 1762 F.wrap.css(startPos).animate(endPos, { 1763 duration : current.nextSpeed, 1764 easing : current.nextEasing, 1765 complete : F._afterZoomIn 1766 }); 1767 } 1768 }, 1769 1770 changeOut: function () { 1771 var previous = F.previous, 1772 effect = previous.prevEffect, 1773 endPos = { opacity : 0.1 }, 1774 direction = F.direction, 1775 distance = 200; 1776 1777 if (effect === 'elastic') { 1778 endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px'; 1779 } 1780 1781 previous.wrap.animate(endPos, { 1782 duration : effect === 'none' ? 0 : previous.prevSpeed, 1783 easing : previous.prevEasing, 1784 complete : function () { 1785 $(this).trigger('onReset').remove(); 1786 } 1787 }); 1788 } 1789 }; 1790 1791 /* 1792 * Overlay helper 1793 */ 1794 1795 F.helpers.overlay = { 1796 defaults : { 1797 closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay 1798 speedOut : 200, // duration of fadeOut animation 1799 showEarly : true, // indicates if should be opened immediately or wait until the content is ready 1800 css : {}, // custom CSS properties 1801 locked : !isTouch, // if true, the content will be locked into overlay 1802 fixed : true // if false, the overlay CSS position property will not be set to "fixed" 1803 }, 1804 1805 overlay : null, // current handle 1806 fixed : false, // indicates if the overlay has position "fixed" 1807 el : $('html'), // element that contains "the lock" 1808 1809 // Public methods 1810 create : function(opts) { 1811 var parent; 1812 1813 opts = $.extend({}, this.defaults, opts); 1814 1815 if (this.overlay) { 1816 this.close(); 1817 } 1818 1819 parent = F.coming ? F.coming.parent : opts.parent; 1820 1821 this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( parent && parent.length ? parent : 'body' ); 1822 this.fixed = false; 1823 1824 if (opts.fixed && F.defaults.fixed) { 1825 this.overlay.addClass('fancybox-overlay-fixed'); 1826 1827 this.fixed = true; 1828 } 1829 }, 1830 1831 open : function(opts) { 1832 var that = this; 1833 1834 opts = $.extend({}, this.defaults, opts); 1835 1836 if (this.overlay) { 1837 this.overlay.off('.overlay').width('auto').height('auto'); 1838 } 1839 else { 1840 this.create(opts); 1841 } 1842 1843 if (!this.fixed) { 1844 W.on('resize.overlay', $.proxy( this.update, this) ); 1845 1846 this.update(); 1847 } 1848 1849 if (opts.closeClick) { 1850 this.overlay.on('click.overlay', function(e) { 1851 if ($(e.target).hasClass('fancybox-overlay')) { 1852 if (F.isActive) { 1853 F.close(); 1854 } 1855 else { 1856 that.close(); 1857 } 1858 return false; 1859 } 1860 }); 1861 } 1862 1863 this.overlay.css( opts.css ).show(); 1864 }, 1865 1866 close : function() { 1867 W.off('resize.overlay'); 1868 1869 if (this.el.hasClass('fancybox-lock')) { 1870 $('.fancybox-margin').removeClass('fancybox-margin'); 1871 1872 this.el.removeClass('fancybox-lock'); 1873 1874 W.scrollTop( this.scrollV ).scrollLeft( this.scrollH ); 1875 } 1876 1877 $('.fancybox-overlay').remove().hide(); 1878 1879 $.extend(this, { 1880 overlay : null, 1881 fixed : false 1882 }); 1883 }, 1884 1885 // Private, callbacks 1886 1887 update : function () { 1888 var width = '100%', offsetWidth; 1889 1890 // Reset width/height so it will not mess 1891 this.overlay.width(width).height('100%'); 1892 1893 // jQuery does not return reliable result for IE 1894 if (IE) { 1895 offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth); 1896 1897 if (D.width() > offsetWidth) { 1898 width = D.width(); 1899 } 1900 } 1901 else if (D.width() > W.width()) { 1902 width = D.width(); 1903 } 1904 1905 this.overlay.width(width).height(D.height()); 1906 }, 1907 1908 // This is where we can manipulate DOM, because later it would cause iframes to reload 1909 onReady : function (opts, obj) { 1910 var overlay = this.overlay; 1911 1912 $('.fancybox-overlay').stop(true, true); 1913 1914 if (!overlay) { 1915 this.create(opts); 1916 } 1917 1918 if (opts.locked && this.fixed && obj.fixed) { 1919 obj.locked = this.overlay.append( obj.wrap ); 1920 obj.fixed = false; 1921 } 1922 1923 if (opts.showEarly === true) { 1924 this.beforeShow.apply(this, arguments); 1925 } 1926 }, 1927 1928 beforeShow : function(opts, obj) { 1929 if (obj.locked && !this.el.hasClass('fancybox-lock')) { 1930 if (this.fixPosition !== false) { 1931 $('*:not(object)').filter(function(){ 1932 return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") ); 1933 }).addClass('fancybox-margin'); 1934 } 1935 1936 this.el.addClass('fancybox-margin'); 1937 1938 this.scrollV = W.scrollTop(); 1939 this.scrollH = W.scrollLeft(); 1940 1941 this.el.addClass('fancybox-lock'); 1942 1943 W.scrollTop( this.scrollV ).scrollLeft( this.scrollH ); 1944 } 1945 1946 this.open(opts); 1947 }, 1948 1949 // afterShow: function (opts) { 1950 // // Prevent background scrolling. 1951 // $("html, body").css("overflow","hidden"); 1952 // }, 1953 1954 onUpdate : function() { 1955 if (!this.fixed) { 1956 this.update(); 1957 } 1958 }, 1959 1960 afterClose: function (opts) { 1961 // Undo prevent background scrolling. 1962 // $("html, body").css("overflow","auto"); 1963 // Remove overlay if exists and fancyBox is not opening 1964 // (e.g., it is not being open using afterClose callback) 1965 if (this.overlay && !F.coming) { 1966 this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this )); 1967 } 1968 } 1969 }; 1970 1971 /* 1972 * Title helper 1973 */ 1974 1975 F.helpers.title = { 1976 defaults : { 1977 type : 'float', // 'float', 'inside', 'outside' or 'over', 1978 position : 'bottom' // 'top' or 'bottom' 1979 }, 1980 1981 beforeShow: function (opts) { 1982 var current = F.current, 1983 text = current.title, 1984 type = opts.type, 1985 title, 1986 target; 1987 1988 if ($.isFunction(text)) { 1989 text = text.call(current.element, current); 1990 } 1991 1992 if (!isString(text) || $.trim(text) === '') { 1993 return; 1994 } 1995 1996 title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">' + DOMPurify.sanitize(text) + '</div>'); 1997 1998 switch (type) { 1999 case 'inside': 2000 target = F.skin; 2001 break; 2002
vendor: 3,314 bytes, lines 2003-2131
2003 case 'outside': 2004 target = F.wrap; 2005 break; 2006 2007 case 'over': 2008 target = F.inner; 2009 break; 2010 2011 default: // 'float' 2012 target = F.skin; 2013 2014 title.appendTo('body'); 2015 2016 if (IE) { 2017 title.width( title.width() ); 2018 } 2019 2020 title.wrapInner('<span class="child"></span>'); 2021 2022 //Increase bottom margin so this title will also fit into viewport 2023 F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) ); 2024 break; 2025 } 2026 2027 title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target); 2028 } 2029 }; 2030 2031 // jQuery plugin initialization 2032 $.fn.fancybox = function (options) { 2033 var index, 2034 that = $(this), 2035 selector = this.selector || '', 2036 run = function(e) { 2037 var what = $(this).blur(), idx = index, relType, relVal; 2038 2039 if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) { 2040 relType = options.groupAttr || 'data-fancybox-group'; 2041 relVal = what.attr(relType); 2042 2043 if (!relVal) { 2044 relType = 'rel'; 2045 relVal = what.get(0)[ relType ]; 2046 } 2047 2048 if (relVal && relVal !== '' && relVal !== 'nofollow') { 2049 what = selector.length ? $(selector) : that; 2050 what = what.filter('[' + relType + '="' + relVal + '"]'); 2051 idx = what.index(this); 2052 } 2053 2054 options.index = idx; 2055 2056 // Abort if not enough screen space 2057 var viewport = F.getViewport(); 2058 if ( (options.minVpWidth && viewport.w < options.minVpWidth) || (options.minVpHeight && viewport.h < options.minVpHeight) ) { 2059 return; 2060 } 2061 2062 // Stop an event from bubbling if everything is fine 2063 if (F.open(what, options) !== false) { 2064 e.preventDefault(); 2065 return false; 2066 } 2067 } 2068 }; 2069 2070 options = options || {}; 2071 index = options.index || 0; 2072 2073 if (!selector || options.live === false) { 2074 that.off('click.fb-start').on('click.fb-start', run); 2075 } 2076 else { 2077 D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); 2078 } 2079 2080 this.filter('[data-fancybox-start=1]').trigger('click'); 2081 2082 return this; 2083 }; 2084 2085 // Tests that need a body at doc ready 2086 D.ready(function() { 2087 var w1, w2; 2088 2089 if ( $.scrollbarWidth === undefined ) { 2090 // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth 2091 $.scrollbarWidth = function() { 2092 var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'), 2093 child = parent.children(), 2094 width = child.innerWidth() - child.height( 99 ).innerWidth(); 2095 2096 parent.remove(); 2097 2098 return width; 2099 }; 2100 } 2101 2102 if ( $.support.fixedPosition === undefined ) { 2103 $.support.fixedPosition = (function() { 2104 var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'), 2105 fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 ); 2106 2107 elem.remove(); 2108 2109 return fixed; 2110 }()); 2111 } 2112 2113 $.extend(F.defaults, { 2114 scrollbarWidth : $.scrollbarWidth(), 2115 fixed : $.support.fixedPosition, 2116 parent : $('body') 2117 }); 2118 2119 //Get real width of page scroll-bar 2120 w1 = $(window).width(); 2121 2122 H.addClass('fancybox-lock-test'); 2123 2124 w2 = $(window).width(); 2125 2126 H.removeClass('fancybox-lock-test'); 2127 2128 $("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head"); 2129 }); 2130 2131}(window, document, 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.