Project

General

Profile

Download (27.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/*!
2
	Colorbox v1.4.22 - 2013-06-19
3
	jQuery lightbox and modal window plugin
4
	(c) 2013 Jack Moore - http://www.jacklmoore.com/colorbox
5
	license: http://www.opensource.org/licenses/mit-license.php
6
*/
7
(function ($, document, window) {
8
	var
9
	// Default settings object.
10
	// See http://jacklmoore.com/colorbox for details.
11
	defaults = {
12
		transition: "elastic",
13
		speed: 300,
14
		fadeOut: 300,
15
		width: false,
16
		initialWidth: "600",
17
		innerWidth: false,
18
		maxWidth: false,
19
		height: false,
20
		initialHeight: "450",
21
		innerHeight: false,
22
		maxHeight: false,
23
		scalePhotos: true,
24
		scrolling: true,
25
		inline: false,
26
		html: false,
27
		iframe: false,
28
		fastIframe: true,
29
		photo: false,
30
		href: false,
31
		title: false,
32
		rel: false,
33
		opacity: 0.9,
34
		preloading: true,
35
		className: false,
36

    
37
		// alternate image paths for high-res displays
38
		retinaImage: false,
39
		retinaUrl: false,
40
		retinaSuffix: '@2x.$1',
41

    
42
		// internationalization
43
		current: "image {current} of {total}",
44
		previous: "previous",
45
		next: "next",
46
		close: "close",
47
		xhrError: "This content failed to load.",
48
		imgError: "This image failed to load.",
49

    
50
		open: false,
51
		returnFocus: true,
52
		trapFocus: true,
53
		reposition: true,
54
		loop: true,
55
		slideshow: false,
56
		slideshowAuto: true,
57
		slideshowSpeed: 2500,
58
		slideshowStart: "start slideshow",
59
		slideshowStop: "stop slideshow",
60
		photoRegex: /\.(gif|png|jp(e|g|eg)|bmp|ico|webp)((#|\?).*)?$/i,
61

    
62
		onOpen: false,
63
		onLoad: false,
64
		onComplete: false,
65
		onCleanup: false,
66
		onClosed: false,
67
		overlayClose: true,
68
		escKey: true,
69
		arrowKey: true,
70
		top: false,
71
		bottom: false,
72
		left: false,
73
		right: false,
74
		fixed: false,
75
		data: undefined
76
	},
77
	
78
	// Abstracting the HTML and event identifiers for easy rebranding
79
	colorbox = 'colorbox',
80
	prefix = 'cbox',
81
	boxElement = prefix + 'Element',
82
	
83
	// Events
84
	event_open = prefix + '_open',
85
	event_load = prefix + '_load',
86
	event_complete = prefix + '_complete',
87
	event_cleanup = prefix + '_cleanup',
88
	event_closed = prefix + '_closed',
89
	event_purge = prefix + '_purge',
90

    
91
	// Cached jQuery Object Variables
92
	$overlay,
93
	$box,
94
	$wrap,
95
	$content,
96
	$topBorder,
97
	$leftBorder,
98
	$rightBorder,
99
	$bottomBorder,
100
	$related,
101
	$window,
102
	$loaded,
103
	$loadingBay,
104
	$loadingOverlay,
105
	$title,
106
	$current,
107
	$slideshow,
108
	$next,
109
	$prev,
110
	$close,
111
	$groupControls,
112
	$events = $('<a/>'),
113
	
114
	// Variables for cached values or use across multiple functions
115
	settings,
116
	interfaceHeight,
117
	interfaceWidth,
118
	loadedHeight,
119
	loadedWidth,
120
	element,
121
	index,
122
	photo,
123
	open,
124
	active,
125
	closing,
126
	loadingTimer,
127
	publicMethod,
128
	div = "div",
129
	className,
130
	requests = 0,
131
	init;
132

    
133
	// ****************
134
	// HELPER FUNCTIONS
135
	// ****************
136
	
137
	// Convenience function for creating new jQuery objects
138
	function $tag(tag, id, css) {
139
		var element = document.createElement(tag);
140

    
141
		if (id) {
142
			element.id = prefix + id;
143
		}
144

    
145
		if (css) {
146
			element.style.cssText = css;
147
		}
148

    
149
		return $(element);
150
	}
151
	
152
	// Get the window height using innerHeight when available to avoid an issue with iOS
153
	// http://bugs.jquery.com/ticket/6724
154
	function winheight() {
155
		return window.innerHeight ? window.innerHeight : $(window).height();
156
	}
157

    
158
	// Determine the next and previous members in a group.
159
	function getIndex(increment) {
160
		var
161
		max = $related.length,
162
		newIndex = (index + increment) % max;
163
		
164
		return (newIndex < 0) ? max + newIndex : newIndex;
165
	}
166

    
167
	// Convert '%' and 'px' values to integers
168
	function setSize(size, dimension) {
169
		return Math.round((/%/.test(size) ? ((dimension === 'x' ? $window.width() : winheight()) / 100) : 1) * parseInt(size, 10));
170
	}
171
	
172
	// Checks an href to see if it is a photo.
173
	// There is a force photo option (photo: true) for hrefs that cannot be matched by the regex.
174
	function isImage(settings, url) {
175
		return settings.photo || settings.photoRegex.test(url);
176
	}
177

    
178
	function retinaUrl(settings, url) {
179
		return settings.retinaUrl && window.devicePixelRatio > 1 ? url.replace(settings.photoRegex, settings.retinaSuffix) : url;
180
	}
181

    
182
	function trapFocus(e) {
183
		if ('contains' in $box[0] && !$box[0].contains(e.target)) {
184
			e.stopPropagation();
185
			$box.focus();
186
		}
187
	}
188

    
189
	// Assigns function results to their respective properties
190
	function makeSettings() {
191
		var i,
192
			data = $.data(element, colorbox);
193
		
194
		if (data == null) {
195
			settings = $.extend({}, defaults);
196
			if (console && console.log) {
197
				console.log('Error: cboxElement missing settings object');
198
			}
199
		} else {
200
			settings = $.extend({}, data);
201
		}
202
		
203
		for (i in settings) {
204
			if ($.isFunction(settings[i]) && i.slice(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time.
205
				settings[i] = settings[i].call(element);
206
			}
207
		}
208
		
209
		settings.rel = settings.rel || element.rel || $(element).data('rel') || 'nofollow';
210
		settings.href = settings.href || $(element).attr('href');
211
		settings.title = settings.title || element.title;
212
		
213
		if (typeof settings.href === "string") {
214
			settings.href = $.trim(settings.href);
215
		}
216
	}
217

    
218
	function trigger(event, callback) {
219
		// for external use
220
		$(document).trigger(event);
221

    
222
		// for internal use
223
		$events.trigger(event);
224

    
225
		if ($.isFunction(callback)) {
226
			callback.call(element);
227
		}
228
	}
229

    
230
	// Slideshow functionality
231
	function slideshow() {
232
		var
233
		timeOut,
234
		className = prefix + "Slideshow_",
235
		click = "click." + prefix,
236
		clear,
237
		set,
238
		start,
239
		stop;
240
		
241
		if (settings.slideshow && $related[1]) {
242
			clear = function () {
243
				clearTimeout(timeOut);
244
			};
245

    
246
			set = function () {
247
				if (settings.loop || $related[index + 1]) {
248
					timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
249
				}
250
			};
251

    
252
			start = function () {
253
				$slideshow
254
					.html(settings.slideshowStop)
255
					.unbind(click)
256
					.one(click, stop);
257

    
258
				$events
259
					.bind(event_complete, set)
260
					.bind(event_load, clear)
261
					.bind(event_cleanup, stop);
262

    
263
				$box.removeClass(className + "off").addClass(className + "on");
264
			};
265
			
266
			stop = function () {
267
				clear();
268
				
269
				$events
270
					.unbind(event_complete, set)
271
					.unbind(event_load, clear)
272
					.unbind(event_cleanup, stop);
273
				
274
				$slideshow
275
					.html(settings.slideshowStart)
276
					.unbind(click)
277
					.one(click, function () {
278
						publicMethod.next();
279
						start();
280
					});
281

    
282
				$box.removeClass(className + "on").addClass(className + "off");
283
			};
284
			
285
			if (settings.slideshowAuto) {
286
				start();
287
			} else {
288
				stop();
289
			}
290
		} else {
291
			$box.removeClass(className + "off " + className + "on");
292
		}
293
	}
294

    
295
	function launch(target) {
296
		if (!closing) {
297
			
298
			element = target;
299
			
300
			makeSettings();
301
			
302
			$related = $(element);
303
			
304
			index = 0;
305
			
306
			if (settings.rel !== 'nofollow') {
307
				$related = $('.' + boxElement).filter(function () {
308
					var data = $.data(this, colorbox),
309
						relRelated;
310

    
311
					if (data) {
312
						relRelated =  $(this).data('rel') || data.rel || this.rel;
313
					}
314
					
315
					return (relRelated === settings.rel);
316
				});
317
				index = $related.index(element);
318
				
319
				// Check direct calls to Colorbox.
320
				if (index === -1) {
321
					$related = $related.add(element);
322
					index = $related.length - 1;
323
				}
324
			}
325
			
326
			$overlay.css({
327
				opacity: parseFloat(settings.opacity),
328
				cursor: settings.overlayClose ? "pointer" : "auto",
329
				visibility: 'visible'
330
			}).show();
331
			
332

    
333
			if (className) {
334
				$box.add($overlay).removeClass(className);
335
			}
336
			if (settings.className) {
337
				$box.add($overlay).addClass(settings.className);
338
			}
339
			className = settings.className;
340

    
341
			$close.html(settings.close).show();
342

    
343
			if (!open) {
344
				open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys.
345
				
346
				// Show colorbox so the sizes can be calculated in older versions of jQuery
347
				$box.css({visibility:'hidden', display:'block'});
348
				
349
				$loaded = $tag(div, 'LoadedContent', 'width:0; height:0; overflow:hidden').appendTo($content);
350

    
351
				// Cache values needed for size calculations
352
				interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();
353
				interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();
354
				loadedHeight = $loaded.outerHeight(true);
355
				loadedWidth = $loaded.outerWidth(true);
356
				
357
				
358
				// Opens inital empty Colorbox prior to content being loaded.
359
				settings.w = setSize(settings.initialWidth, 'x');
360
				settings.h = setSize(settings.initialHeight, 'y');
361
				publicMethod.position();
362

    
363
				slideshow();
364

    
365
				trigger(event_open, settings.onOpen);
366
				
367
				$groupControls.add($title).hide();
368

    
369
				$box.focus();
370
				
371

    
372
				if (settings.trapFocus) {
373
					// Confine focus to the modal
374
					// Uses event capturing that is not supported in IE8-
375
					if (document.addEventListener) {
376

    
377
						document.addEventListener('focus', trapFocus, true);
378
						
379
						$events.one(event_closed, function () {
380
							document.removeEventListener('focus', trapFocus, true);
381
						});
382
					}
383
				}
384

    
385
				// Return focus on closing
386
				if (settings.returnFocus) {
387
					$events.one(event_closed, function () {
388
						$(element).focus();
389
					});
390
				}
391
			}
392
			
393
			load();
394
		}
395
	}
396

    
397
	// Colorbox's markup needs to be added to the DOM prior to being called
398
	// so that the browser will go ahead and load the CSS background images.
399
	function appendHTML() {
400
		if (!$box && document.body) {
401
			init = false;
402
			$window = $(window);
403
			$box = $tag(div).attr({
404
				id: colorbox,
405
				'class': $.support.opacity === false ? prefix + 'IE' : '', // class for optional IE8 & lower targeted CSS.
406
				role: 'dialog',
407
				tabindex: '-1'
408
			}).hide();
409
			$overlay = $tag(div, "Overlay").hide();
410
			$loadingOverlay = $tag(div, "LoadingOverlay").add($tag(div, "LoadingGraphic"));
411
			$wrap = $tag(div, "Wrapper");
412
			$content = $tag(div, "Content").append(
413
				$title = $tag(div, "Title"),
414
				$current = $tag(div, "Current"),
415
				$prev = $('<button type="button"/>').attr({id:prefix+'Previous'}),
416
				$next = $('<button type="button"/>').attr({id:prefix+'Next'}),
417
				$slideshow = $tag('button', "Slideshow"),
418
				$loadingOverlay,
419
				$close = $('<button type="button"/>').attr({id:prefix+'Close'})
420
			);
421
			
422
			$wrap.append( // The 3x3 Grid that makes up Colorbox
423
				$tag(div).append(
424
					$tag(div, "TopLeft"),
425
					$topBorder = $tag(div, "TopCenter"),
426
					$tag(div, "TopRight")
427
				),
428
				$tag(div, false, 'clear:left').append(
429
					$leftBorder = $tag(div, "MiddleLeft"),
430
					$content,
431
					$rightBorder = $tag(div, "MiddleRight")
432
				),
433
				$tag(div, false, 'clear:left').append(
434
					$tag(div, "BottomLeft"),
435
					$bottomBorder = $tag(div, "BottomCenter"),
436
					$tag(div, "BottomRight")
437
				)
438
			).find('div div').css({'float': 'left'});
439
			
440
			$loadingBay = $tag(div, false, 'position:absolute; width:9999px; visibility:hidden; display:none');
441
			
442
			$groupControls = $next.add($prev).add($current).add($slideshow);
443

    
444
			$(document.body).append($overlay, $box.append($wrap, $loadingBay));
445
		}
446
	}
447

    
448
	// Add Colorbox's event bindings
449
	function addBindings() {
450
		function clickHandler(e) {
451
			// ignore non-left-mouse-clicks and clicks modified with ctrl / command, shift, or alt.
452
			// See: http://jacklmoore.com/notes/click-events/
453
			if (!(e.which > 1 || e.shiftKey || e.altKey || e.metaKey || e.ctrlKey)) {
454
				e.preventDefault();
455
				launch(this);
456
			}
457
		}
458

    
459
		if ($box) {
460
			if (!init) {
461
				init = true;
462

    
463
				// Anonymous functions here keep the public method from being cached, thereby allowing them to be redefined on the fly.
464
				$next.click(function () {
465
					publicMethod.next();
466
				});
467
				$prev.click(function () {
468
					publicMethod.prev();
469
				});
470
				$close.click(function () {
471
					publicMethod.close();
472
				});
473
				$overlay.click(function () {
474
					if (settings.overlayClose) {
475
						publicMethod.close();
476
					}
477
				});
478
				
479
				// Key Bindings
480
				$(document).bind('keydown.' + prefix, function (e) {
481
					var key = e.keyCode;
482
					if (open && settings.escKey && key === 27) {
483
						e.preventDefault();
484
						publicMethod.close();
485
					}
486
					if (open && settings.arrowKey && $related[1] && !e.altKey) {
487
						if (key === 37) {
488
							e.preventDefault();
489
							$prev.click();
490
						} else if (key === 39) {
491
							e.preventDefault();
492
							$next.click();
493
						}
494
					}
495
				});
496

    
497
				if ($.isFunction($.fn.on)) {
498
					// For jQuery 1.7+
499
					$(document).on('click.'+prefix, '.'+boxElement, clickHandler);
500
				} else {
501
					// For jQuery 1.3.x -> 1.6.x
502
					// This code is never reached in jQuery 1.9, so do not contact me about 'live' being removed.
503
					// This is not here for jQuery 1.9, it's here for legacy users.
504
					$('.'+boxElement).live('click.'+prefix, clickHandler);
505
				}
506
			}
507
			return true;
508
		}
509
		return false;
510
	}
511

    
512
	// Don't do anything if Colorbox already exists.
513
	if ($.colorbox) {
514
		return;
515
	}
516

    
517
	// Append the HTML when the DOM loads
518
	$(appendHTML);
519

    
520

    
521
	// ****************
522
	// PUBLIC FUNCTIONS
523
	// Usage format: $.colorbox.close();
524
	// Usage from within an iframe: parent.jQuery.colorbox.close();
525
	// ****************
526
	
527
	publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {
528
		var $this = this;
529
		
530
		options = options || {};
531
		
532
		appendHTML();
533

    
534
		if (addBindings()) {
535
			if ($.isFunction($this)) { // assume a call to $.colorbox
536
				$this = $('<a/>');
537
				options.open = true;
538
			} else if (!$this[0]) { // colorbox being applied to empty collection
539
				return $this;
540
			}
541
			
542
			if (callback) {
543
				options.onComplete = callback;
544
			}
545
			
546
			$this.each(function () {
547
				$.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options));
548
			}).addClass(boxElement);
549
			
550
			if (($.isFunction(options.open) && options.open.call($this)) || options.open) {
551
				launch($this[0]);
552
			}
553
		}
554
		
555
		return $this;
556
	};
557

    
558
	publicMethod.position = function (speed, loadedCallback) {
559
		var
560
		css,
561
		top = 0,
562
		left = 0,
563
		offset = $box.offset(),
564
		scrollTop,
565
		scrollLeft;
566
		
567
		$window.unbind('resize.' + prefix);
568

    
569
		// remove the modal so that it doesn't influence the document width/height
570
		$box.css({top: -9e4, left: -9e4});
571

    
572
		scrollTop = $window.scrollTop();
573
		scrollLeft = $window.scrollLeft();
574

    
575
		if (settings.fixed) {
576
			offset.top -= scrollTop;
577
			offset.left -= scrollLeft;
578
			$box.css({position: 'fixed'});
579
		} else {
580
			top = scrollTop;
581
			left = scrollLeft;
582
			$box.css({position: 'absolute'});
583
		}
584

    
585
		// keeps the top and left positions within the browser's viewport.
586
		if (settings.right !== false) {
587
			left += Math.max($window.width() - settings.w - loadedWidth - interfaceWidth - setSize(settings.right, 'x'), 0);
588
		} else if (settings.left !== false) {
589
			left += setSize(settings.left, 'x');
590
		} else {
591
			left += Math.round(Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2);
592
		}
593
		
594
		if (settings.bottom !== false) {
595
			top += Math.max(winheight() - settings.h - loadedHeight - interfaceHeight - setSize(settings.bottom, 'y'), 0);
596
		} else if (settings.top !== false) {
597
			top += setSize(settings.top, 'y');
598
		} else {
599
			top += Math.round(Math.max(winheight() - settings.h - loadedHeight - interfaceHeight, 0) / 2);
600
		}
601

    
602
		$box.css({top: offset.top, left: offset.left, visibility:'visible'});
603

    
604
		// setting the speed to 0 to reduce the delay between same-sized content.
605
		speed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed || 0;
606
		
607
		// this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,
608
		// but it has to be shrank down around the size of div#colorbox when it's done.  If not,
609
		// it can invoke an obscure IE bug when using iframes.
610
		$wrap[0].style.width = $wrap[0].style.height = "9999px";
611
		
612
		function modalDimensions(that) {
613
			$topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = (parseInt(that.style.width,10) - interfaceWidth)+'px';
614
			$content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = (parseInt(that.style.height,10) - interfaceHeight)+'px';
615
		}
616

    
617
		css = {width: settings.w + loadedWidth + interfaceWidth, height: settings.h + loadedHeight + interfaceHeight, top: top, left: left};
618

    
619
		if(speed===0){ // temporary workaround to side-step jQuery-UI 1.8 bug (http://bugs.jquery.com/ticket/12273)
620
			$box.css(css);
621
		}
622
		$box.dequeue().animate(css, {
623
			duration: speed,
624
			complete: function () {
625
				modalDimensions(this);
626
				
627
				active = false;
628
				
629
				// shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation.
630
				$wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px";
631
				$wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px";
632
				
633
				if (settings.reposition) {
634
					setTimeout(function () {  // small delay before binding onresize due to an IE8 bug.
635
						$window.bind('resize.' + prefix, publicMethod.position);
636
					}, 1);
637
				}
638

    
639
				if (loadedCallback) {
640
					loadedCallback();
641
				}
642
			},
643
			step: function () {
644
				modalDimensions(this);
645
			}
646
		});
647
	};
648

    
649
	publicMethod.resize = function (options) {
650
		var scrolltop;
651
		
652
		if (open) {
653
			options = options || {};
654
			
655
			if (options.width) {
656
				settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth;
657
			}
658

    
659
			if (options.innerWidth) {
660
				settings.w = setSize(options.innerWidth, 'x');
661
			}
662

    
663
			$loaded.css({width: settings.w});
664
			
665
			if (options.height) {
666
				settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight;
667
			}
668

    
669
			if (options.innerHeight) {
670
				settings.h = setSize(options.innerHeight, 'y');
671
			}
672

    
673
			if (!options.innerHeight && !options.height) {
674
				scrolltop = $loaded.scrollTop();
675
				$loaded.css({height: "auto"});
676
				settings.h = $loaded.height();
677
			}
678

    
679
			$loaded.css({height: settings.h});
680

    
681
			if(scrolltop) {
682
				$loaded.scrollTop(scrolltop);
683
			}
684
			
685
			publicMethod.position(settings.transition === "none" ? 0 : settings.speed);
686
		}
687
	};
688

    
689
	publicMethod.prep = function (object) {
690
		if (!open) {
691
			return;
692
		}
693
		
694
		var callback, speed = settings.transition === "none" ? 0 : settings.speed;
695

    
696
		$loaded.empty().remove(); // Using empty first may prevent some IE7 issues.
697

    
698
		$loaded = $tag(div, 'LoadedContent').append(object);
699
		
700
		function getWidth() {
701
			settings.w = settings.w || $loaded.width();
702
			settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w;
703
			return settings.w;
704
		}
705
		function getHeight() {
706
			settings.h = settings.h || $loaded.height();
707
			settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h;
708
			return settings.h;
709
		}
710
		
711
		$loaded.hide()
712
		.appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations.
713
		.css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'})
714
		.css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height.
715
		.prependTo($content);
716
		
717
		$loadingBay.hide();
718
		
719
		// floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width.
720
		
721
		$(photo).css({'float': 'none'});
722

    
723
		callback = function () {
724
			var total = $related.length,
725
				iframe,
726
				frameBorder = 'frameBorder',
727
				allowTransparency = 'allowTransparency',
728
				complete;
729
			
730
			if (!open) {
731
				return;
732
			}
733
			
734
			function removeFilter() { // Needed for IE7 & IE8 in versions of jQuery prior to 1.7.2
735
				if ($.support.opacity === false) {
736
					$box[0].style.removeAttribute('filter');
737
				}
738
			}
739
			
740
			complete = function () {
741
				clearTimeout(loadingTimer);
742
				$loadingOverlay.hide();
743
				trigger(event_complete, settings.onComplete);
744
			};
745

    
746
			
747
			$title.html(settings.title).add($loaded).show();
748
			
749
			if (total > 1) { // handle grouping
750
				if (typeof settings.current === "string") {
751
					$current.html(settings.current.replace('{current}', index + 1).replace('{total}', total)).show();
752
				}
753
				
754
				$next[(settings.loop || index < total - 1) ? "show" : "hide"]().html(settings.next);
755
				$prev[(settings.loop || index) ? "show" : "hide"]().html(settings.previous);
756
				
757
				if (settings.slideshow) {
758
					$slideshow.show();
759
				}
760
				
761
				// Preloads images within a rel group
762
				if (settings.preloading) {
763
					$.each([getIndex(-1), getIndex(1)], function(){
764
						var src,
765
							img,
766
							i = $related[this],
767
							data = $.data(i, colorbox);
768

    
769
						if (data && data.href) {
770
							src = data.href;
771
							if ($.isFunction(src)) {
772
								src = src.call(i);
773
							}
774
						} else {
775
							src = $(i).attr('href');
776
						}
777

    
778
						if (src && isImage(data, src)) {
779
							src = retinaUrl(data, src);
780
							img = document.createElement('img');
781
							img.src = src;
782
						}
783
					});
784
				}
785
			} else {
786
				$groupControls.hide();
787
			}
788
			
789
			if (settings.iframe) {
790
				iframe = $tag('iframe')[0];
791
				
792
				if (frameBorder in iframe) {
793
					iframe[frameBorder] = 0;
794
				}
795
				
796
				if (allowTransparency in iframe) {
797
					iframe[allowTransparency] = "true";
798
				}
799

    
800
				if (!settings.scrolling) {
801
					iframe.scrolling = "no";
802
				}
803
				
804
				$(iframe)
805
					.attr({
806
						src: settings.href,
807
						name: (new Date()).getTime(), // give the iframe a unique name to prevent caching
808
						'class': prefix + 'Iframe',
809
						allowFullScreen : true, // allow HTML5 video to go fullscreen
810
						webkitAllowFullScreen : true,
811
						mozallowfullscreen : true
812
					})
813
					.one('load', complete)
814
					.appendTo($loaded);
815
				
816
				$events.one(event_purge, function () {
817
					iframe.src = "//about:blank";
818
				});
819

    
820
				if (settings.fastIframe) {
821
					$(iframe).trigger('load');
822
				}
823
			} else {
824
				complete();
825
			}
826
			
827
			if (settings.transition === 'fade') {
828
				$box.fadeTo(speed, 1, removeFilter);
829
			} else {
830
				removeFilter();
831
			}
832
		};
833
		
834
		if (settings.transition === 'fade') {
835
			$box.fadeTo(speed, 0, function () {
836
				publicMethod.position(0, callback);
837
			});
838
		} else {
839
			publicMethod.position(speed, callback);
840
		}
841
	};
842

    
843
	function load () {
844
		var href, setResize, prep = publicMethod.prep, $inline, request = ++requests;
845
		
846
		active = true;
847
		
848
		photo = false;
849
		
850
		element = $related[index];
851
		
852
		makeSettings();
853
		
854
		trigger(event_purge);
855
		
856
		trigger(event_load, settings.onLoad);
857
		
858
		settings.h = settings.height ?
859
				setSize(settings.height, 'y') - loadedHeight - interfaceHeight :
860
				settings.innerHeight && setSize(settings.innerHeight, 'y');
861
		
862
		settings.w = settings.width ?
863
				setSize(settings.width, 'x') - loadedWidth - interfaceWidth :
864
				settings.innerWidth && setSize(settings.innerWidth, 'x');
865
		
866
		// Sets the minimum dimensions for use in image scaling
867
		settings.mw = settings.w;
868
		settings.mh = settings.h;
869
		
870
		// Re-evaluate the minimum width and height based on maxWidth and maxHeight values.
871
		// If the width or height exceed the maxWidth or maxHeight, use the maximum values instead.
872
		if (settings.maxWidth) {
873
			settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth;
874
			settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw;
875
		}
876
		if (settings.maxHeight) {
877
			settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight;
878
			settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh;
879
		}
880
		
881
		href = settings.href;
882
		
883
		loadingTimer = setTimeout(function () {
884
			$loadingOverlay.show();
885
		}, 100);
886
		
887
		if (settings.inline) {
888
			// Inserts an empty placeholder where inline content is being pulled from.
889
			// An event is bound to put inline content back when Colorbox closes or loads new content.
890
			$inline = $tag(div).hide().insertBefore($(href)[0]);
891

    
892
			$events.one(event_purge, function () {
893
				$inline.replaceWith($loaded.children());
894
			});
895

    
896
			prep($(href));
897
		} else if (settings.iframe) {
898
			// IFrame element won't be added to the DOM until it is ready to be displayed,
899
			// to avoid problems with DOM-ready JS that might be trying to run in that iframe.
900
			prep(" ");
901
		} else if (settings.html) {
902
			prep(settings.html);
903
		} else if (isImage(settings, href)) {
904

    
905
			href = retinaUrl(settings, href);
906

    
907
			photo = document.createElement('img');
908

    
909
			$(photo)
910
			.addClass(prefix + 'Photo')
911
			.bind('error',function () {
912
				settings.title = false;
913
				prep($tag(div, 'Error').html(settings.imgError));
914
			})
915
			.one('load', function () {
916
				var percent;
917

    
918
				if (request !== requests) {
919
					return;
920
				}
921

    
922
				photo.alt = $(element).attr('alt') || $(element).attr('data-alt') || '';
923

    
924
				if (settings.retinaImage && window.devicePixelRatio > 1) {
925
					photo.height = photo.height / window.devicePixelRatio;
926
					photo.width = photo.width / window.devicePixelRatio;
927
				}
928

    
929
				if (settings.scalePhotos) {
930
					setResize = function () {
931
						photo.height -= photo.height * percent;
932
						photo.width -= photo.width * percent;
933
					};
934
					if (settings.mw && photo.width > settings.mw) {
935
						percent = (photo.width - settings.mw) / photo.width;
936
						setResize();
937
					}
938
					if (settings.mh && photo.height > settings.mh) {
939
						percent = (photo.height - settings.mh) / photo.height;
940
						setResize();
941
					}
942
				}
943
				
944
				if (settings.h) {
945
					photo.style.marginTop = Math.max(settings.mh - photo.height, 0) / 2 + 'px';
946
				}
947
				
948
				if ($related[1] && (settings.loop || $related[index + 1])) {
949
					photo.style.cursor = 'pointer';
950
					photo.onclick = function () {
951
						publicMethod.next();
952
					};
953
				}
954

    
955
				photo.style.width = photo.width + 'px';
956
				photo.style.height = photo.height + 'px';
957

    
958
				setTimeout(function () { // A pause because Chrome will sometimes report a 0 by 0 size otherwise.
959
					prep(photo);
960
				}, 1);
961
			});
962
			
963
			setTimeout(function () { // A pause because Opera 10.6+ will sometimes not run the onload function otherwise.
964
				photo.src = href;
965
			}, 1);
966
		} else if (href) {
967
			$loadingBay.load(href, settings.data, function (data, status) {
968
				if (request === requests) {
969
					prep(status === 'error' ? $tag(div, 'Error').html(settings.xhrError) : $(this).contents());
970
				}
971
			});
972
		}
973
	}
974
		
975
	// Navigates to the next page/image in a set.
976
	publicMethod.next = function () {
977
		if (!active && $related[1] && (settings.loop || $related[index + 1])) {
978
			index = getIndex(1);
979
			launch($related[index]);
980
		}
981
	};
982
	
983
	publicMethod.prev = function () {
984
		if (!active && $related[1] && (settings.loop || index)) {
985
			index = getIndex(-1);
986
			launch($related[index]);
987
		}
988
	};
989

    
990
	// Note: to use this within an iframe use the following format: parent.jQuery.colorbox.close();
991
	publicMethod.close = function () {
992
		if (open && !closing) {
993
			
994
			closing = true;
995
			
996
			open = false;
997
			
998
			trigger(event_cleanup, settings.onCleanup);
999
			
1000
			$window.unbind('.' + prefix);
1001
			
1002
			$overlay.fadeTo(settings.fadeOut || 0, 0);
1003
			
1004
			$box.stop().fadeTo(settings.fadeOut || 0, 0, function () {
1005
			
1006
				$box.add($overlay).css({'opacity': 1, cursor: 'auto'}).hide();
1007
				
1008
				trigger(event_purge);
1009
				
1010
				$loaded.empty().remove(); // Using empty first may prevent some IE7 issues.
1011
				
1012
				setTimeout(function () {
1013
					closing = false;
1014
					trigger(event_closed, settings.onClosed);
1015
				}, 1);
1016
			});
1017
		}
1018
	};
1019

    
1020
	// Removes changes Colorbox made to the document, but does not remove the plugin.
1021
	publicMethod.remove = function () {
1022
		if (!$box) { return; }
1023

    
1024
		$box.stop();
1025
		$.colorbox.close();
1026
		$box.stop().remove();
1027
		$overlay.remove();
1028
		closing = false;
1029
		$box = null;
1030
		$('.' + boxElement)
1031
			.removeData(colorbox)
1032
			.removeClass(boxElement);
1033

    
1034
		$(document).unbind('click.'+prefix);
1035
	};
1036

    
1037
	// A method for fetching the current element Colorbox is referencing.
1038
	// returns a jQuery object.
1039
	publicMethod.element = function () {
1040
		return $(element);
1041
	};
1042

    
1043
	publicMethod.settings = defaults;
1044

    
1045
}(jQuery, document, window));
(5-5/5)