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