PageSourceSearch

http://www.isse.fr/js/fancybox/jquery.fancybox.js

js isse.fr collected 2026-10-02 16:21:43 UTC 29,124 bytes, 1,279 lines download raw bytes

1 /*!
2 * fancyBox - jQuery Plugin
3 * version: 2.0.3 (29/11/2011)
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 2011 Janis Skarnelis - [email protected]
10 *
11 */
12(function (window, document, $) {
13	var W = $(window),
14		D = $(document),
15		F = $.fancybox = function () {
16			F.open.apply( this, arguments );
17		},
18		didResize = false,
19		resizeTimer = null;
20
21	$.extend(F, {
22		// The current version of fancyBox
23		version: '2.0.3',
24
25		defaults: {
26			padding: 15,
27			margin: 20,
28
29			width: 800,
30			height: 600,
31			minWidth: 200,
32			minHeight: 200,
33			maxWidth: 9999,
34			maxHeight: 9999,
35
36			autoSize: true,
37			fitToView: true,
38			aspectRatio: false,
39			topRatio: 0.5,
40
41			fixed: !$.browser.msie || $.browser.version > 6,
42			scrolling: 'auto', // 'auto', 'yes' or 'no'
43			wrapCSS: 'fancybox-default',
44
45			arrows: true,
46			closeBtn: true,
47			closeClick: false,
48			nextClick : false,
49			mouseWheel: true,
50			autoPlay: false,
51			playSpeed: 3000,
52
53			modal: false,
54			loop: true,
55			ajax: {},
56			keys: {
57				next: [13, 32, 34, 39, 40], // enter, space, page down, right arrow, down arrow
58				prev: [8, 33, 37, 38], // backspace, page up, left arrow, up arrow
59				close: [27] // escape key
60			},
61
62			// Override some properties
63			index: 0,
64			type: null,
65			href: null,
66			content: null,
67			title: null,
68
69			// HTML templates
70			tpl: {
71				wrap: '<div class="fancybox-wrap"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div>',
72				image: '<img class="fancybox-image" src="{href}" alt="" />',
73				iframe: '<iframe class="fancybox-iframe" name="fancybox-frame{rnd}" frameborder="0" hspace="0" ' + ($.browser.msie ? 'allowtransparency="true""' : '') + ' scrolling="{scrolling}" src="{href}"></iframe>',
74				swf: '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{href}" /><embed src="{href}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="100%" height="100%" wmode="transparent"></embed></object>',
75				error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
76				closeBtn: '<div title="Close" class="fancybox-item fancybox-close"></div>',
77				next: '<a title="Next" class="fancybox-item fancybox-next"><span></span></a>',
78				prev: '<a title="Previous" class="fancybox-item fancybox-prev"><span></span></a>'
79			},
80
81			// Properties for each animation type
82			// Opening fancyBox
83			openEffect: 'elastic', // 'elastic', 'fade' or 'none'
84			openSpeed: 500,
85			openEasing: 'swing',
86			openOpacity: true,
87			openMethod: 'zoomIn',
88
89			// Closing fancyBox
90			closeEffect: 'fade', // 'elastic', 'fade' or 'none'
91			closeSpeed: 500,
92			closeEasing: 'swing',
93			closeOpacity: true,
94			closeMethod: 'zoomOut',
95
96			// Changing next gallery item
97			nextEffect: 'elastic', // 'elastic', 'fade' or 'none'
98			nextSpeed: 300,
99			nextEasing: 'swing',
100			nextMethod: 'changeIn',
101
102			// Changing previous gallery item
103			prevEffect: 'elastic', // 'elastic', 'fade' or 'none'
104			prevSpeed: 300,
105			prevEasing: 'swing',
106			prevMethod: 'changeOut',
107
108			// Enabled helpers
109			helpers: {
110				overlay: {
111					speedIn: 0,
112					speedOut: 0,
113					opacity: 0.85,
114					css: {
115						cursor: 'pointer',
116						'background-color': 'rgba(0, 0, 0, 0.85)' //Browsers who don`t support rgba will fall back to default color value defined at CSS file
117					},
118					closeClick: true
119				},
120				title: {
121					type: 'float' // 'float', 'inside', 'outside' or 'over'
122				}
123			},
124
125			// Callbacks
126			onCancel: $.noop, // If canceling
127			beforeLoad: $.noop, // Before loading
128			afterLoad: $.noop, // After loading
129			beforeShow: $.noop, // Before changing in current item
130			afterShow: $.noop, // After opening
131			beforeClose: $.noop, // Before closing
132			afterClose: $.noop // After closing
133		},
134
135		//Current state
136		group: {}, // Selected group
137		opts: {}, // Group options
138		coming: null, // Element being loaded
139		current: null, // Currently loaded element
140		isOpen: false, // Is currently open
141		isOpened: false, // Have been fully opened at least once
142		wrap: null,
143		outer: null,
144		inner: null,
145
146		player: {
147			timer: null,
148			isActive: false
149		},
150
151		// Loaders
152		ajaxLoad: null,
153		imgPreload: null,
154
155		// Some collections
156		transitions: {},
157		helpers: {},
158
159		/*
160		 *	Static methods
161		 */
162
163		open: function (group, opts) {
164			// Normalize group
165			if (!$.isArray(group)) {
166				group = [group];
167			}
168
169			if (!group.length) {
170				return;
171			}
172
173			//Kill existing instances
174			F.close(true);
175
176			//extend the defaults
177			F.opts = $.extend(true, {}, F.defaults, opts);
178			F.group = group;
179
180			F._start(F.opts.index || 0);
181		},
182
183		cancel: function () {
184			if (F.coming && false === F.trigger('onCancel')) {
185				return;
186			}
187
188			F.coming = null;
189
190			F.hideLoading();
191
192			if (F.ajaxLoad) {
193				F.ajaxLoad.abort();
194			}
195
196			F.ajaxLoad = null;
197
198			if (F.imgPreload) {
199				F.imgPreload.onload = F.imgPreload.onabort = F.imgPreload.onerror = null;
200			}
201		},
202
203		close: function (a) {
204			F.cancel();
205
206			if (!F.current || false === F.trigger('beforeClose')) {
207				return;
208			}
209
210			F.unbindEvents();
211
212			//If forced or is still opening then remove immediately
213			if (!F.isOpen || (a && a[0] === true)) {
214				$(".fancybox-wrap").stop().trigger('onReset').remove();
215
216				F._afterZoomOut();
217
218			} else {
219				F.isOpen = F.isOpened = false;
220
221				$(".fancybox-item").remove();
222
223				F.wrap.stop(true).removeClass('fancybox-opened');
224				F.inner.css('overflow', 'hidden');
225
226				F.transitions[F.current.closeMethod]();
227			}
228		},
229
230		play: function (a) {
231			var clear = function () {
232					clearTimeout(F.player.timer);
233				},
234				set = function () {
235					clear();
236
237					if (F.current && F.player.isActive) {
238						F.player.timer = setTimeout(F.next, F.current.playSpeed);
239					}
240				},
241				stop = function () {
242					clear();
243
244					$('body').unbind('.player');
245
246					F.player.isActive = false;
247
248					F.trigger('onPlayEnd');
249				},
250				start = function () {
251					if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
252						F.player.isActive = true;
253
254						set();
255
256						$('body').bind({
257							'onCancel.player afterShow.player onUpdate.player': set,
258							'beforeClose.player': stop,
259							'beforeLoad.player': clear
260						});
261
262						F.trigger('onPlayStart');
263					}
264				};
265
266			if (F.player.isActive || (a && a[0] === false)) {
267				stop();
268			} else {
269				start();
270			}
271		},
272
273		next: function () {
274			if (F.current) {
275				F.jumpto(F.current.index + 1);
276			}
277		},
278
279		prev: function () {
280			if (F.current) {
281				F.jumpto(F.current.index - 1);
282			}
283		},
284
285		jumpto: function (index) {
286			if (!F.current) {
287				return;
288			}
289
290			index = parseInt(index, 10);
291
292			if (F.group.length > 1 && F.current.loop) {
293				if (index >= F.group.length) {
294					index = 0;
295
296				} else if (index < 0) {
297					index = F.group.length - 1;
298				}
299			}
300
301			if (typeof F.group[index] !== 'undefined') {
302				F.cancel();
303
304				F._start(index);
305			}
306		},
307
308		reposition: function (a) {
309			if (F.isOpen) {
310				F.wrap.css(F._getPosition(a));
311			}
312		},
313
314		update: function () {
315			if (F.isOpen) {
316				// It's a very bad idea to attach handlers to the window scroll event, run this code after a delay
317				if (!didResize) {
318					resizeTimer = setInterval(function () {
319						if (didResize) {
320							didResize = false;
321
322							clearTimeout(resizeTimer);
323
324							if (F.current) {
325								if (F.current.autoSize) {
326									F.inner.height('auto');
327									F.current.height = F.inner.height();
328								}
329
330								F._setDimension();
331
332								if (F.current.canGrow) {
333									F.inner.height('auto');
334								}
335
336								F.reposition();
337
338								F.trigger('onUpdate');
339							}
340						}
341					}, 100);
342				}
343
344				didResize = true;
345			}
346		},
347
348		toggle: function () {
349			if (F.isOpen) {
350				F.current.fitToView = !F.current.fitToView;
351
352				F.update();
353			}
354		},
355
356		hideLoading: function () {
357			$("#fancybox-loading").remove();
358		},
359
360		showLoading: function () {
361			F.hideLoading();
362
363			$('<div id="fancybox-loading"></div>').click(F.cancel).appendTo('body');
364		},
365
366		getViewport: function () {
367			return {
368				x: W.scrollLeft(),
369				y: W.scrollTop(),
370				w: W.width(),
371				h: W.height()
372			};
373		},
374
375		// Unbind the keyboard / clicking actions
376		unbindEvents: function () {
377			if (F.wrap) {
378				F.wrap.unbind('.fb');	
379			}
380
381			D.unbind('.fb');
382			W.unbind('.fb');
383		},
384
385		bindEvents: function () {
386			var current = F.current,
387				keys = current.keys;
388
389			if (!current) {
390				return;
391			}
392
393			W.bind('resize.fb, orientationchange.fb', F.update);
394
395			if (keys) {
396				D.bind('keydown.fb', function (e) {
397					// Ignore key events within form elements
398					if ($.inArray(e.target.tagName.toLowerCase(), ['input', 'textarea', 'select', 'button']) > -1) {
399						return;
400					}
401
402					if ($.inArray(e.keyCode, keys.close) > -1) {
403						F.close();
404						e.preventDefault();
405
406					} else if ($.inArray(e.keyCode, keys.next) > -1) {
407						F.next();
408						e.preventDefault();
409
410					} else if ($.inArray(e.keyCode, keys.prev) > -1) {
411						F.prev();
412						e.preventDefault();
413					}
414				});
415			}
416
417			if ($.fn.mousewheel && current.mouseWheel && F.group.length > 1) {
418				F.wrap.bind('mousewheel.fb', function (e, delta) {
419					if ($(e.target).get(0).clientHeight === 0 || $(e.target).get(0).scrollHeight === $(e.target).get(0).clientHeight) {
420						e.preventDefault();
421
422						F[delta > 0 ? 'prev' : 'next']();
423					}
424				});
425			}
426		},
427
428		trigger: function (event) {
429			var ret, obj = $.inArray(event, ['onCancel', 'beforeLoad', 'afterLoad']) > -1 ? 'coming' : 'current';
430
431			if (!F[obj]) {
432				return;
433			}
434
435			if ($.isFunction(F[obj][event])) {
436				ret = F[obj][event].apply(F[obj], Array.prototype.slice.call(arguments, 1));
437			}
438
439			if (ret === false) {
440				return false;
441			}
442
443			if (F[obj].helpers) {
444				$.each(F[obj].helpers, function (helper, opts) {
445					if (opts && typeof F.helpers[helper] !== 'undefined' && $.isFunction(F.helpers[helper][event])) {
446						F.helpers[helper][event](opts);
447					}
448				});
449			}
450
451			$.event.trigger(event + '.fb');
452		},
453
454		isImage: function (str) {
455			return str && str.match(/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i);
456		},
457
458		isSWF: function (str) {
459			return str && str.match(/\.(swf)(.*)?$/i);
460		},
461
462		_start: function (index) {
463			var element = F.group[index] || null,
464				isDom,
465				href,
466				type,
467				rez,
468				coming = $.extend(true, {}, F.opts, ($.isPlainObject(element) ? element : {}), {
469					index : index,
470					element : element
471				});
472
473			// Convert margin property to array - top, right, bottom, left
474			if (typeof coming.margin === 'number') {
475				coming.margin = [coming.margin, coming.margin, coming.margin, coming.margin];
476			}
477
478			// 'modal' propery is just a shortcut
479			if (coming.modal) {
480				$.extend(true, coming, {
481					closeBtn : false,
482					closeClick: false,
483					nextClick : false,
484					arrows : false,
485					mouseWheel : false,
486					keys : null,
487					helpers: {
488						overlay : {
489							css: {
490								cursor : 'auto'
491							},
492							closeClick : false
493						}
494					}
495				});
496			}
497
498			//Give a chance for callback or helpers to update coming item (type, title, etc)
499			F.coming = coming;
500
501			if (false === F.trigger('beforeLoad')) {
502				F.coming = null;
503				return;
504			}
505
506			if (typeof element === 'object' && (element.nodeType || element instanceof $)) {
507				isDom = true;
508				coming.href = $(element).attr('href') || coming.href;
509				coming.title = $(element).attr('title') || coming.title;
510
511				if ($.metadata) {
512					$.extend(coming, $(element).metadata());	
513				}
514			}
515
516			type = coming.type;
517			href = coming.href;
518
519			///Check if content type is set, if not, try to get
520			if (!type) {
521				if (isDom) {
522					rez = $(element).data('fancybox-type');
523
524					if (!rez && element.className) {
525						rez = element.className.match(/fancybox\.(\w+)/);
526						rez = rez ? rez[1] : false;
527					}
528				}
529
530				if (rez) {
531					type = rez;
532
533				} else if (href) {
534					if (F.isImage(href)) {
535						type = 'image';
536
537					} else if (F.isSWF(href)) {
538						type = 'swf';
539
540					} else if (href.match(/^#/)) {
541						type = 'inline';
542					}
543				}
544
545				// ...if not - display element itself
546				if (!type) {
547					type = isDom ? 'inline' : 'html';
548				}
549
550				coming.type = type;
551			}
552
553			// Check before try to load; 'inline' and 'html' types need content, others - href
554			if (type === 'inline' || type === 'html') {
555				if (!coming.content) {
556					coming.content = type === 'inline' && href ? $(href) : element;
557				}
558
559				if (!coming.content.length) {
560					type = null;
561				}
562
563			} else {
564				coming.href = href || element;
565
566				if (!coming.href) {
567					type = null;
568				}
569			}
570
571			/*
572				Add reference to the group, so it`s possible to access from callbacks, example:
573
574				afterLoad : function() {
575					this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
576				}
577
578			*/
579
580			coming.group = F.group;
581
582			if (type === 'image') {
583				F._loadImage();
584
585			} else if (type === 'ajax') {
586				F._loadAjax();
587
588			} else if (type) {
589				F._afterLoad();
590
591			} else {
592				F._error();
593			}
594		},
595
596		_error: function () {
597			F.coming.type = 'html';
598			F.coming.minHeight = 0;
599			F.coming.autoSize = true;
600			F.coming.content = F.coming.tpl.error;
601
602			F._afterLoad();
603		},
604
605		_loadImage: function () {
606			// Reset preload image so it is later possible to check "complete" property
607			F.imgPreload = new Image();
608
609			F.imgPreload.onload = function () {
610				this.onload = this.onerror = null;
611
612				F.coming.width = this.width;
613				F.coming.height = this.height;
614
615				F._afterLoad();
616			};
617
618			F.imgPreload.onerror = function () {
619				this.onload = this.onerror = null;
620
621				F._error();
622			};
623
624			F.imgPreload.src = F.coming.href;
625
626			if (!F.imgPreload.complete) {
627				F.showLoading();
628			}
629		},
630
631		_loadAjax: function () {
632			F.showLoading();
633
634			F.ajaxLoad = $.ajax($.extend({}, F.coming.ajax, {
635				url: F.coming.href,
636				error: function (jqXHR, textStatus, errorThrown) {
637					if (textStatus !== 'abort') {
638						F.coming.content = errorThrown;
639
640						F._error();
641
642					} else {
643						F.hideLoading();
644					}
645				},
646				success: function (data, textStatus, jqXHR) {
647					if (textStatus === 'success') {
648						F.coming.content = data;
649
650						F._afterLoad();
651					}
652				}
653			}));
654		},
655
656		_afterLoad: function () {
657			F.hideLoading();
658
659			if (!F.coming || false === F.trigger('afterLoad', F.current)) {
660				F.coming = false;
661
662				return;
663			}
664
665			if (F.isOpened) {
666				$(".fancybox-item").remove();
667
668				F.wrap.stop(true).removeClass('fancybox-opened');
669				F.inner.css('overflow', 'hidden');
670
671				F.transitions[F.current.prevMethod]();
672
673			} else {
674				$(".fancybox-wrap").stop().trigger('onReset').remove();
675
676				F.trigger('afterClose');
677			}
678
679			F.unbindEvents();
680
681			F.isOpen = false;
682			F.current = F.coming;
683			F.coming = false;
684
685			//Build the neccessary markup
686			F.wrap = $(F.current.tpl.wrap).addClass('fancybox-tmp ' + F.current.wrapCSS).appendTo('body');
687			F.outer = $('.fancybox-outer', F.wrap).css('padding', F.current.padding + 'px');
688			F.inner = $('.fancybox-inner', F.wrap);
689
690			F._setContent();
691
692			//Give a chance for helpers or callbacks to update elements
693			F.trigger('beforeShow');
694
695			//Set initial dimensions and hide
696			F._setDimension();
697
698			F.wrap.hide().removeClass('fancybox-tmp');
699
700			F.bindEvents();
701
702			F.transitions[ F.isOpened ? F.current.nextMethod : F.current.openMethod ]();
703		},
704
705		_setContent: function () {
706			var content, loadingBay, current = F.current,
707				type = current.type;
708
709			switch (type) {
710				case 'inline':
711				case 'ajax':
712				case 'html':
713					if (type === 'inline') {
714						content = current.content.show().detach();
715
716						if (content.parent().hasClass('fancybox-inner')) {
717							content.parents('.fancybox-wrap').trigger('onReset').remove();
718						}
719
720						$(F.wrap).bind('onReset', function () {
721							content.appendTo('body').hide();
722						});
723
724					} else {
725						content = current.content;
726					}
727
728					if (current.autoSize) {
729						loadingBay = $('<div class="fancybox-tmp"></div>').appendTo($("body")).append(content);
730
731						current.width = loadingBay.outerWidth();
732						current.height = loadingBay.outerHeight(true);
733
734						content = loadingBay.contents().detach();
735
736						loadingBay.remove();
737					}
738
739				break;
740
741				case 'image':
742					content = current.tpl.image.replace('{href}', current.href);
743
744					current.aspectRatio = true;
745				break;
746
747				case 'swf':
748					content = current.tpl.swf.replace(/\{width\}/g, current.width).replace(/\{height\}/g, current.height).replace(/\{href\}/g, current.href);
749				break;
750
751				case 'iframe':
752					content = current.tpl.iframe.replace('{href}', current.href).replace('{scrolling}', current.scrolling).replace('{rnd}', new Date().getTime());
753				break;
754			}
755
756			if ($.inArray(type, ['image', 'swf', 'iframe']) > -1) {
757				current.autoSize = false;
758				current.scrolling = false;
759			}
760
761			F.inner.append(content);
762		},
763
764		_setDimension: function () {
765			var current = F.current,
766				viewport = F.getViewport(),
767				margin = current.margin,
768				padding2 = current.padding * 2,
769				width = current.width + padding2,
770				height = current.height + padding2,
771				ratio = current.width / current.height,
772
773				maxWidth = current.maxWidth,
774				maxHeight = current.maxHeight,
775				minWidth = current.minWidth,
776				minHeight = current.minHeight,
777				height_,
778				space;
779
780			viewport.w -= (margin[1] + margin[3]);
781			viewport.h -= (margin[0] + margin[2]);
782
783			if (width.toString().indexOf('%') > -1) {
784				width = ((viewport.w * parseFloat(width)) / 100);
785			}
786
787			if (height.toString().indexOf('%') > -1) {
788				height = ((viewport.h * parseFloat(height)) / 100);
789			}
790
791			if (current.fitToView) {
792				maxWidth = Math.min(viewport.w, maxWidth);
793				maxHeight = Math.min(viewport.h, maxHeight);
794			}
795
796			maxWidth = Math.max(minWidth, maxWidth);
797			maxHeight = Math.max(minHeight, maxHeight);
798
799			if (current.aspectRatio) {
800				if (width > maxWidth) {
801					width = maxWidth;
802					height = ((width - padding2) / ratio) + padding2;
803				}
804
805				if (height > maxHeight) {
806					height = maxHeight;
807					width = ((height - padding2) * ratio) + padding2;
808				}
809
810				if (width < minWidth) {
811					width = minWidth;
812					height = ((width - padding2) / ratio) + padding2;
813				}
814
815				if (height < minHeight) {
816					height = minHeight;
817					width = ((height - padding2) * ratio) + padding2;
818				}
819
820			} else {
821				width = Math.max(minWidth, Math.min(width, maxWidth));
822				height = Math.max(minHeight, Math.min(height, maxHeight));
823			}
824
825			width = Math.round(width);
826			height = Math.round(height);
827
828			//Reset dimensions
829			$(F.wrap.add(F.outer).add(F.inner)).width('auto').height('auto');
830
831			F.inner.width(width - padding2).height(height - padding2);
832			F.wrap.width(width);
833
834			height_ = F.wrap.height(); // Real wrap height
835
836			//Fit wrapper inside
837			if (width > maxWidth || height_ > maxHeight) {
838				while ((width > maxWidth || height_ > maxHeight) && width > minWidth && height_ > minHeight) {
839					height = height - 10;
840
841					if (current.aspectRatio) {
842						width = Math.round(((height - padding2) * ratio) + padding2);
843
844						if (width < minWidth) {
845							width = minWidth;
846							height = ((width - padding2) / ratio) + padding2;
847						}
848
849					} else {
850						width = width - 10;
851					}
852
853					F.inner.width(width - padding2).height(height - padding2);
854					F.wrap.width(width);
855
856					height_ = F.wrap.height();
857				}
858			}
859
860			current.dim = {
861				width: width,
862				height: height_
863			};
864
865			current.canGrow = current.autoSize && height > minHeight && height < maxHeight;
866			current.canShrink = false;
867			current.canExpand = false;
868
869			if ((width - padding2) < current.width || (height - padding2) < current.height) {
870				current.canExpand = true;
871
872			} else if ((width > viewport.w || height_ > viewport.h) && width > minWidth && height > minHeight) {
873				current.canShrink = true;
874			}
875
876			space = height_ - padding2;
877
878			F.innerSpace = space - F.inner.height();
879			F.outerSpace = space - F.outer.height();
880		},
881
882		_getPosition: function (a) {
883			var viewport = F.getViewport(),
884				margin = F.current.margin,
885				width = F.wrap.width() + margin[1] + margin[3],
886				height = F.wrap.height() + margin[0] + margin[2],
887				rez = {
888					position: 'absolute',
889					top: margin[0] + viewport.y,
890					left: margin[3] + viewport.x
891				};
892
893			if (F.current.fixed && (!a || a[0] === false) && height <= viewport.h && width <= viewport.w) {
894				rez = {
895					position: 'fixed',
896					top: margin[0],
897					left: margin[3]
898				};
899			}
900
901			rez.top = Math.ceil(Math.max(rez.top, rez.top + ((viewport.h - height) * F.current.topRatio))) + 'px';
902			rez.left = Math.ceil(Math.max(rez.left, rez.left + ((viewport.w - width) * 0.5))) + 'px';
903
904			return rez;
905		},
906
907		_afterZoomIn: function () {
908			var current = F.current;
909
910			F.isOpen = F.isOpened = true;
911
912			F.wrap.addClass('fancybox-opened').css('overflow', 'visible');
913
914			F.update();
915
916			F.inner.css('overflow', current.scrolling === 'auto' ? 'auto' : (current.scrolling === 'yes' ? 'scroll' : 'hidden'));
917
918			//Assign a click event
919			if (current.closeClick || current.nextClick) {
920				F.inner.bind('click.fb', current.nextClick ? F.next : F.close);
921			}
922
923			//Create a close button
924			if (current.closeBtn) {
925				$(F.current.tpl.closeBtn).appendTo(F.wrap).bind('click.fb', F.close);
926			}
927
928			//Create navigation arrows
929			if (current.arrows && F.group.length > 1) {
930				if (current.loop || current.index > 0) {
931					$(current.tpl.prev).appendTo(F.wrap).bind('click.fb', F.prev);
932				}
933
934				if (current.loop || current.index < F.group.length - 1) {
935					$(current.tpl.next).appendTo(F.wrap).bind('click.fb', F.next);
936				}
937			}
938
939			F.trigger('afterShow');
940
941			if (F.opts.autoPlay && !F.player.isActive) {
942				F.opts.autoPlay = false;
943
944				F.play();
945			}
946		},
947
948		_afterZoomOut: function () {
949			F.trigger('afterClose');
950
951			F.wrap.trigger('onReset').remove();
952
953			$.extend(F, {
954				group: {},
955				opts: {},
956				current: null,
957				isOpened: false,
958				isOpen: false,
959				wrap: null,
960				outer: null,
961				inner: null
962			});
963		}
964	});
965
966	/*
967	 *	Default transitions
968	 */
969
970	F.transitions = {
971		getOrigPosition: function () {
972			var element = F.current.element,
973				pos = {},
974				width = 50,
975				height = 50,
976				image, viewport;
977
978			if (element && element.nodeName && $(element).is(':visible')) {
979				image = $(element).find('img:first');
980
981				if (image.length) {
982					pos = image.offset();
983					width = image.outerWidth();
984					height = image.outerHeight();
985
986				} else {
987					pos = $(element).offset();
988				}
989
990			} else {
991				viewport = F.getViewport();
992				pos.top = viewport.y + (viewport.h - height) * 0.5;
993				pos.left = viewport.x + (viewport.w - width) * 0.5;
994			}
995
996			pos = {
997				top: Math.ceil(pos.top) + 'px',
998				left: Math.ceil(pos.left) + 'px',
999				width: Math.ceil(width) + 'px',
1000				height: Math.ceil(height) + 'px'
1001			};
1002
1003			return pos;
1004		},
1005
1006		step: function (now, fx) {
1007			var ratio, innerValue, outerValue;
1008
1009			if (fx.prop === 'width' || fx.prop === 'height') {
1010				innerValue = outerValue = Math.ceil(now - (F.current.padding * 2));
1011
1012				if (fx.prop === 'height') {
1013					ratio = (now - fx.start) / (fx.end - fx.start);
1014
1015					if (fx.start > fx.end) {
1016						ratio = 1 - ratio;
1017					}
1018
1019					innerValue -= F.innerSpace * ratio;
1020					outerValue -= F.outerSpace * ratio;
1021				}
1022
1023				F.inner[fx.prop](innerValue);
1024				F.outer[fx.prop](outerValue);
1025			}
1026		},
1027
1028		zoomIn: function () {
1029			var current = F.current,
1030				startPos,
1031				endPos,
1032				dim = current.dim;
1033
1034			if (current.openEffect === 'elastic') {
1035				endPos = $.extend({}, dim, F._getPosition(true));
1036
1037				//Remove "position" property
1038				delete endPos.position;
1039
1040				startPos = this.getOrigPosition();
1041
1042				if (current.openOpacity) {
1043					startPos.opacity = 0;
1044					endPos.opacity = 1;
1045				}
1046
1047				F.wrap.css(startPos).show().animate(endPos, {
1048					duration: current.openSpeed,
1049					easing: current.openEasing,
1050					step: this.step,
1051					complete: F._afterZoomIn
1052				});
1053
1054			} else {
1055				F.wrap.css($.extend({}, dim, F._getPosition()));
1056
1057				if (current.openEffect === 'fade') {
1058					F.wrap.fadeIn(current.openSpeed, F._afterZoomIn);
1059
1060				} else {
1061					F.wrap.show();
1062					F._afterZoomIn();
1063				}
1064			}
1065		},
1066
1067		zoomOut: function () {
1068			var current = F.current,
1069				endPos;
1070
1071			if (current.closeEffect === 'elastic') {
1072				if (F.wrap.css('position') === 'fixed') {
1073					F.wrap.css(F._getPosition(true));
1074				}
1075
1076				endPos = this.getOrigPosition();
1077
1078				if (current.closeOpacity) {
1079					endPos.opacity = 0;
1080				}
1081
1082				F.wrap.animate(endPos, {
1083					duration: current.closeSpeed,
1084					easing: current.closeEasing,
1085					step: this.step,
1086					complete: F._afterZoomOut
1087				});
1088
1089			} else {
1090				F.wrap.fadeOut(current.closeEffect === 'fade' ? current.closeSpeed : 0, F._afterZoomOut);
1091			}
1092		},
1093
1094		changeIn: function () {
1095			var current = F.current,
1096				startPos;
1097
1098			if (F.current.nextEffect === 'elastic') {
1099				startPos = F._getPosition(true);
1100				startPos.opacity = 0;
1101				startPos.top = (parseInt(startPos.top, 10) - 200) + 'px';
1102
1103				F.wrap.css(startPos).show().animate({
1104					opacity: 1,
1105					top: '+=200px'
1106				}, {
1107					duration: current.nextSpeed,
1108					complete: F._afterZoomIn
1109				});
1110
1111			} else {
1112				F.wrap.css(F._getPosition());
1113
1114				if (current.nextEffect === 'fade') {
1115					F.wrap.hide().fadeIn(current.nextSpeed, F._afterZoomIn);
1116
1117				} else {
1118					F.wrap.show();
1119					F._afterZoomIn();
1120				}
1121			}
1122		},
1123
1124		changeOut: function () {
1125			function cleanUp() {
1126				$(this).trigger('onReset').remove();
1127			}
1128
1129			F.wrap.removeClass('fancybox-opened');
1130
1131			if (F.current.prevEffect === 'elastic') {
1132				F.wrap.animate({
1133					'opacity': 0,
1134					top: '+=200px'
1135				}, {
1136					duration: F.current.prevSpeed,
1137					complete: cleanUp
1138				});
1139
1140			} else {
1141				F.wrap.fadeOut(F.current.prevEffect === 'fade' ? F.current.prevSpeed : 0, cleanUp);
1142			}
1143		}
1144	};
1145
1146	/*
1147	 *	Overlay helper
1148	 */
1149
1150	F.helpers.overlay = {
1151		overlay: null,
1152
1153		update: function () {
1154			var width, scrollWidth, offsetWidth;
1155
1156			//Reset width/height so it will not mess
1157			this.overlay.width(0).height(0);
1158
1159			if ($.browser.msie) {
1160				scrollWidth = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth);
1161				offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
1162
1163				width = scrollWidth < offsetWidth ? W.width() : scrollWidth;
1164
1165			} else {
1166				width = D.width();
1167			}
1168
1169			this.overlay.width(width).height(D.height());
1170		},
1171
1172		beforeShow: function (opts) {
1173			if (this.overlay) {
1174				return;
1175			}
1176
1177			this.overlay = $('<div id="fancybox-overlay"></div>').css(opts.css || {
1178				background: 'black'
1179			}).appendTo('body');
1180
1181			this.update();
1182
1183			if (opts.closeClick) {
1184				this.overlay.bind('click.fb', F.close);
1185			}
1186
1187			W.bind("resize.fb", $.proxy(this.update, this));
1188
1189			this.overlay.fadeTo(opts.speedIn || "fast", opts.opacity || 1);
1190		},
1191
1192		onUpdate: function () {
1193			//Update as content may change document dimensions
1194			this.update();
1195		},
1196
1197		afterClose: function (opts) {
1198			if (this.overlay) {
1199				this.overlay.fadeOut(opts.speedOut || "fast", function () {
1200					$(this).remove();
1201				});
1202			}
1203
1204			this.overlay = null;
1205		}
1206	};
1207
1208	/*
1209	 *	Title helper
1210	 */
1211
1212	F.helpers.title = {
1213		beforeShow: function (opts) {
1214			var title, text = F.current.title;
1215
1216			if (text) {
1217				title = $('<div class="fancybox-title fancybox-title-' + opts.type + '-wrap">' + text + '</div>').appendTo('body');
1218
1219				if (opts.type === 'float') {
1220					//This helps for some browsers
1221					title.width(title.width());
1222
1223					title.wrapInner('<span class="child"></span>');
1224
1225					//Increase bottom margin so this title will also fit into viewport
1226					F.current.margin[2] += Math.abs(parseInt(title.css('margin-bottom'), 10));
1227				}
1228
1229				title.appendTo(opts.type === 'over' ? F.inner : (opts.type === 'outside' ? F.wrap : F.outer));
1230			}
1231		}
1232	};
1233
1234	// jQuery plugin initialization
1235	$.fn.fancybox = function (options) {
1236		var opts = options || {},
1237			selector = this.selector || '';
1238
1239		function run(e) {
1240			var group = [], relType = false, relVal = $(this).data('fancybox-group');
1241
1242			e.preventDefault();
1243
1244			// Check if element has 'data-fancybox-group' attribute, if not - use 'rel'
1245			if (typeof relVal !== 'undefined') {
1246				relType = relVal ? 'data-fancybox-group' : false;
1247
1248			} else if (this.rel && this.rel !== '' && this.rel !== 'nofollow') {
1249				relVal = this.rel;
1250				relType = 'rel';
1251			}
1252
1253			if (relType) {
1254				group = selector.length ? $(selector).filter('[' + relType + '="' + relVal + '"]') : $('[' + relType + '="' + relVal + '"]');
1255			}
1256
1257			if (group.length) {
1258				opts.index = group.index(this);
1259
1260				F.open(group.get(), opts);
1261
1262			} else {
1263				F.open(this, opts);
1264			}
1265
1266			return false;
1267		}
1268
1269		if (selector) {
1270			D.undelegate(selector, 'click.fb-start').delegate(selector, 'click.fb-start', run);
1271
1272		} else {
1273			$(this).unbind('click.fb-start').bind('click.fb-start', run);
1274		}
1275
1276		return this;
1277	};
1278
1279}(window, document, jQuery));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.