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