Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: fancybox/source/jquery.fancybox.js

Issue 8615139: adblockpluschrome: Open share page in lightbox (Closed)
Patch Set: Created Oct. 23, 2012, 4:12 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*!
2 * fancyBox - jQuery Plugin
3 * version: 2.1.2 (Mon, 15 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 - janis@fancyapps.com
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.clie ntHeight && 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.2',
52
53 defaults: {
54 padding : 15,
55 margin : 20,
56
57 width : 800,
58 height : 600,
59 minWidth : 100,
60 minHeight : 100,
61 maxWidth : 9999,
62 maxHeight : 9999,
63
64 autoSize : true,
65 autoHeight : false,
66 autoWidth : false,
67
68 autoResize : true,
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="{hr ef}" alt="" />',
139 iframe : '<iframe id="fancybox-frame{rnd}" nam e="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspac e="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + ($.browser.msi e ? ' allowtransparency="true"' : '') + '></iframe>',
140 error : '<p class="fancybox-error">The reques ted content cannot be loaded.<br/>Please try again later.</p>',
141 closeBtn : '<a title="Close" class="fancybox-ite m fancybox-close" href="javascript:;"></a>',
142 next : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
143 prev : '<a title="Previous" class="fancybox- nav fancybox-prev" href="javascript:;"><span></span></a>'
144 },
145
146 // Properties for each animation type
147 // Opening fancyBox
148 openEffect : 'fade', // 'elastic', 'fade' or 'none'
149 openSpeed : 250,
150 openEasing : 'swing',
151 openOpacity : true,
152 openMethod : 'zoomIn',
153
154 // Closing fancyBox
155 closeEffect : 'fade', // 'elastic', 'fade' or 'none'
156 closeSpeed : 250,
157 closeEasing : 'swing',
158 closeOpacity : true,
159 closeMethod : 'zoomOut',
160
161 // Changing next gallery item
162 nextEffect : 'elastic', // 'elastic', 'fade' or 'none'
163 nextSpeed : 250,
164 nextEasing : 'swing',
165 nextMethod : 'changeIn',
166
167 // Changing previous gallery item
168 prevEffect : 'elastic', // 'elastic', 'fade' or 'none'
169 prevSpeed : 250,
170 prevEasing : 'swing',
171 prevMethod : 'changeOut',
172
173 // 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 ite m
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
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 s et 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, elem ent.metadata());
268 }
269
270 } else {
271 obj = element;
272 }
273 }
274
275 href = opts.href || obj.href || (isString(elem ent) ? 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').mat ch(/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 "/myp age.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(hr ef) ? 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.default s.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 = nul l;
377 }
378
379 // If the first item has been canceled, then clear every thing
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 ope ning/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-op ened');
413
414 F.transitions[ F.current.closeMethod ]();
415 }
416 },
417
418 // Manage slideshow:
419 // $.fancybox.play(); - toggle slideshow
420 // $.fancybox.play( true ); - start
421 // $.fancybox.play( false ); - stop
422 play: function ( action ) {
423 var clear = function () {
424 clearTimeout(F.player.timer);
425 },
426 set = function () {
427 clear();
428
429 if (F.current && F.player.isActive) {
430 F.player.timer = setTimeout(F.ne xt, F.current.playSpeed);
431 }
432 },
433 stop = function () {
434 clear();
435
436 $('body').unbind('.player');
437
438 F.player.isActive = false;
439
440 F.trigger('onPlayEnd');
441 },
442 start = function () {
443 if (F.current && (F.current.loop || F.cu rrent.index < F.group.length - 1)) {
444 F.player.isActive = true;
445
446 $('body').bind({
447 'afterShow.player onUpda te.player' : set,
448 'onCancel.player beforeC lose.player' : stop,
449 'beforeLoad.player' : cl ear
450 });
451
452 set();
453
454 F.trigger('onPlayStart');
455 }
456 };
457
458 if (action === true || (!F.player.isActive && action !== false)) {
459 start();
460 } else {
461 stop();
462 }
463 },
464
465 // Navigate to next gallery item
466 next: function ( direction ) {
467 var current = F.current;
468
469 if (current) {
470 if (!isString(direction)) {
471 direction = current.direction.next;
472 }
473
474 F.jumpto(current.index + 1, direction, 'next');
475 }
476 },
477
478 // Navigate to previous gallery item
479 prev: function ( direction ) {
480 var current = F.current;
481
482 if (current) {
483 if (!isString(direction)) {
484 direction = current.direction.prev;
485 }
486
487 F.jumpto(current.index - 1, direction, 'prev');
488 }
489 },
490
491 // Navigate to gallery item by index
492 jumpto: function ( index, direction, router ) {
493 var current = F.current;
494
495 if (!current) {
496 return;
497 }
498
499 index = getScalar(index);
500
501 F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];
502 F.router = router || 'jumpto';
503
504 if (current.loop) {
505 if (index < 0) {
506 index = current.group.length + (index % current.group.length);
507 }
508
509 index = index % current.group.length;
510 }
511
512 if (current.group[ index ] !== undefined) {
513 F.cancel();
514
515 F._start(index);
516 }
517 },
518
519 // Center inside viewport and toggle position type to fixed or a bsolute if needed
520 reposition: function (e, onlyAbsolute) {
521 var current = F.current,
522 wrap = current ? current.wrap : null,
523 pos;
524
525 if (wrap) {
526 pos = F._getPosition(onlyAbsolute);
527
528 if (e && e.type === 'scroll') {
529 delete pos.position;
530
531 wrap.stop(true, true).animate(pos, 200);
532
533 } else {
534 wrap.css(pos);
535
536 current.pos = $.extend({}, current.dim, 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 didUpdate = setTimeout(function() {
556 var current = F.current;
557
558 if (!current || F.isClosing) {
559 return;
560 }
561
562 F.wrap.removeClass('fancybox-tmp');
563
564 if (type !== 'scroll') {
565 F._setDimension();
566 }
567
568 if (!(type === 'scroll' && current.canShrink)) {
569 F.reposition(e);
570 }
571
572 F.trigger('onUpdate');
573
574 didUpdate = null;
575
576 }, (anyway && !isTouch ? 0 : 300));
577 },
578
579 // Shrink content to fit inside viewport or restore if resized
580 toggle: function ( action ) {
581 if (F.isOpen) {
582 F.current.fitToView = $.type(action) === "boolea n" ? action : !F.current.fitToView;
583
584 // Help browser to restore document dimensions
585 if (isTouch) {
586 F.wrap.removeAttr('style').addClass('fan cybox-tmp');
587
588 F.trigger('onUpdate');
589 }
590
591 F.update();
592 }
593 },
594
595 hideLoading: function () {
596 D.unbind('.loading');
597
598 $('#fancybox-loading').remove();
599 },
600
601 showLoading: function () {
602 var el, viewport;
603
604 F.hideLoading();
605
606 el = $('<div id="fancybox-loading"><div></div></div>').c lick(F.cancel).appendTo('body');
607
608 // If user will press the escape-button, the request wil l be canceled
609 D.bind('keydown.loading', function(e) {
610 if ((e.which || e.keyCode) === 27) {
611 F.cancel();
612 }
613 });
614
615 if (!F.defaults.fixed) {
616 viewport = F.getViewport();
617
618 el.css({
619 position : 'absolute',
620 top : (viewport.h * 0.5) + viewport.y,
621 left : (viewport.w * 0.5) + viewport.x
622 });
623 }
624 },
625
626 getViewport: function () {
627 var locked = (F.current && F.current.locked) || false,
628 rez = {
629 x: W.scrollLeft(),
630 y: W.scrollTop()
631 };
632
633 if (locked) {
634 rez.w = locked[0].clientWidth;
635 rez.h = locked[0].clientHeight;
636
637 } else {
638 // See http://bugs.jquery.com/ticket/6724
639 rez.w = isTouch && window.innerWidth ? window.i nnerWidth : W.width();
640 rez.h = isTouch && window.innerHeight ? window.i nnerHeight : W.height();
641 }
642
643 return rez;
644 },
645
646 // Unbind the keyboard / clicking actions
647 unbindEvents: function () {
648 if (F.wrap && isQuery(F.wrap)) {
649 F.wrap.unbind('.fb');
650 }
651
652 D.unbind('.fb');
653 W.unbind('.fb');
654 },
655
656 bindEvents: function () {
657 var current = F.current,
658 keys;
659
660 if (!current) {
661 return;
662 }
663
664 // Changing document height on iOS devices triggers a 'r esize' event,
665 // that can change document height... repeating infinite ly
666 W.bind('orientationchange.fb' + (isTouch ? '' : ' resize .fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);
667
668 keys = current.keys;
669
670 if (keys) {
671 D.bind('keydown.fb', function (e) {
672 var code = e.which || e.keyCode,
673 target = e.target || e.srcElemen t;
674
675 // Skip esc key if loading, because show Loading will cancel preloading
676 if (code === 27 && F.coming) {
677 return false;
678 }
679
680 // Ignore key combinations and key event s within form elements
681 if (!e.ctrlKey && !e.altKey && !e.shiftK ey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]' )))) {
682 $.each(keys, function(i, val) {
683 if (current.group.length > 1 && val[ code ] !== undefined) {
684 F[ i ]( val[ cod e ] );
685
686 e.preventDefault ();
687 return false;
688 }
689
690 if ($.inArray(code, val) > -1) {
691 F[ i ] ();
692
693 e.preventDefault ();
694 return false;
695 }
696 });
697 }
698 });
699 }
700
701 if ($.fn.mousewheel && current.mouseWheel) {
702 F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {
703 var target = e.target || null,
704 parent = $(target),
705 canScroll = false;
706
707 while (parent.length) {
708 if (canScroll || parent.is('.fan cybox-skin') || parent.is('.fancybox-wrap')) {
709 break;
710 }
711
712 canScroll = isScrollable( parent [0] );
713 parent = $(parent).parent();
714 }
715
716 if (delta !== 0 && !canScroll) {
717 if (F.group.length > 1 && !curre nt.canShrink) {
718 if (deltaY > 0 || deltaX > 0) {
719 F.prev( deltaY > 0 ? 'down' : 'left' );
720
721 } else if (deltaY < 0 || deltaX < 0) {
722 F.next( deltaY < 0 ? 'up' : 'right' );
723 }
724
725 e.preventDefault();
726 }
727 }
728 });
729 }
730 },
731
732 trigger: function (event, o) {
733 var ret, obj = o || F.coming || F.current;
734
735 if (!obj) {
736 return;
737 }
738
739 if ($.isFunction( obj[event] )) {
740 ret = obj[event].apply(obj, Array.prototype.slic e.call(arguments, 1));
741 }
742
743 if (ret === false) {
744 return false;
745 }
746
747 if (event === 'onCancel' && !F.isOpened) {
748 F.isActive = false;
749 }
750
751 if (obj.helpers) {
752 $.each(obj.helpers, function (helper, opts) {
753 if (opts && F.helpers[helper] && $.isFun ction(F.helpers[helper][event])) {
754 opts = $.extend(true, {}, F.help ers[helper].defaults, opts);
755
756 F.helpers[helper][event](opts, o bj);
757 }
758 });
759 }
760
761 $.event.trigger(event + '.fb');
762 },
763
764 isImage: function (str) {
765 return isString(str) && str.match(/(^data:image\/.*,)|(\ .(jp(e|g|eg)|gif|png|bmp|webp)((\?|#).*)?$)/i);
766 },
767
768 isSWF: function (str) {
769 return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i );
770 },
771
772 _start: function (index) {
773 var coming = {},
774 obj,
775 href,
776 type,
777 margin,
778 padding;
779
780 index = getScalar( index );
781 obj = F.group[ index ] || null;
782
783 if (!obj) {
784 return false;
785 }
786
787 coming = $.extend(true, {}, F.opts, obj);
788
789 // Convert margin and padding properties to array - top, right, bottom, left
790 margin = coming.margin;
791 padding = coming.padding;
792
793 if ($.type(margin) === 'number') {
794 coming.margin = [margin, margin, margin, margin] ;
795 }
796
797 if ($.type(padding) === 'number') {
798 coming.padding = [padding, padding, padding, pad ding];
799 }
800
801 // 'modal' propery is just a shortcut
802 if (coming.modal) {
803 $.extend(true, coming, {
804 closeBtn : false,
805 closeClick : false,
806 nextClick : false,
807 arrows : false,
808 mouseWheel : false,
809 keys : null,
810 helpers: {
811 overlay : {
812 closeClick : false
813 }
814 }
815 });
816 }
817
818 // 'autoSize' property is a shortcut, too
819 if (coming.autoSize) {
820 coming.autoWidth = coming.autoHeight = true;
821 }
822
823 if (coming.width === 'auto') {
824 coming.autoWidth = true;
825 }
826
827 if (coming.height === 'auto') {
828 coming.autoHeight = true;
829 }
830
831 /*
832 * Add reference to the group, so it`s possible to acces s from callbacks, example:
833 * afterLoad : function() {
834 * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
835 * }
836 */
837
838 coming.group = F.group;
839 coming.index = index;
840
841 // Give a chance for callback or helpers to update comin g item (type, title, etc)
842 F.coming = coming;
843
844 if (false === F.trigger('beforeLoad')) {
845 F.coming = null;
846
847 return;
848 }
849
850 type = coming.type;
851 href = coming.href;
852
853 if (!type) {
854 F.coming = null;
855
856 //If we can not determine content type then drop silently or display next/prev item if looping through gallery
857 if (F.current && F.router && F.router !== 'jumpt o') {
858 F.current.index = index;
859
860 return F[ F.router ]( F.direction );
861 }
862
863 return false;
864 }
865
866 F.isActive = true;
867
868 if (type === 'image' || type === 'swf') {
869 coming.autoHeight = coming.autoWidth = false;
870 coming.scrolling = 'visible';
871 }
872
873 if (type === 'image') {
874 coming.aspectRatio = true;
875 }
876
877 if (type === 'iframe' && isTouch) {
878 coming.scrolling = 'scroll';
879 }
880
881 // Build the neccessary markup
882 coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );
883
884 $.extend(coming, {
885 skin : $('.fancybox-skin', coming.wrap),
886 outer : $('.fancybox-outer', coming.wrap),
887 inner : $('.fancybox-inner', coming.wrap)
888 });
889
890 $.each(["Top", "Right", "Bottom", "Left"], function(i, v ) {
891 coming.skin.css('padding' + v, getValue(coming.p adding[ i ]));
892 });
893
894 F.trigger('onReady');
895
896 // Check before try to load; 'inline' and 'html' types n eed content, others - href
897 if (type === 'inline' || type === 'html') {
898 if (!coming.content || !coming.content.length) {
899 return F._error( 'content' );
900 }
901
902 } else if (!href) {
903 return F._error( 'href' );
904 }
905
906 if (type === 'image') {
907 F._loadImage();
908
909 } else if (type === 'ajax') {
910 F._loadAjax();
911
912 } else if (type === 'iframe') {
913 F._loadIframe();
914
915 } else {
916 F._afterLoad();
917 }
918 },
919
920 _error: function ( type ) {
921 $.extend(F.coming, {
922 type : 'html',
923 autoWidth : true,
924 autoHeight : true,
925 minWidth : 0,
926 minHeight : 0,
927 scrolling : 'no',
928 hasError : type,
929 content : F.coming.tpl.error
930 });
931
932 F._afterLoad();
933 },
934
935 _loadImage: function () {
936 // Reset preload image so it is later possible to check "complete" property
937 var img = F.imgPreload = new Image();
938
939 img.onload = function () {
940 this.onload = this.onerror = null;
941
942 F.coming.width = this.width;
943 F.coming.height = this.height;
944
945 F._afterLoad();
946 };
947
948 img.onerror = function () {
949 this.onload = this.onerror = null;
950
951 F._error( 'image' );
952 };
953
954 img.src = F.coming.href;
955
956 if (img.complete !== true) {
957 F.showLoading();
958 }
959 },
960
961 _loadAjax: function () {
962 var coming = F.coming;
963
964 F.showLoading();
965
966 F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
967 url: coming.href,
968 error: function (jqXHR, textStatus) {
969 if (F.coming && textStatus !== 'abort') {
970 F._error( 'ajax', jqXHR );
971
972 } else {
973 F.hideLoading();
974 }
975 },
976 success: function (data, textStatus) {
977 if (textStatus === 'success') {
978 coming.content = data;
979
980 F._afterLoad();
981 }
982 }
983 }));
984 },
985
986 _loadIframe: function() {
987 var coming = F.coming,
988 iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))
989 .attr('scrolling', isTouch ? 'auto' : co ming.iframe.scrolling)
990 .attr('src', coming.href);
991
992 // This helps IE
993 $(coming.wrap).bind('onReset', function () {
994 try {
995 $(this).find('iframe').hide().attr('src' , '//about:blank').end().empty();
996 } catch (e) {}
997 });
998
999 if (coming.iframe.preload) {
1000 F.showLoading();
1001
1002 iframe.one('load', function() {
1003 $(this).data('ready', 1);
1004
1005 // iOS will lose scrolling if we resize
1006 if (!isTouch) {
1007 $(this).bind('load.fb', F.update );
1008 }
1009
1010 // Without this trick:
1011 // - iframe won't scroll on iOS device s
1012 // - IE7 sometimes displays empty ifra me
1013 $(this).parents('.fancybox-wrap').width( '100%').removeClass('fancybox-tmp').show();
1014
1015 F._afterLoad();
1016 });
1017 }
1018
1019 coming.content = iframe.appendTo( coming.inner );
1020
1021 if (!coming.iframe.preload) {
1022 F._afterLoad();
1023 }
1024 },
1025
1026 _preloadImages: function() {
1027 var group = F.group,
1028 current = F.current,
1029 len = group.length,
1030 cnt = current.preload ? Math.min(current.pre load, len - 1) : 0,
1031 item,
1032 i;
1033
1034 for (i = 1; i <= cnt; i += 1) {
1035 item = group[ (current.index + i ) % len ];
1036
1037 if (item.type === 'image' && item.href) {
1038 new Image().src = item.href;
1039 }
1040 }
1041 },
1042
1043 _afterLoad: function () {
1044 var coming = F.coming,
1045 previous = F.current,
1046 placeholder = 'fancybox-placeholder',
1047 current,
1048 content,
1049 type,
1050 scrolling,
1051 href,
1052 embed;
1053
1054 F.hideLoading();
1055
1056 if (!coming || F.isActive === false) {
1057 return;
1058 }
1059
1060 if (false === F.trigger('afterLoad', coming, previous)) {
1061 coming.wrap.stop(true).trigger('onReset').remove ();
1062
1063 F.coming = null;
1064
1065 return;
1066 }
1067
1068 if (previous) {
1069 F.trigger('beforeChange', previous);
1070
1071 previous.wrap.stop(true).removeClass('fancybox-o pened')
1072 .find('.fancybox-item, .fancybox-nav')
1073 .remove();
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.removeClass('fancybox-tmp') ,
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(conten t).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', fun ction () {
1109 if ($(this).find(content ).length) {
1110 content.hide().r eplaceAll( content.data(placeholder) ).data(placeholder, false);
1111 }
1112 });
1113 }
1114 break;
1115
1116 case 'image':
1117 content = current.tpl.image.replace('{hr ef}', href);
1118 break;
1119
1120 case 'swf':
1121 content = '<object id="fancybox-swf" cla ssid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><pa ram name="movie" value="' + href + '"></param>';
1122 embed = '';
1123
1124 $.each(current.swf, function(name, val) {
1125 content += '<param name="' + nam e + '" value="' + val + '"></param>';
1126 embed += ' ' + name + '="' + v al + '"';
1127 });
1128
1129 content += '<embed src="' + href + '" ty pe="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></emb ed></object>';
1130 break;
1131 }
1132
1133 if (!(isQuery(content) && content.parent().is(current.in ner))) {
1134 current.inner.append( content );
1135 }
1136
1137 // Give a chance for helpers or callbacks to update elem ents
1138 F.trigger('beforeShow');
1139
1140 // Set scrolling before calculating dimensions
1141 current.inner.css('overflow', scrolling === 'yes' ? 'scr oll' : (scrolling === 'no' ? 'hidden' : scrolling));
1142
1143 // Set initial dimensions and start position
1144 F._setDimension();
1145
1146 F.reposition();
1147
1148 F.isOpen = false;
1149 F.coming = null;
1150
1151 F.bindEvents();
1152
1153 if (!F.isOpened) {
1154 $('.fancybox-wrap').not( current.wrap ).stop(tru e).trigger('onReset').remove();
1155
1156 } else if (previous.prevMethod) {
1157 F.transitions[ previous.prevMethod ]();
1158 }
1159
1160 F.transitions[ F.isOpened ? current.nextMethod : current .openMethod ]();
1161
1162 F._preloadImages();
1163 },
1164
1165 _setDimension: function () {
1166 var viewport = F.getViewport(),
1167 steps = 0,
1168 canShrink = false,
1169 canExpand = false,
1170 wrap = F.wrap,
1171 skin = F.skin,
1172 inner = F.inner,
1173 current = F.current,
1174 width = current.width,
1175 height = current.height,
1176 minWidth = current.minWidth,
1177 minHeight = current.minHeight,
1178 maxWidth = current.maxWidth,
1179 maxHeight = current.maxHeight,
1180 scrolling = current.scrolling,
1181 scrollOut = current.scrollOutside ? current.scr ollbarWidth : 0,
1182 margin = current.margin,
1183 wMargin = getScalar(margin[1] + margin[3]),
1184 hMargin = getScalar(margin[0] + margin[2]),
1185 wPadding,
1186 hPadding,
1187 wSpace,
1188 hSpace,
1189 origWidth,
1190 origHeight,
1191 origMaxWidth,
1192 origMaxHeight,
1193 ratio,
1194 width_,
1195 height_,
1196 maxWidth_,
1197 maxHeight_,
1198 iframe,
1199 body;
1200
1201 // Reset dimensions so we could re-check actual size
1202 wrap.add(skin).add(inner).width('auto').height('auto');
1203
1204 wPadding = getScalar(skin.outerWidth(true) - skin.width ());
1205 hPadding = getScalar(skin.outerHeight(true) - skin.heigh t());
1206
1207 // Any space between content and viewport (margin, paddi ng, border, title)
1208 wSpace = wMargin + wPadding;
1209 hSpace = hMargin + hPadding;
1210
1211 origWidth = isPercentage(width) ? (viewport.w - wSpace ) * getScalar(width) / 100 : width;
1212 origHeight = isPercentage(height) ? (viewport.h - hSpace ) * getScalar(height) / 100 : height;
1213
1214 if (current.type === 'iframe') {
1215 iframe = current.content;
1216
1217 if (current.autoHeight && iframe.data('ready') = == 1) {
1218 try {
1219 if (iframe[0].contentWindow.docu ment.location) {
1220 inner.width( origWidth ) .height(9999);
1221
1222 body = iframe.contents() .find('body');
1223
1224 if (scrollOut) {
1225 body.css('overfl ow-x', 'hidden');
1226 }
1227
1228 origHeight = body.height ();
1229 }
1230
1231 } catch (e) {}
1232 }
1233
1234 } else if (current.autoWidth || current.autoHeight) {
1235 inner.addClass( 'fancybox-tmp' );
1236
1237 // Set width or height in case we need to calcul ate only one dimension
1238 if (!current.autoWidth) {
1239 inner.width( origWidth );
1240 }
1241
1242 if (!current.autoHeight) {
1243 inner.height( origHeight );
1244 }
1245
1246 if (current.autoWidth) {
1247 origWidth = inner.width();
1248 }
1249
1250 if (current.autoHeight) {
1251 origHeight = inner.height();
1252 }
1253
1254 inner.removeClass( 'fancybox-tmp' );
1255 }
1256
1257 width = getScalar( origWidth );
1258 height = getScalar( origHeight );
1259
1260 ratio = origWidth / origHeight;
1261
1262 // Calculations for the content
1263 minWidth = getScalar(isPercentage(minWidth) ? getScalar (minWidth, 'w') - wSpace : minWidth);
1264 maxWidth = getScalar(isPercentage(maxWidth) ? getScalar (maxWidth, 'w') - wSpace : maxWidth);
1265
1266 minHeight = getScalar(isPercentage(minHeight) ? getScala r(minHeight, 'h') - hSpace : minHeight);
1267 maxHeight = getScalar(isPercentage(maxHeight) ? getScala r(maxHeight, 'h') - hSpace : maxHeight);
1268
1269 // These will be used to determine if wrap can fit in th e viewport
1270 origMaxWidth = maxWidth;
1271 origMaxHeight = maxHeight;
1272
1273 if (current.fitToView) {
1274 maxWidth = Math.min(viewport.w - wSpace, maxWid th);
1275 maxHeight = Math.min(viewport.h - hSpace, maxHei ght);
1276 }
1277
1278 maxWidth_ = viewport.w - wMargin;
1279 maxHeight_ = viewport.h - hMargin;
1280
1281 if (current.aspectRatio) {
1282 if (width > maxWidth) {
1283 width = maxWidth;
1284 height = getScalar(width / ratio);
1285 }
1286
1287 if (height > maxHeight) {
1288 height = maxHeight;
1289 width = getScalar(height * ratio);
1290 }
1291
1292 if (width < minWidth) {
1293 width = minWidth;
1294 height = getScalar(width / ratio);
1295 }
1296
1297 if (height < minHeight) {
1298 height = minHeight;
1299 width = getScalar(height * ratio);
1300 }
1301
1302 } else {
1303 width = Math.max(minWidth, Math.min(width, maxWi dth));
1304
1305 if (current.autoHeight && current.type !== 'ifra me') {
1306 inner.width( width );
1307
1308 height = inner.height();
1309 }
1310
1311 height = Math.max(minHeight, Math.min(height, ma xHeight));
1312 }
1313
1314 // Try to fit inside viewport (including the title)
1315 if (current.fitToView) {
1316 inner.width( width ).height( height );
1317
1318 wrap.width( width + wPadding );
1319
1320 // Real wrap dimensions
1321 width_ = wrap.width();
1322 height_ = wrap.height();
1323
1324 if (current.aspectRatio) {
1325 while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
1326 if (steps++ > 19) {
1327 break;
1328 }
1329
1330 height = Math.max(minHeight, Mat h.min(maxHeight, height - 10));
1331 width = getScalar(height * rati o);
1332
1333 if (width < minWidth) {
1334 width = minWidth;
1335 height = getScalar(width / ratio);
1336 }
1337
1338 if (width > maxWidth) {
1339 width = maxWidth;
1340 height = getScalar(width / ratio);
1341 }
1342
1343 inner.width( width ).height( hei ght );
1344
1345 wrap.width( width + wPadding );
1346
1347 width_ = wrap.width();
1348 height_ = wrap.height();
1349 }
1350
1351 } else {
1352 width = Math.max(minWidth, Math.min(wi dth, width - (width_ - maxWidth_)));
1353 height = Math.max(minHeight, Math.min(he ight, height - (height_ - maxHeight_)));
1354 }
1355 }
1356
1357 if (scrollOut && scrolling === 'auto' && height < origHe ight && (width + wPadding + scrollOut) < maxWidth_) {
1358 width += scrollOut;
1359 }
1360
1361 inner.width( width ).height( height );
1362
1363 wrap.width( width + wPadding );
1364
1365 width_ = wrap.width();
1366 height_ = wrap.height();
1367
1368 canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
1369 canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < ori gHeight));
1370
1371 $.extend(current, {
1372 dim : {
1373 width : getValue( width_ ),
1374 height : getValue( height_ )
1375 },
1376 origWidth : origWidth,
1377 origHeight : origHeight,
1378 canShrink : canShrink,
1379 canExpand : canExpand,
1380 wPadding : wPadding,
1381 hPadding : hPadding,
1382 wrapSpace : height_ - skin.outerHeight(true),
1383 skinSpace : skin.height() - height
1384 });
1385
1386 if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
1387 inner.height('auto');
1388 }
1389 },
1390
1391 _getPosition: function (onlyAbsolute) {
1392 var current = F.current,
1393 viewport = F.getViewport(),
1394 margin = current.margin,
1395 width = F.wrap.width() + margin[1] + margin[ 3],
1396 height = F.wrap.height() + margin[0] + margin[ 2],
1397 rez = {
1398 position: 'absolute',
1399 top : margin[0],
1400 left : margin[3]
1401 };
1402
1403 if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
1404 rez.position = 'fixed';
1405
1406 } else if (!current.locked) {
1407 rez.top += viewport.y;
1408 rez.left += viewport.x;
1409 }
1410
1411 rez.top = getValue(Math.max(rez.top, rez.top + ((view port.h - height) * current.topRatio)));
1412 rez.left = getValue(Math.max(rez.left, rez.left + ((view port.w - width) * current.leftRatio)));
1413
1414 return rez;
1415 },
1416
1417 _afterZoomIn: function () {
1418 var current = F.current;
1419
1420 if (!current) {
1421 return;
1422 }
1423
1424 F.isOpen = F.isOpened = true;
1425
1426 F.wrap.css('overflow', 'visible').addClass('fancybox-ope ned');
1427
1428 F.reposition();
1429
1430 // Assign a click event
1431 if ( current.closeClick || (current.nextClick && F.group .length > 1) ) {
1432 F.inner.css('cursor', 'pointer').bind('click.fb' , function(e) {
1433 if (!$(e.target).is('a') && !$(e.target) .parent().is('a')) {
1434 F[ current.closeClick ? 'close' : 'next' ]();
1435 }
1436 });
1437 }
1438
1439 // Create a close button
1440 if (current.closeBtn) {
1441 $(current.tpl.closeBtn).appendTo(F.skin).bind('c lick.fb', F.close);
1442 }
1443
1444 // Create navigation arrows
1445 if (current.arrows && F.group.length > 1) {
1446 if (current.loop || current.index > 0) {
1447 $(current.tpl.prev).appendTo(F.outer).bi nd('click.fb', F.prev);
1448 }
1449
1450 if (current.loop || current.index < F.group.leng th - 1) {
1451 $(current.tpl.next).appendTo(F.outer).bi nd('click.fb', F.next);
1452 }
1453 }
1454
1455 F.trigger('afterShow');
1456
1457 // Stop the slideshow if this is the last item
1458 if (!current.loop && current.index === current.group.len gth - 1) {
1459 F.play( false );
1460
1461 } else if (F.opts.autoPlay && !F.player.isActive) {
1462 F.opts.autoPlay = false;
1463
1464 F.play();
1465 }
1466 },
1467
1468 _afterZoomOut: function () {
1469 var current = F.current;
1470
1471 $('.fancybox-wrap').stop(true).trigger('onReset').remove ();
1472
1473 $.extend(F, {
1474 group : {},
1475 opts : {},
1476 router : false,
1477 current : null,
1478 isActive : false,
1479 isOpened : false,
1480 isOpen : false,
1481 isClosing : false,
1482 wrap : null,
1483 skin : null,
1484 outer : null,
1485 inner : null
1486 });
1487
1488 F.trigger('afterClose', current);
1489 }
1490 });
1491
1492 /*
1493 * Default transitions
1494 */
1495
1496 F.transitions = {
1497 getOrigPosition: function () {
1498 var current = F.current,
1499 element = current.element,
1500 orig = current.orig,
1501 pos = {},
1502 width = 50,
1503 height = 50,
1504 hPadding = current.hPadding,
1505 wPadding = current.wPadding,
1506 viewport = F.getViewport();
1507
1508 if (!orig && current.isDom && element.is(':visible')) {
1509 orig = element.find('img:first');
1510
1511 if (!orig.length) {
1512 orig = element;
1513 }
1514 }
1515
1516 if (isQuery(orig)) {
1517 pos = orig.offset();
1518
1519 if (orig.is('img')) {
1520 width = orig.outerWidth();
1521 height = orig.outerHeight();
1522 }
1523
1524 } else {
1525 pos.top = viewport.y + (viewport.h - height) * current.topRatio;
1526 pos.left = viewport.x + (viewport.w - width) * current.leftRatio;
1527 }
1528
1529 if (F.wrap.css('position') === 'fixed' || current.locked ) {
1530 pos.top -= viewport.y;
1531 pos.left -= viewport.x;
1532 }
1533
1534 pos = {
1535 top : getValue(pos.top - hPadding * current .topRatio),
1536 left : getValue(pos.left - wPadding * current .leftRatio),
1537 width : getValue(width + wPadding),
1538 height : getValue(height + hPadding)
1539 };
1540
1541 return pos;
1542 },
1543
1544 step: function (now, fx) {
1545 var ratio,
1546 padding,
1547 value,
1548 prop = fx.prop,
1549 current = F.current,
1550 wrapSpace = current.wrapSpace,
1551 skinSpace = current.skinSpace;
1552
1553 if (prop === 'width' || prop === 'height') {
1554 ratio = fx.end === fx.start ? 1 : (now - fx.star t) / (fx.end - fx.start);
1555
1556 if (F.isClosing) {
1557 ratio = 1 - ratio;
1558 }
1559
1560 padding = prop === 'width' ? current.wPadding : current.hPadding;
1561 value = now - padding;
1562
1563 F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) );
1564 F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
1565 }
1566 },
1567
1568 zoomIn: function () {
1569 var current = F.current,
1570 startPos = current.pos,
1571 effect = current.openEffect,
1572 elastic = effect === 'elastic',
1573 endPos = $.extend({opacity : 1}, startPos);
1574
1575 // Remove "position" property that breaks older IE
1576 delete endPos.position;
1577
1578 if (elastic) {
1579 startPos = this.getOrigPosition();
1580
1581 if (current.openOpacity) {
1582 startPos.opacity = 0.1;
1583 }
1584
1585 } else if (effect === 'fade') {
1586 startPos.opacity = 0.1;
1587 }
1588
1589 F.wrap.css(startPos).animate(endPos, {
1590 duration : effect === 'none' ? 0 : current.openS peed,
1591 easing : current.openEasing,
1592 step : elastic ? this.step : null,
1593 complete : F._afterZoomIn
1594 });
1595 },
1596
1597 zoomOut: function () {
1598 var current = F.current,
1599 effect = current.closeEffect,
1600 elastic = effect === 'elastic',
1601 endPos = {opacity : 0.1};
1602
1603 if (elastic) {
1604 endPos = this.getOrigPosition();
1605
1606 if (current.closeOpacity) {
1607 endPos.opacity = 0.1;
1608 }
1609 }
1610
1611 F.wrap.animate(endPos, {
1612 duration : effect === 'none' ? 0 : current.close Speed,
1613 easing : current.closeEasing,
1614 step : elastic ? this.step : null,
1615 complete : F._afterZoomOut
1616 });
1617 },
1618
1619 changeIn: function () {
1620 var current = F.current,
1621 effect = current.nextEffect,
1622 startPos = current.pos,
1623 endPos = { opacity : 1 },
1624 direction = F.direction,
1625 distance = 200,
1626 field;
1627
1628 startPos.opacity = 0.1;
1629
1630 if (effect === 'elastic') {
1631 field = direction === 'down' || direction === 'u p' ? 'top' : 'left';
1632
1633 if (direction === 'down' || direction === 'right ') {
1634 startPos[ field ] = getValue(getScalar(s tartPos[ field ]) - distance);
1635 endPos[ field ] = '+=' + distance + 'p x';
1636
1637 } else {
1638 startPos[ field ] = getValue(getScalar(s tartPos[ field ]) + distance);
1639 endPos[ field ] = '-=' + distance + 'p x';
1640 }
1641 }
1642
1643 // Workaround for http://bugs.jquery.com/ticket/12273
1644 if (effect === 'none') {
1645 F._afterZoomIn();
1646
1647 } else {
1648 F.wrap.css(startPos).animate(endPos, {
1649 duration : current.nextSpeed,
1650 easing : current.nextEasing,
1651 complete : function() {
1652 // This helps FireFox to properl y render the box
1653 setTimeout(F._afterZoomIn, 20);
1654 }
1655 });
1656 }
1657 },
1658
1659 changeOut: function () {
1660 var previous = F.previous,
1661 effect = previous.prevEffect,
1662 endPos = { opacity : 0.1 },
1663 direction = F.direction,
1664 distance = 200;
1665
1666 if (effect === 'elastic') {
1667 endPos[ direction === 'down' || direction === 'u p' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
1668 }
1669
1670 previous.wrap.animate(endPos, {
1671 duration : effect === 'none' ? 0 : previous.prev Speed,
1672 easing : previous.prevEasing,
1673 complete : function () {
1674 $(this).trigger('onReset').remove();
1675 }
1676 });
1677 }
1678 };
1679
1680 /*
1681 * Overlay helper
1682 */
1683
1684 F.helpers.overlay = {
1685 defaults : {
1686 closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay
1687 speedOut : 200, // duration of fadeOut animation
1688 showEarly : true, // indicates if should be opened imm ediately or wait until the content is ready
1689 css : {}, // custom CSS properties
1690 locked : true // if true, the content will be lock ed into overlay
1691 },
1692
1693 overlay : null,
1694 fixed : false,
1695
1696 // Public methods
1697 create : function() {
1698 if (this.overlay) {
1699 this.close();
1700 }
1701
1702 this.overlay = $('<div class="fancybox-overlay"></div>') .appendTo( this.el || 'body' );
1703 this.fixed = false;
1704
1705 if (F.defaults.fixed && !isTouch) {
1706 this.overlay.addClass('fancybox-overlay-fixed');
1707
1708 this.fixed = true;
1709 }
1710 },
1711
1712 open : function(opts) {
1713 var that = this;
1714
1715 opts = $.extend({}, this.defaults, opts);
1716
1717 if (this.overlay) {
1718 this.overlay.unbind('.overlay').width('auto').he ight('auto');
1719
1720 } else {
1721 this.create();
1722 }
1723
1724 if (!this.fixed) {
1725 W.bind('resize.overlay', $.proxy( this.update, t his) );
1726
1727 this.update();
1728 }
1729
1730 if (opts.closeClick) {
1731 this.overlay.bind('click.overlay', function(e) {
1732 if ($(e.target).hasClass('fancybox-overl ay')) {
1733 if (F.isActive) {
1734 F.close();
1735 } else {
1736 that.close();
1737 }
1738 }
1739 });
1740 }
1741
1742 this.overlay.css( opts.css ).show();
1743 },
1744
1745 close : function() {
1746 $('.fancybox-overlay').remove();
1747
1748 W.unbind('resize.overlay');
1749
1750 this.overlay = null;
1751 },
1752
1753 // Private, callbacks
1754
1755 update : function () {
1756 var width = '100%', offsetWidth;
1757
1758 // Reset width/height so it will not mess
1759 this.overlay.width(width).height('100%');
1760
1761 // jQuery does not return reliable result for IE
1762 if ($.browser.msie) {
1763 offsetWidth = Math.max(document.documentElement. offsetWidth, document.body.offsetWidth);
1764
1765 if (D.width() > offsetWidth) {
1766 width = D.width();
1767 }
1768
1769 } else if (D.width() > W.width()) {
1770 width = D.width();
1771 }
1772
1773 this.overlay.width(width).height(D.height());
1774 },
1775
1776 // This is where we can manipulate DOM, because later it would c ause iframes to reload
1777 onReady : function (opts, obj) {
1778 $('.fancybox-overlay').stop(true, true);
1779
1780 if (!this.overlay) {
1781 this.margin = D.height() > W.height() || $('body ').css('overflow-y') === 'scroll' ? $('body').css('margin-right') : false;
1782 this.el = document.all && !document.querySel ector ? $('html') : $('body');
1783
1784 this.create();
1785 }
1786
1787 if (opts.locked && this.fixed) {
1788 obj.locked = this.overlay.append( obj.wrap );
1789 obj.fixed = false;
1790 }
1791
1792 if (opts.showEarly === true) {
1793 this.beforeShow.apply(this, arguments);
1794 }
1795 },
1796
1797 beforeShow : function(opts, obj) {
1798 if (obj.locked) {
1799 this.el.addClass('fancybox-lock');
1800
1801 if (this.margin !== false) {
1802 $('body').css('margin-right', getScalar( this.margin ) + obj.scrollbarWidth);
1803 }
1804 }
1805
1806 this.open(opts);
1807 },
1808
1809 onUpdate : function() {
1810 if (!this.fixed) {
1811 this.update();
1812 }
1813 },
1814
1815 afterClose: function (opts) {
1816 var that = this,
1817 speed = opts.speedOut;
1818
1819 // Remove overlay if exists and fancyBox is not opening
1820 // (e.g., it is not being open using afterClose callback )
1821 if (that.overlay && !F.isActive) {
1822 that.overlay.fadeOut(speed || 0, function () {
1823 if (that.margin !== false) {
1824 $('body').css('margin-right', th at.margin);
1825 }
1826
1827 that.el.removeClass('fancybox-lock');
1828
1829 that.close();
1830 });
1831 }
1832 }
1833 };
1834
1835 /*
1836 * Title helper
1837 */
1838
1839 F.helpers.title = {
1840 defaults : {
1841 type : 'float', // 'float', 'inside', 'outside' or ' over',
1842 position : 'bottom' // 'top' or 'bottom'
1843 },
1844
1845 beforeShow: function (opts) {
1846 var current = F.current,
1847 text = current.title,
1848 type = opts.type,
1849 title,
1850 target;
1851
1852 if ($.isFunction(text)) {
1853 text = text.call(current.element, current);
1854 }
1855
1856 if (!isString(text) || $.trim(text) === '') {
1857 return;
1858 }
1859
1860 title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">' + text + '</div>');
1861
1862 switch (type) {
1863 case 'inside':
1864 target = F.skin;
1865 break;
1866
1867 case 'outside':
1868 target = F.wrap;
1869 break;
1870
1871 case 'over':
1872 target = F.inner;
1873 break;
1874
1875 default: // 'float'
1876 target = F.skin;
1877
1878 title.appendTo('body');
1879
1880 if ($.browser.msie) {
1881 title.width( title.width() );
1882 }
1883
1884 title.wrapInner('<span class="child"></s pan>');
1885
1886 //Increase bottom margin so this title w ill also fit into viewport
1887 F.current.margin[2] += Math.abs( getScal ar(title.css('margin-bottom')) );
1888 break;
1889 }
1890
1891 title[ (opts.position === 'top' ? 'prependTo' : 'append To') ](target);
1892 }
1893 };
1894
1895 // jQuery plugin initialization
1896 $.fn.fancybox = function (options) {
1897 var index,
1898 that = $(this),
1899 selector = this.selector || '',
1900 run = function(e) {
1901 var what = $(this).blur(), idx = index, relType, relVal;
1902
1903 if (!(e.ctrlKey || e.altKey || e.shiftKey || e.m etaKey) && !what.is('.fancybox-wrap')) {
1904 relType = options.groupAttr || 'data-fan cybox-group';
1905 relVal = what.attr(relType);
1906
1907 if (!relVal) {
1908 relType = 'rel';
1909 relVal = what.get(0)[ relType ] ;
1910 }
1911
1912 if (relVal && relVal !== '' && relVal != = 'nofollow') {
1913 what = selector.length ? $(selec tor) : that;
1914 what = what.filter('[' + relType + '="' + relVal + '"]');
1915 idx = what.index(this);
1916 }
1917
1918 options.index = idx;
1919
1920 // Stop an event from bubbling if everyt hing is fine
1921 if (F.open(what, options) !== false) {
1922 e.preventDefault();
1923 }
1924 }
1925 };
1926
1927 options = options || {};
1928 index = options.index || 0;
1929
1930 if (!selector || options.live === false) {
1931 that.unbind('click.fb-start').bind('click.fb-start', run );
1932 } else {
1933 D.undelegate(selector, 'click.fb-start').delegate(select or + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);
1934 }
1935
1936 return this;
1937 };
1938
1939 // Tests that need a body at doc ready
1940 D.ready(function() {
1941 if ( $.scrollbarWidth === undefined ) {
1942 // http://benalman.com/projects/jquery-misc-plugins/#scr ollbarwidth
1943 $.scrollbarWidth = function() {
1944 var parent = $('<div style="width:50px;height:50 px;overflow:auto"><div/></div>').appendTo('body'),
1945 child = parent.children(),
1946 width = child.innerWidth() - child.heig ht( 99 ).innerWidth();
1947
1948 parent.remove();
1949
1950 return width;
1951 };
1952 }
1953
1954 if ( $.support.fixedPosition === undefined ) {
1955 $.support.fixedPosition = (function() {
1956 var elem = $('<div style="position:fixed;top:20 px;"></div>').appendTo('body'),
1957 fixed = ( elem[0].offsetTop === 20 || el em[0].offsetTop === 15 );
1958
1959 elem.remove();
1960
1961 return fixed;
1962 }());
1963 }
1964
1965 $.extend(F.defaults, {
1966 scrollbarWidth : $.scrollbarWidth(),
1967 fixed : $.support.fixedPosition,
1968 parent : $('body')
1969 });
1970 });
1971
1972 }(window, document, jQuery));
OLDNEW

Powered by Google App Engine
This is Rietveld