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