annotate static/js/fancybox2/source/jquery.fancybox.js @ 112:4bd65fe0911f

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