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