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