PageSourceSearch

https://www.crillonlebrave.fr/typo3conf/ext/arc_projet/Resources/P…/libs/lightcase/js/lightcase.js?1677853379

js crillonlebrave.fr collected 2026-10-02 18:03:37 UTC 48,395 bytes, 1,773 lines download raw bytes

1/*
2 * Lightcase - jQuery Plugin
3 * The smart and flexible Lightbox Plugin.
4 *
5 * @author		Cornel Boppart <[email protected]>
6 * @copyright	Author
7 *
8 * @version		2.3.4 (29/12/2015)
9 */
10
11;(function ($) {
12
13	'use strict';
14
15	var _self = {
16		cache: {},
17
18		support: {},
19
20		objects: {},
21
22		/**
23		 * Initializes the plugin
24		 *
25		 * @param	{object}	options
26		 * @return	{object}
27		 */
28		init: function (options) {
29			return this.each(function () {
30				$(this).unbind('click.lightcase').bind('click.lightcase', function (event) {
31					event.preventDefault();
32					$(this).lightcase('start', options);
33				});
34			});
35		},
36
37		/**
38		 * Starts the plugin
39		 *
40		 * @param	{object}	options
41		 * @return	{void}
42		 */
43		start: function (options) {
44			_self.origin = lightcase.origin = this;
45
46			_self.settings = lightcase.settings = $.extend(true, {
47				idPrefix: 'lightcase-',
48				classPrefix: 'lightcase-',
49				attrPrefix: 'lc-',
50				transition: 'elastic',
51				transitionIn: null,
52				transitionOut: null,
53				cssTransitions: true,
54				speedIn: 250,
55				speedOut: 250,
56				maxWidth: 800,
57				maxHeight: 500,
58				forceWidth: false,
59				forceHeight: false,
60				liveResize: true,
61				fullScreenModeForMobile: true,
62				mobileMatchExpression: /(iphone|ipod|ipad|android|blackberry|symbian)/,
63				disableShrink: false,
64				shrinkFactor: .75,
65				overlayOpacity: .9,
66				slideshow: false,
67				timeout: 5000,
68				swipe: true,
69				useKeys: true,
70				useCategories: true,
71				navigateEndless: true,
72				closeOnOverlayClick: true,
73				title: null,
74				caption: null,
75				showTitle: true,
76				showCaption: true,
77				showSequenceInfo: true,
78				inline: {
79					width: 'auto',
80					height: 'auto'
81				},
82				ajax: {
83					width: 'auto',
84					height: 'auto',
85					type: 'get',
86					dataType: 'html',
87					data: {}
88				},
89				iframe: {
90					width: 800,
91					height: 500,
92					frameborder: 0
93				},
94				flash: {
95					width: 400,
96					height: 205,
97					wmode: 'transparent'
98				},
99				video: {
100					width: 400,
101					height: 225,
102					poster: '',
103					preload: 'auto',
104					controls: true,
105					autobuffer: true,
106					autoplay: true,
107					loop: false
108				},
109				attr: 'data-rel',
110				href: null,
111				type: null,
112				typeMapping: {
113					'image': 'jpg,jpeg,gif,png,bmp',
114					'flash': 'swf',
115					'video': 'mp4,mov,ogv,ogg,webm',
116					'iframe': 'html,php',
117					'ajax': 'json,txt',
118					'inline': '#'
119				},
120				errorMessage: function () {
121					return '<p class="' + _self.settings.classPrefix + 'error">' + _self.settings.labels['errorMessage'] + '</p>';
122				},
123				labels: {
124					'errorMessage': 'Source could not be found...',
125					'sequenceInfo.of': ' / ',
126					'close': 'Close',
127					'navigator.prev': 'Prev',
128					'navigator.next': 'Next',
129 					'navigator.play': 'Play',
130					'navigator.pause': 'Pause'
131				},
132				markup: function () {
133					$('body').append(
134						_self.objects.overlay = $('<div id="' + _self.settings.idPrefix + 'overlay"></div>'),
135						_self.objects.loading = $('<div id="' + _self.settings.idPrefix + 'loading" class="' + _self.settings.classPrefix + 'icon-spin"></div>'),
136						_self.objects.case = $('<div id="' + _self.settings.idPrefix + 'case" aria-hidden="true" role="dialog"></div>')
137					);
138					_self.objects.case.after(
139						_self.objects.nav = $('<div id="' + _self.settings.idPrefix + 'nav"></div>')
140					);
141					_self.objects.nav.append(
142						_self.objects.close = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-close"><span>' + _self.settings.labels['close'] + '</span></a>'),
143						_self.objects.prev = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-prev"><span>' + _self.settings.labels['navigator.prev'] + '</span></a>').hide(),
144						_self.objects.next = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-next"><span>' + _self.settings.labels['navigator.next'] + '</span></a>').hide(),
145						_self.objects.play = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-play"><span>' + _self.settings.labels['navigator.play'] + '</span></a>').hide(),
146						_self.objects.pause = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-pause"><span>' + _self.settings.labels['navigator.pause'] + '</span></a>').hide()
147					);
148					_self.objects.case.append(
149						_self.objects.content = $('<div id="' + _self.settings.idPrefix + 'content"></div>'),
150						_self.objects.info = $('<div id="' + _self.settings.idPrefix + 'info"></div>')
151					);
152					_self.objects.content.append(
153						_self.objects.contentInner = $('<div class="' + _self.settings.classPrefix + 'contentInner"></div>')
154					);
155					_self.objects.info.append(
156						_self.objects.sequenceInfo = $('<div id="' + _self.settings.idPrefix + 'sequenceInfo"></div>'),
157						_self.objects.title = $('<h4 id="' + _self.settings.idPrefix + 'title"></h4>'),
158						_self.objects.caption = $('<p id="' + _self.settings.idPrefix + 'caption"></p>')
159					);
160				},
161				onInit: {},
162				onStart: {},
163				onFinish: {},
164				onClose: {},
165				onCleanup: {}
166			}, options);
167
168			// Call onInit hook functions
169			_self._callHooks(_self.settings.onInit);
170
171			_self.objectData = _self._setObjectData(this);
172
173			_self._cacheScrollPosition();
174			_self._watchScrollInteraction();
175
176			_self._addElements();
177			_self._open();
178
179			_self.dimensions = _self.getViewportDimensions();
180		},
181
182		/**
183		 * Getter method for objects
184		 *
185		 * @param	{string}	name
186		 * @return	{object}
187		 */
188		get: function (name) {
189			return _self.objects[name];
190		},
191
192		/**
193		 * Getter method for objectData
194		 *
195		 * @return	{object}
196		 */
197		getObjectData: function () {
198			return _self.objectData;
199		},
200
201		/**
202		 * Sets the object data
203		 *
204		 * @param	{object}	object
205		 * @return	{object}	objectData
206		 */
207		_setObjectData: function (object) {
208		 	var $object = $(object),
209				objectData = {
210				title: _self.settings.title || $object.attr(_self._prefixAttributeName('title')) || $object.attr('title'),
211				caption: _self.settings.caption || $object.attr(_self._prefixAttributeName('caption')) || $object.children('img').attr('alt'),
212				url: _self._determineUrl(),
213				requestType: _self.settings.ajax.type,
214				requestData: _self.settings.ajax.data,
215				requestDataType: _self.settings.ajax.dataType,
216				rel: $object.attr(_self._determineAttributeSelector()),
217				type: _self.settings.type || _self._verifyDataType(_self._determineUrl()),
218				isPartOfSequence: _self._isPartOfSequence($object.attr(_self.settings.attr), ':'),
219				isPartOfSequenceWithSlideshow: _self._isPartOfSequence($object.attr(_self.settings.attr), ':slideshow'),
220				currentIndex: $(_self._determineAttributeSelector()).index($object),
221				sequenceLength: $(_self._determineAttributeSelector()).length
222			};
223
224			// Add sequence info to objectData
225			objectData.sequenceInfo = (objectData.currentIndex + 1) + _self.settings.labels['sequenceInfo.of'] + objectData.sequenceLength;
226
227			// Add next/prev index
228			objectData.prevIndex = objectData.currentIndex - 1;
229			objectData.nextIndex = objectData.currentIndex + 1;
230
231			return objectData;
232		},
233
234		/**
235		 * Prefixes a data attribute name with defined name from 'settings.attrPrefix'
236		 * to ensure more uniqueness for all lightcase related/used attributes.
237		 *
238		 * @param	{string}	name
239		 * @return	{string}
240		 */
241		_prefixAttributeName: function (name) {
242			return 'data-' + _self.settings.attrPrefix + name;
243		},
244
245		/**
246		 * Determines the link target considering 'settings.href' and data attributes
247		 * but also with a fallback to the default 'href' value.
248		 *
249		 * @return	{string}
250		 */
251		_determineLinkTarget: function () {
252			return _self.settings.href || $(_self.origin).attr(_self._prefixAttributeName('href')) || $(_self.origin).attr('href');
253		},
254
255		/**
256		 * Determines the attribute selector to use, depending on
257		 * whether categorized collections are beeing used or not.
258		 *
259		 * @return	{string}	selector
260		 */
261		_determineAttributeSelector: function () {
262			var	$origin = $(_self.origin),
263				selector = '';
264
265			if (typeof _self.cache.selector !== 'undefined') {
266				selector = _self.cache.selector;
267			} else if (_self.settings.useCategories === true && $origin.attr(_self._prefixAttributeName('categories'))) {
268				var	categories = $origin.attr(_self._prefixAttributeName('categories')).split(' ');
269
270				$.each(categories, function (index, category) {
271					if (index > 0) {
272						selector += ',';
273					}
274					selector += '[' + _self._prefixAttributeName('categories') + '~="' + category + '"]';
275				});
276			} else {
277				selector = '[' + _self.settings.attr + '="' + $origin.attr(_self.settings.attr) + '"]';
278			}
279
280			_self.cache.selector = selector;
281
282			return selector;
283		},
284
285		/**
286		 * Determines the correct resource according to the
287		 * current viewport and density.
288		 *
289		 * @return	{string}	url
290		 */
291		_determineUrl: function () {
292			var dataUrl = _self._verifyDataUrl(_self._determineLinkTarget()),
293				width = 0,
294				density = 0,
295				url;
296
297			$.each(dataUrl, function (index, src) {
298				if (
299					// Check density
300					_self._devicePixelRatio() >= src.density &&
301					src.density >= density &&
302					// Check viewport width
303					_self._matchMedia()('screen and (min-width:' + src.width + 'px)') &&
304					src.width >= width
305				) {
306					width = src.width;
307					density = src.density;
308					url = src.url;
309				}
310			});
311
312			return url;
313		},
314
315		/**
316		 * Normalizes an url and returns information about the resource path,
317		 * the viewport width as well as density if defined.
318		 *
319		 * @param	{string}	url	Path to resource in format of an url or srcset
320		 * @return	{object}
321		 */
322		_normalizeUrl: function (url) {
323			var srcExp = /^\d+$/;
324
325			return url.split(',').map(function (str) {
326				var src = {
327					width: 0,
328					density: 0
329				};
330
331				str.trim().split(/\s+/).forEach(function (url, i) {
332					if (i === 0) {
333						return src.url = url;
334					}
335
336					var value = url.substring(0, url.length - 1),
337						lastChar = url[url.length - 1],
338						intVal = parseInt(value, 10),
339						floatVal = parseFloat(value);
340					if (lastChar === 'w' && srcExp.test(value)) {
341						src.width = intVal;
342					} else if (lastChar === 'h' && srcExp.test(value)) {
343						src.height = intVal;
344					} else if (lastChar === 'x' && !isNaN(floatVal)) {
345						src.density = floatVal;
346					}
347				});
348
349				return src;
350			});
351		},
352
353		/**
354		 * Verifies if the link is part of a sequence
355		 *
356		 * @param	{string}	rel
357		 * @param	{string}	expression
358		 * @return	{boolean}
359		 */
360		_isPartOfSequence: function (rel, expression) {
361			var getSimilarLinks = $('[' + _self.settings.attr + '="' + rel + '"]'),
362				regexp = new RegExp(expression);
363
364			return (regexp.test(rel) && getSimilarLinks.length > 1);
365		},
366
367		/**
368		 * Verifies if the slideshow should be enabled
369		 *
370		 * @return	{boolean}
371		 */
372		isSlideshowEnabled: function () {
373			return (_self.objectData.isPartOfSequence && (_self.settings.slideshow === true || _self.objectData.isPartOfSequenceWithSlideshow === true));
374		},
375
376		/**
377		 * Loads the new content to show
378		 *
379		 * @return	{void}
380		 */
381		_loadContent: function () {
382			if (_self.cache.originalObject) {
383				_self._restoreObject();
384			}
385
386			_self._createObject();
387		},
388
389		/**
390		 * Creates a new object
391		 *
392		 * @return	{void}
393		 */
394		_createObject: function () {
395			var $object;
396
397			// Create object
398			switch (_self.objectData.type) {
399				case 'image':
400					$object = $(new Image());
401					$object.attr({
402						// The time expression is required to prevent the binding of an image load
403						'src': _self.objectData.url,
404						'alt': _self.objectData.title
405					});
406					break;
407				case 'inline':
408					$object = $('<div class="' + _self.settings.classPrefix + 'inlineWrap"></div>');
409					$object.html(_self._cloneObject($(_self.objectData.url)));
410
411					// Add custom attributes from _self.settings
412					$.each(_self.settings.inline, function (name, value) {
413						$object.attr(_self._prefixAttributeName(name), value);
414					});
415					break;
416				case 'ajax':
417					$object = $('<div class="' + _self.settings.classPrefix + 'inlineWrap"></div>');
418
419					// Add custom attributes from _self.settings
420					$.each(_self.settings.ajax, function (name, value) {
421						if (name !== 'data') {
422							$object.attr(_self._prefixAttributeName(name), value);
423						}
424					});
425					break;
426				case 'flash':
427					$object = $('<embed src="' + _self.objectData.url + '" type="application/x-shockwave-flash"></embed>');
428
429					// Add custom attributes from _self.settings
430					$.each(_self.settings.flash, function (name, value) {
431						$object.attr(name, value);
432					});
433					break;
434				case 'video':
435					$object = $('<video></video>');
436					$object.attr('src', _self.objectData.url);
437
438					// Add custom attributes from _self.settings
439					$.each(_self.settings.video, function (name, value) {
440						$object.attr(name, value);
441					});
442					break;
443				default :
444					$object = $('<iframe></iframe>');
445					$object.attr({
446						'src': _self.objectData.url
447					});
448
449					// Add custom attributes from _self.settings
450					$.each(_self.settings.iframe, function (name, value) {
451						$object.attr(name, value);
452					});
453					break;
454			}
455
456			_self._addObject($object);
457			_self._loadObject($object);
458		},
459
460		/**
461		 * Adds the new object to the markup
462		 *
463		 * @param	{object}	$object
464		 * @return	{void}
465		 */
466		_addObject: function ($object) {
467			// Add object to content holder
468			_self.objects.contentInner.html($object);
469
470			// Start loading
471			_self._loading('start');
472
473			// Call onStart hook functions
474			_self._callHooks(_self.settings.onStart);
475
476			// Add sequenceInfo to the content holder or hide if its empty
477			if (_self.settings.showSequenceInfo === true && _self.objectData.isPartOfSequence) {
478				_self.objects.sequenceInfo.html(_self.objectData.sequenceInfo);
479				_self.objects.sequenceInfo.show();
480			} else {
481				_self.objects.sequenceInfo.empty();
482				_self.objects.sequenceInfo.hide();
483			}
484			// Add title to the content holder or hide if its empty
485			if (_self.settings.showTitle === true && _self.objectData.title !== undefined && _self.objectData.title !== '') {
486				_self.objects.title.html(_self.objectData.title);
487				_self.objects.title.show();
488			} else {
489				_self.objects.title.empty();
490				_self.objects.title.hide();
491			}
492			// Add caption to the content holder or hide if its empty
493			if (_self.settings.showCaption === true && _self.objectData.caption !== undefined && _self.objectData.caption !== '') {
494				_self.objects.caption.html(_self.objectData.caption);
495				_self.objects.caption.show();
496			} else {
497				_self.objects.caption.empty();
498				_self.objects.caption.hide();
499			}
500		},
501
502		/**
503		 * Loads the new object
504		 *
505		 * @param	{object}	$object
506		 * @return	{void}
507		 */
508		_loadObject: function ($object) {
509			// Load the object
510			switch (_self.objectData.type) {
511				case 'inline':
512					if ($(_self.objectData.url)) {
513						_self._showContent($object);
514					} else {
515						_self.error();
516					}
517					break;
518				case 'ajax':
519					$.ajax(
520						$.extend({}, _self.settings.ajax, {
521							url: _self.objectData.url,
522							type: _self.objectData.requestType,
523							dataType: _self.objectData.requestDataType,
524							data: _self.objectData.requestData,
525							success: function (data, textStatus, jqXHR) {
526								// Unserialize if data is transferred as json
527								if (_self.objectData.requestDataType === 'json') {
528									_self.objectData.data = data;
529								} else {
530									$object.html(data);
531								}
532								_self._showContent($object);
533							},
534							error: function (jqXHR, textStatus, errorThrown) {
535								_self.error();
536							}
537						})
538					);
539					break;
540				case 'flash':
541					_self._showContent($object);
542					break;
543				case 'video':
544					if (typeof($object.get(0).canPlayType) === 'function' || _self.objects.case.find('video').length === 0) {
545						_self._showContent($object);
546					} else {
547						_self.error();
548					}
549					break;
550				default:
551					if (_self.objectData.url) {
552						$object.load(function () {
553							_self._showContent($object);
554						});
555						$object.error(function () {
556							_self.error();
557						});
558					} else {
559						_self.error();
560					}
561					break;
562			}
563		},
564
565		/**
566		 * Throws an error message if something went wrong
567		 *
568		 * @return	{void}
569		 */
570		error: function () {
571			_self.objectData.type = 'error';
572			var $object = $('<div class="' + _self.settings.classPrefix + 'inlineWrap"></div>');
573
574			$object.html(_self.settings.errorMessage);
575			_self.objects.contentInner.html($object);
576
577			_self._showContent(_self.objects.contentInner);
578		},
579
580		/**
581		 * Calculates the dimensions to fit content
582		 *
583		 * @param	{object}	$object
584		 * @return	{void}
585		 */
586		_calculateDimensions: function ($object) {
587			_self._cleanupDimensions();
588
589			// Set default dimensions
590			var dimensions = {
591				objectWidth: $object.attr('width') ? $object.attr('width') : $object.attr(_self._prefixAttributeName('width')),
592				objectHeight: $object.attr('height') ? $object.attr('height') : $object.attr(_self._prefixAttributeName('height'))
593			};
594
595			if (!_self.settings.disableShrink) {
596				// Add calculated maximum width/height to dimensions
597				dimensions.maxWidth = parseInt(_self.dimensions.windowWidth * _self.settings.shrinkFactor);
598				dimensions.maxHeight = parseInt(_self.dimensions.windowHeight * _self.settings.shrinkFactor);
599
600				// If the auto calculated maxWidth/maxHeight greather than the userdefined one, use that.
601				if (dimensions.maxWidth > _self.settings.maxWidth) {
602					dimensions.maxWidth = _self.settings.maxWidth;
603				}
604				if (dimensions.maxHeight > _self.settings.maxHeight) {
605					dimensions.maxHeight = _self.settings.maxHeight;
606				}
607
608				// Calculate the difference between screen width/height and image width/height
609				dimensions.differenceWidthAsPercent = parseInt(100 / dimensions.maxWidth * dimensions.objectWidth);
610				dimensions.differenceHeightAsPercent = parseInt(100 / dimensions.maxHeight * dimensions.objectHeight);
611
612				switch (_self.objectData.type) {
613					case 'image':
614					case 'flash':
615					case 'video':
616						if (dimensions.differenceWidthAsPercent > 100 && dimensions.differenceWidthAsPercent > dimensions.differenceHeightAsPercent) {
617							dimensions.objectWidth = dimensions.maxWidth;
618							dimensions.objectHeight = parseInt(dimensions.objectHeight / dimensions.differenceWidthAsPercent * 100);
619						}
620						if (dimensions.differenceHeightAsPercent > 100 && dimensions.differenceHeightAsPercent > dimensions.differenceWidthAsPercent) {
621							dimensions.objectWidth = parseInt(dimensions.objectWidth / dimensions.differenceHeightAsPercent * 100);
622							dimensions.objectHeight = dimensions.maxHeight;
623						}
624						if (dimensions.differenceHeightAsPercent > 100 && dimensions.differenceWidthAsPercent < dimensions.differenceHeightAsPercent) {
625							dimensions.objectWidth = parseInt(dimensions.maxWidth / dimensions.differenceHeightAsPercent * dimensions.differenceWidthAsPercent);
626							dimensions.objectHeight = dimensions.maxHeight;
627						}
628						break;
629					case 'error':
630						if (!isNaN(dimensions.objectWidth) && dimensions.objectWidth > dimensions.maxWidth) {
631							dimensions.objectWidth = dimensions.maxWidth;
632						}
633						break;
634					default:
635						if ((isNaN(dimensions.objectWidth) || dimensions.objectWidth > dimensions.maxWidth) && !_self.settings.forceWidth) {
636							dimensions.objectWidth = dimensions.maxWidth;
637						}
638						if (((isNaN(dimensions.objectHeight) && dimensions.objectHeight !== 'auto') || dimensions.objectHeight > dimensions.maxHeight) && !_self.settings.forceHeight) {
639							dimensions.objectHeight = dimensions.maxHeight;
640						}
641						break;
642				}
643			}
644
645			if (_self.settings.forceWidth) {
646				dimensions.maxWidth = dimensions.objectWidth;
647			} else if ($object.attr(_self._prefixAttributeName('max-width'))) {
648				dimensions.maxWidth =  $object.attr(_self._prefixAttributeName('max-width'));
649			}
650
651			if (_self.settings.forceHeight) {
652				dimensions.maxHeight = dimensions.objectHeight;
653			} else if ($object.attr(_self._prefixAttributeName('max-height'))) {
654				dimensions.maxHeight =  $object.attr(_self._prefixAttributeName('max-height'));
655			}
656
657			_self._adjustDimensions($object, dimensions);
658		},
659
660		/**
661		 * Adjusts the dimensions
662		 *
663		 * @param	{object}	$object
664		 * @param	{object}	dimensions
665		 * @return	{void}
666		 */
667		_adjustDimensions: function ($object, dimensions) {
668			// Adjust width and height
669			$object.css({
670				'width': dimensions.objectWidth,
671				'height': dimensions.objectHeight,
672				'max-width': dimensions.maxWidth,
673				'max-height': dimensions.maxHeight
674			});
675
676			_self.objects.contentInner.css({
677				'width': $object.outerWidth(),
678				'height': $object.outerHeight(),
679				'max-width': '100%'
680			});
681
682			_self.objects.case.css({
683				'width': _self.objects.contentInner.outerWidth()
684			});
685
686			// Adjust margin
687			_self.objects.case.css({
688				'margin-top': parseInt(-(_self.objects.case.outerHeight() / 2)),
689				'margin-left': parseInt(-(_self.objects.case.outerWidth() / 2))
690			});
691		},
692
693		/**
694		 * Handles the _loading
695		 *
696		 * @param	{string}	process
697		 * @return	{void}
698		 */
699		_loading: function (process) {
700			if (process === 'start') {
701				_self.objects.case.addClass(_self.settings.classPrefix + 'loading');
702				_self.objects.loading.show();
703			} else if (process === 'end') {
704				_self.objects.case.removeClass(_self.settings.classPrefix + 'loading');
705				_self.objects.loading.hide();
706			}
707		},
708
709
710		/**
711		 * Gets the client screen dimensions
712		 *
713		 * @return	{object}	dimensions
714		 */
715		getViewportDimensions: function () {
716			return {
717				windowWidth: $(window).innerWidth(),
718				windowHeight: $(window).innerHeight()
719			};
720		},
721
722		/**
723		 * Verifies the url
724		 *
725		 * @param	{string}	dataUrl
726		 * @return	{object}	dataUrl	Clean url for processing content
727		 */
728		_verifyDataUrl: function (dataUrl) {
729			if (!dataUrl || dataUrl === undefined || dataUrl === '') {
730				return false;
731			}
732
733			if (dataUrl.indexOf('#') > -1) {
734				dataUrl = dataUrl.split('#');
735				dataUrl = '#' + dataUrl[dataUrl.length - 1];
736			}
737
738			return _self._normalizeUrl(dataUrl.toString());
739		},
740
741		/**
742		 * Verifies the data type of the content to load
743		 *
744		 * @param	{string}			url
745		 * @return	{string|boolean}	Array key if expression matched, else false
746		 */
747		_verifyDataType: function (url) {
748			var typeMapping = _self.settings.typeMapping;
749
750			// Early abort if dataUrl couldn't be verified
751			if (!url) {
752				return false;
753			}
754
755			// Verify the dataType of url according to typeMapping which
756			// has been defined in settings.
757			for (var key in typeMapping) {
758				if (typeMapping.hasOwnProperty(key)) {
759					var suffixArr = typeMapping[key].split(',');
760
761					for (var i = 0; i < suffixArr.length; i++) {
762						var suffix = suffixArr[i].toLowerCase(),
763							regexp = new RegExp('\.(' + suffix + ')$', 'i'),
764							// Verify only the last 5 characters of the string
765							str = url.toLowerCase().split('?')[0].substr(-5);
766
767						if (regexp.test(str) === true || (key === 'inline' && (url.indexOf(suffix) > -1))) {
768							return key;
769						}
770					}
771				}
772			}
773
774			// If no expression matched, return 'iframe'.
775			return 'iframe';
776		},
777
778		/**
779		 * Extends html markup with the essential tags
780		 *
781		 * @return	{void}
782		 */
783		_addElements: function () {
784			if (typeof _self.objects.case !== 'undefined' && $('#' + _self.objects.case.attr('id')).length) {
785				return;
786			}
787
788			_self.settings.markup();
789		},
790
791		/**
792		 * Shows the loaded content
793		 *
794		 * @param	{object}	$object
795		 * @return	{void}
796		 */
797		_showContent: function ($object) {
798			// Add data attribute with the object type
799			_self.objects.case.attr(_self._prefixAttributeName('type'), _self.objectData.type);
800
801			_self.cache.object = $object;
802			_self._calculateDimensions($object);
803
804			// Call onFinish hook functions
805			_self._callHooks(_self.settings.onFinish);
806
807			switch (_self.settings.transitionIn) {
808				case 'scrollTop':
809				case 'scrollRight':
810				case 'scrollBottom':
811				case 'scrollLeft':
812				case 'scrollHorizontal':
813				case 'scrollVertical':
814					_self.transition.scroll(_self.objects.case, 'in', _self.settings.speedIn);
815					_self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn);
816					break;
817				case 'elastic':
818					if (_self.objects.case.css('opacity') < 1) {
819						_self.transition.zoom(_self.objects.case, 'in', _self.settings.speedIn);
820						_self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn);
821					}
822				case 'fade':
823				case 'fadeInline':
824					_self.transition.fade(_self.objects.case, 'in', _self.settings.speedIn);
825					_self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn);
826					break;
827				default:
828					_self.transition.fade(_self.objects.case, 'in', 0);
829					break;
830			}
831
832			// End loading.
833			_self._loading('end');
834			_self.isBusy = false;
835		},
836
837		/**
838		 * Processes the content to show
839		 *
840		 * @return	{void}
841		 */
842		_processContent: function () {
843			_self.isBusy = true;
844
845			switch (_self.settings.transitionOut) {
846				case 'scrollTop':
847				case 'scrollRight':
848				case 'scrollBottom':
849				case 'scrollLeft':
850				case 'scrollVertical':
851				case 'scrollHorizontal':
852					if (_self.objects.case.is(':hidden')) {
853						_self.transition.fade(_self.objects.case, 'out', 0, 0, function () {
854							_self._loadContent();
855						});
856						_self.transition.fade(_self.objects.contentInner, 'out', 0);
857					} else {
858						_self.transition.scroll(_self.objects.case, 'out', _self.settings.speedOut, function () {
859							_self._loadContent();
860						});
861					}
862					break;
863				case 'fade':
864					if (_self.objects.case.is(':hidden')) {
865						_self.transition.fade(_self.objects.case, 'out', 0, 0, function () {
866							_self._loadContent();
867						});
868					} else {
869						_self.transition.fade(_self.objects.case, 'out', _self.settings.speedOut, 0, function () {
870							_self._loadContent();
871						});
872					}
873					break;
874				case 'fadeInline':
875				case 'elastic':
876					if (_self.objects.case.is(':hidden')) {
877						_self.transition.fade(_self.objects.case, 'out', 0, 0, function () {
878							_self._loadContent();
879						});
880					} else {
881						_self.transition.fade(_self.objects.contentInner, 'out', _self.settings.speedOut, 0, function () {
882							_self._loadContent();
883						});
884					}
885					break;
886				default:
887					_self.transition.fade(_self.objects.case, 'out', 0, 0, function () {
888						_self._loadContent();
889					});
890					break;
891			}
892		},
893
894		/**
895		 * Handles events for gallery buttons
896		 *
897		 * @return	{void}
898		 */
899		_handleEvents: function () {
900			_self._unbindEvents();
901
902			_self.objects.nav.children().not(_self.objects.close).hide();
903
904			// If slideshow is enabled, show play/pause and start timeout.
905			if (_self.isSlideshowEnabled()) {
906				// Only start the timeout if slideshow is not pausing
907				if (!_self.objects.nav.hasClass(_self.settings.classPrefix + 'paused')) {
908					_self._startTimeout();
909				} else {
910					_self._stopTimeout();
911				}
912			}
913
914			if (_self.settings.liveResize) {
915				_self._watchResizeInteraction();
916			}
917
918			_self.objects.close.click(function (event) {
919				event.preventDefault();
920				_self.close();
921			});
922
923			if (_self.settings.closeOnOverlayClick === true) {
924				_self.objects.overlay.css('cursor', 'pointer').click(function (event) {
925					event.preventDefault();
926
927					_self.close();
928				});
929			}
930
931			if (_self.settings.useKeys === true) {
932				_self._addKeyEvents();
933			}
934
935			if (_self.objectData.isPartOfSequence) {
936				_self.objects.nav.attr(_self._prefixAttributeName('ispartofsequence'), true);
937				_self.objects.nav.data('items', _self._setNavigation());
938
939				_self.objects.prev.click(function (event) {
940					event.preventDefault();
941
942					if (_self.settings.navigateEndless === true || !_self.item.isFirst()) {
943						_self.objects.prev.unbind('click');
944						_self.cache.action = 'prev';
945						_self.objects.nav.data('items').prev.click();
946
947						if (_self.isSlideshowEnabled()) {
948							_self._stopTimeout();
949						}
950					}
951				});
952
953				_self.objects.next.click(function (event) {
954					event.preventDefault();
955
956					if (_self.settings.navigateEndless === true || !_self.item.isLast()) {
957						_self.objects.next.unbind('click');
958						_self.cache.action = 'next';
959						_self.objects.nav.data('items').next.click();
960
961						if (_self.isSlideshowEnabled()) {
962							_self._stopTimeout();
963						}
964					}
965				});
966
967				if (_self.isSlideshowEnabled()) {
968					_self.objects.play.click(function (event) {
969						event.preventDefault();
970						_self._startTimeout();
971					});
972					_self.objects.pause.click(function (event) {
973						event.preventDefault();
974						_self._stopTimeout();
975					});
976				}
977
978				// Enable swiping if activated
979				if (_self.settings.swipe === true) {
980					if ($.isPlainObject($.event.special.swipeleft)) {
981						_self.objects.case.on('swipeleft', function (event) {
982							event.preventDefault();
983							_self.objects.next.click();
984							if (_self.isSlideshowEnabled()) {
985								_self._stopTimeout();
986							}
987						});
988					}
989					if ($.isPlainObject($.event.special.swiperight)) {
990						_self.objects.case.on('swiperight', function (event) {
991							event.preventDefault();
992							_self.objects.prev.click();
993							if (_self.isSlideshowEnabled()) {
994								_self._stopTimeout();
995							}
996						});
997					}
998				}
999			}
1000		},
1001
1002		/**
1003		 * Adds the key events
1004		 *
1005		 * @return	{void}
1006		 */
1007		_addKeyEvents: function () {
1008			$(document).bind('keyup.lightcase', function (event) {
1009				// Do nothing if lightcase is in process
1010				if (_self.isBusy) {
1011					return;
1012				}
1013
1014				switch (event.keyCode) {
1015					// Escape key
1016					case 27:
1017						_self.objects.close.click();
1018						break;
1019					// Backward key
1020					case 37:
1021						if (_self.objectData.isPartOfSequence) {
1022							_self.objects.prev.click();
1023						}
1024						break;
1025					// Forward key
1026					case 39:
1027						if (_self.objectData.isPartOfSequence) {
1028							_self.objects.next.click();
1029						}
1030						break;
1031				}
1032			});
1033		},
1034
1035		/**
1036		 * Starts the slideshow timeout
1037		 *
1038		 * @return	{void}
1039		 */
1040		_startTimeout: function () {
1041			_self.objects.play.hide();
1042			_self.objects.pause.show();
1043
1044			_self.cache.action = 'next';
1045			_self.objects.nav.removeClass(_self.settings.classPrefix + 'paused');
1046
1047			_self.timeout = setTimeout(function () {
1048				_self.objects.nav.data('items').next.click();
1049			}, _self.settings.timeout);
1050		},
1051
1052		/**
1053		 * Stops the slideshow timeout
1054		 *
1055		 * @return	{void}
1056		 */
1057		_stopTimeout: function () {
1058			_self.objects.play.show();
1059			_self.objects.pause.hide();
1060
1061			_self.objects.nav.addClass(_self.settings.classPrefix + 'paused');
1062
1063			clearTimeout(_self.timeout);
1064		},
1065
1066		/**
1067		 * Sets the navigator buttons (prev/next)
1068		 *
1069		 * @return	{object}	items
1070		 */
1071		_setNavigation: function () {
1072			var $links = $((_self.cache.selector || _self.settings.attr)),
1073				sequenceLength = _self.objectData.sequenceLength - 1,
1074				items = {
1075					prev: $links.eq(_self.objectData.prevIndex),
1076					next: $links.eq(_self.objectData.nextIndex)
1077				};
1078
1079			if (_self.objectData.currentIndex > 0) {
1080				_self.objects.prev.show();
1081			} else {
1082				items.prevItem = $links.eq(sequenceLength);
1083			}
1084			if (_self.objectData.nextIndex <= sequenceLength) {
1085				_self.objects.next.show();
1086			} else {
1087				items.next = $links.eq(0);
1088			}
1089
1090			if (_self.settings.navigateEndless === true) {
1091				_self.objects.prev.show();
1092				_self.objects.next.show();
1093			}
1094
1095			return items;
1096		},
1097
1098		/**
1099		 * Item information/status
1100		 *
1101		 */
1102		item: {
1103			/**
1104			 * Verifies if the current item is first item.
1105			 *
1106			 * @return	{boolean}
1107			 */
1108			isFirst: function () {
1109				return (_self.objectData.currentIndex === 0);
1110			},
1111
1112			/**
1113			 * Verifies if the current item is last item.
1114			 *
1115			 * @return	{boolean}
1116			 */
1117			isLast: function () {
1118				return (_self.objectData.currentIndex === (_self.objectData.sequenceLength - 1));
1119			}
1120		},
1121
1122		/**
1123		 * Clones the object for inline elements
1124		 *
1125		 * @param	{object}	$object
1126		 * @return	{object}	$clone
1127		 */
1128		_cloneObject: function ($object) {
1129			var $clone = $object.clone(),
1130				objectId = $object.attr('id');
1131
1132			// If element is hidden, cache the object and remove
1133			if ($object.is(':hidden')) {
1134				_self._cacheObjectData($object);
1135				$object.attr('id', _self.settings.idPrefix + 'temp-' + objectId).empty();
1136			} else {
1137				// Prevent duplicated id's
1138				$clone.removeAttr('id');
1139			}
1140
1141			return $clone.show();
1142		},
1143
1144		/**
1145		 * Verifies if it is a mobile device
1146		 *
1147		 * @return	{boolean}
1148		 */
1149		isMobileDevice: function () {
1150			var deviceAgent = navigator.userAgent.toLowerCase(),
1151				agentId = deviceAgent.match(_self.settings.mobileMatchExpression);
1152
1153			return agentId ? true : false;
1154		},
1155
1156		/**
1157		 * Verifies if css transitions are supported
1158		 *
1159		 * @return	{string|boolean}	The transition prefix if supported, else false.
1160		 */
1161		isTransitionSupported: function () {
1162			var body = $('body').get(0),
1163				isTransitionSupported = false,
1164				transitionMapping = {
1165					'transition': '',
1166					'WebkitTransition': '-webkit-',
1167					'MozTransition': '-moz-',
1168					'OTransition': '-o-',
1169					'MsTransition': '-ms-'
1170				};
1171
1172			for (var key in transitionMapping) {
1173				if (transitionMapping.hasOwnProperty(key) && key in body.style) {
1174					_self.support.transition = transitionMapping[key];
1175					isTransitionSupported = true;
1176				}
1177			}
1178
1179			return isTransitionSupported;
1180		},
1181
1182		/**
1183		 * Transition types
1184		 *
1185		 */
1186		transition: {
1187			/**
1188			 * Fades in/out the object
1189			 *
1190			 * @param	{object}	$object
1191			 * @param	{string}	type
1192			 * @param	{number}	speed
1193			 * @param	{number}	opacity
1194			 * @param	{function}	callback
1195			 * @return	{void}		Animates an object
1196			 */
1197			fade: function ($object, type, speed, opacity, callback) {
1198				var isInTransition = type === 'in',
1199					startTransition = {},
1200					startOpacity = $object.css('opacity'),
1201					endTransition = {},
1202					endOpacity = opacity ? opacity: isInTransition ? 1 : 0;
1203
1204				if (!_self.isOpen && isInTransition) return;
1205
1206				startTransition['opacity'] = startOpacity;
1207				endTransition['opacity'] = endOpacity;
1208
1209				$object.css(startTransition).show();
1210
1211				// Css transition
1212				if (_self.support.transitions) {
1213					endTransition[_self.support.transition + 'transition'] = speed + 'ms ease';
1214
1215					setTimeout(function () {
1216						$object.css(endTransition);
1217
1218						setTimeout(function () {
1219							$object.css(_self.support.transition + 'transition', '');
1220
1221							if (callback && (_self.isOpen || !isInTransition)) {
1222								callback();
1223							}
1224						}, speed);
1225					}, 15);
1226				} else {
1227					// Fallback to js transition
1228					$object.stop();
1229					$object.animate(endTransition, speed, callback);
1230				}
1231			},
1232
1233			/**
1234			 * Scrolls in/out the object
1235			 *
1236			 * @param	{object}	$object
1237			 * @param	{string}	type
1238			 * @param	{number}	speed
1239			 * @param	{function}	callback
1240			 * @return	{void}		Animates an object
1241			 */
1242			scroll: function ($object, type, speed, callback) {
1243				var isInTransition = type === 'in',
1244					transition = isInTransition ? _self.settings.transitionIn : _self.settings.transitionOut,
1245					direction = 'left',
1246					startTransition = {},
1247					startOpacity = isInTransition ? 0 : 1,
1248					startOffset = isInTransition ? '-50%' : '50%',
1249					endTransition = {},
1250					endOpacity = isInTransition ? 1 : 0,
1251					endOffset = isInTransition ? '50%' : '-50%';
1252
1253				if (!_self.isOpen && isInTransition) return;
1254
1255				switch (transition) {
1256					case 'scrollTop':
1257						direction = 'top';
1258						break;
1259					case 'scrollRight':
1260						startOffset = isInTransition ? '150%' : '50%';
1261						endOffset = isInTransition ? '50%' : '150%';
1262						break;
1263					case 'scrollBottom':
1264						direction = 'top';
1265						startOffset = isInTransition ? '150%' : '50%';
1266						endOffset = isInTransition ? '50%' : '150%';
1267						break;
1268					case 'scrollHorizontal':
1269						startOffset = isInTransition ? '150%' : '50%';
1270						endOffset = isInTransition ? '50%' : '-50%';
1271						break;
1272					case 'scrollVertical':
1273						direction = 'top';
1274						startOffset = isInTransition ? '-50%' : '50%';
1275						endOffset = isInTransition ? '50%' : '150%';
1276						break;
1277				}
1278
1279				if (_self.cache.action === 'prev') {
1280					switch (transition) {
1281						case 'scrollHorizontal':
1282							startOffset = isInTransition ? '-50%' : '50%';
1283							endOffset = isInTransition ? '50%' : '150%';
1284							break;
1285						case 'scrollVertical':
1286							startOffset = isInTransition ? '150%' : '50%';
1287							endOffset = isInTransition ? '50%' : '-50%';
1288							break;
1289					}
1290				}
1291
1292				startTransition['opacity'] = startOpacity;
1293				startTransition[direction] = startOffset;
1294
1295				endTransition['opacity'] = endOpacity;
1296				endTransition[direction] = endOffset;
1297
1298				$object.css(startTransition).show();
1299
1300				// Css transition
1301				if (_self.support.transitions) {
1302					endTransition[_self.support.transition + 'transition'] = speed + 'ms ease';
1303
1304					setTimeout(function () {
1305						$object.css(endTransition);
1306
1307						setTimeout(function () {
1308							$object.css(_self.support.transition + 'transition', '');
1309
1310							if (callback && (_self.isOpen || !isInTransition)) {
1311								callback();
1312							}
1313						}, speed);
1314					}, 15);
1315				} else {
1316					// Fallback to js transition
1317					$object.stop();
1318					$object.animate(endTransition, speed, callback);
1319				}
1320			},
1321
1322			/**
1323			 * Zooms in/out the object
1324			 *
1325			 * @param	{object}	$object
1326			 * @param	{string}	type
1327			 * @param	{number}	speed
1328			 * @param	{function}	callback
1329			 * @return	{void}		Animates an object
1330			 */
1331			zoom: function ($object, type, speed, callback) {
1332				var isInTransition = type === 'in',
1333					startTransition = {},
1334					startOpacity = $object.css('opacity'),
1335					startScale = isInTransition ? 'scale(0.75)' : 'scale(1)',
1336					endTransition = {},
1337					endOpacity = isInTransition ? 1 : 0,
1338					endScale = isInTransition ? 'scale(1)' : 'scale(0.75)';
1339
1340				if (!_self.isOpen && isInTransition) return;
1341
1342				startTransition['opacity'] = startOpacity;
1343				startTransition[_self.support.transition + 'transform'] = startScale;
1344
1345				endTransition['opacity'] = endOpacity;
1346
1347				$object.css(startTransition).show();
1348
1349				// Css transition
1350				if (_self.support.transitions) {
1351					endTransition[_self.support.transition + 'transform'] = endScale;
1352					endTransition[_self.support.transition + 'transition'] = speed + 'ms ease';
1353
1354					setTimeout(function () {
1355						$object.css(endTransition);
1356
1357						setTimeout(function () {
1358							$object.css(_self.support.transition + 'transform', '');
1359							$object.css(_self.support.transition + 'transition', '');
1360
1361							if (callback && (_self.isOpen || !isInTransition)) {
1362								callback();
1363							}
1364						}, speed);
1365					}, 15);
1366				} else {
1367					// Fallback to js transition
1368					$object.stop();
1369					$object.animate(endTransition, speed, callback);
1370				}
1371			}
1372		},
1373
1374		/**
1375		 * Calls all the registered functions of a specific hook
1376		 *
1377		 * @param	{object}	hooks
1378		 * @return	{void}
1379		 */
1380		_callHooks: function (hooks) {
1381			if (typeof(hooks) === 'object') {
1382				$.each(hooks, function(index, hook) {
1383					if (typeof(hook) === 'function') {
1384						hook.call(_self.origin);
1385					}
1386				});
1387			}
1388		},
1389
1390		/**
1391		 * Caches the object data
1392		 *
1393		 * @param	{object}	$object
1394		 * @return	{void}
1395		 */
1396		_cacheObjectData: function ($object) {
1397			$.data($object, 'cache', {
1398				id: $object.attr('id'),
1399				content: $object.html()
1400			});
1401
1402			_self.cache.originalObject = $object;
1403		},
1404
1405		/**
1406		 * Restores the object from cache
1407		 *
1408		 * @return	void
1409		 */
1410		_restoreObject: function () {
1411			var $object = $('[id^="' + _self.settings.idPrefix + 'temp-"]');
1412
1413			$object.attr('id', $.data(_self.cache.originalObject, 'cache').id);
1414			$object.html($.data(_self.cache.originalObject, 'cache').content);
1415		},
1416
1417		/**
1418		 * Executes functions for a window resize.
1419		 * It stops an eventual timeout and recalculates dimenstions.
1420		 *
1421		 * @return	{void}
1422		 */
1423		resize: function () {
1424			if (!_self.isOpen) return;
1425
1426			if (_self.isSlideshowEnabled()) {
1427				_self._stopTimeout();
1428			}
1429
1430			_self.dimensions = _self.getViewportDimensions();
1431			_self._calculateDimensions(_self.cache.object);
1432		},
1433
1434		/**
1435		 * Caches the actual scroll coordinates.
1436		 *
1437		 * @return	{void}
1438		 */
1439		_cacheScrollPosition: function () {
1440			var	$window = $(window),
1441				$document = $(document),
1442				offset = {
1443					'top': $window.scrollTop(),
1444					'left':  $window.scrollLeft()
1445				};
1446
1447			_self.cache.scrollPosition = _self.cache.scrollPosition || {};
1448
1449			if ($document.width() > $window.width()) {
1450				_self.cache.scrollPosition.left = offset.left;
1451			}
1452			if ($document.height() > $window.height()) {
1453				_self.cache.scrollPosition.top = offset.top;
1454			}
1455		},
1456
1457		/**
1458		 * Watches for any resize interaction and caches the new sizes.
1459		 *
1460		 * @return	{void}
1461		 */
1462		_watchResizeInteraction: function () {
1463			$(window).resize(_self.resize);
1464		},
1465
1466		/**
1467		 * Stop watching any resize interaction related to _self.
1468		 *
1469		 * @return	{void}
1470		 */
1471		_unwatchResizeInteraction: function () {
1472			$(window).off('resize', _self.resize);
1473		},
1474
1475		/**
1476		 * Watches for any scroll interaction and caches the new position.
1477		 *
1478		 * @return	{void}
1479		 */
1480		_watchScrollInteraction: function () {
1481			$(window).scroll(_self._cacheScrollPosition);
1482		},
1483
1484		/**
1485		 * Stop watching any scroll interaction related to _self.
1486		 *
1487		 * @return	{void}
1488		 */
1489		_unwatchScrollInteraction: function () {
1490			$(window).off('scroll', _self._cacheScrollPosition);
1491		},
1492
1493		/**
1494		 * Restores to the original scoll position before
1495		 * lightcase got initialized.
1496		 *
1497		 * @return	{void}
1498		 */
1499		_restoreScrollPosition: function () {
1500			$(window)
1501				.scrollTop(parseInt(_self.cache.scrollPosition.top))
1502				.scrollLeft(parseInt(_self.cache.scrollPosition.left))
1503				.resize();
1504		},
1505
1506		/**
1507		 * Switches to the fullscreen mode
1508		 *
1509		 * @return	{void}
1510		 */
1511		_switchToFullScreenMode: function () {
1512			_self.settings.shrinkFactor = 1;
1513			_self.settings.overlayOpacity = 1;
1514
1515			$('html').addClass(_self.settings.classPrefix + 'fullScreenMode');
1516		},
1517
1518		/**
1519		 * Enters into the lightcase view
1520		 *
1521		 * @return	{void}
1522		 */
1523		_open: function () {
1524			_self.isOpen = true;
1525
1526			_self.support.transitions = _self.settings.cssTransitions ? _self.isTransitionSupported() : false;
1527			_self.support.mobileDevice = _self.isMobileDevice();
1528
1529			if (_self.support.mobileDevice) {
1530				$('html').addClass(_self.settings.classPrefix + 'isMobileDevice');
1531
1532				if (_self.settings.fullScreenModeForMobile) {
1533					_self._switchToFullScreenMode();
1534				}
1535			}
1536			if (!_self.settings.transitionIn) {
1537				_self.settings.transitionIn = _self.settings.transition;
1538			}
1539			if (!_self.settings.transitionOut) {
1540				_self.settings.transitionOut = _self.settings.transition;
1541			}
1542
1543			switch (_self.settings.transitionIn) {
1544				case 'fade':
1545				case 'fadeInline':
1546				case 'elastic':
1547				case 'scrollTop':
1548				case 'scrollRight':
1549				case 'scrollBottom':
1550				case 'scrollLeft':
1551				case 'scrollVertical':
1552				case 'scrollHorizontal':
1553					if (_self.objects.case.is(':hidden')) {
1554						_self.objects.close.css('opacity', 0);
1555						_self.objects.overlay.css('opacity', 0);
1556						_self.objects.case.css('opacity', 0);
1557						_self.objects.contentInner.css('opacity', 0);
1558					}
1559					_self.transition.fade(_self.objects.overlay, 'in', _self.settings.speedIn, _self.settings.overlayOpacity, function () {
1560						_self.transition.fade(_self.objects.close, 'in', _self.settings.speedIn);
1561						_self._handleEvents();
1562						_self._processContent();
1563					});
1564					break;
1565				default:
1566					_self.transition.fade(_self.objects.overlay, 'in', 0, _self.settings.overlayOpacity, function () {
1567						_self.transition.fade(_self.objects.close, 'in', 0);
1568						_self._handleEvents();
1569						_self._processContent();
1570					});
1571					break;
1572			}
1573
1574			$('html').addClass(_self.settings.classPrefix + 'open');
1575			_self.objects.case.attr('aria-hidden', 'false');
1576		},
1577
1578		/**
1579		 * Escapes from the lightcase view
1580		 *
1581		 * @return	{void}
1582		 */
1583		close: function () {
1584			_self.isOpen = false;
1585
1586			if (_self.isSlideshowEnabled()) {
1587				_self._stopTimeout();
1588				_self.objects.nav.removeClass(_self.settings.classPrefix + 'paused');
1589			}
1590
1591			_self.objects.loading.hide();
1592
1593			_self._unbindEvents();
1594
1595			_self._unwatchResizeInteraction();
1596			_self._unwatchScrollInteraction();
1597
1598			$('html').removeClass(_self.settings.classPrefix + 'open');
1599			_self.objects.case.attr('aria-hidden', 'true');
1600
1601			_self.objects.nav.children().hide();
1602
1603			_self._restoreScrollPosition();
1604
1605			// Call onClose hook functions
1606			_self._callHooks(_self.settings.onClose);
1607
1608			switch (_self.settings.transitionOut) {
1609				case 'fade':
1610				case 'fadeInline':
1611				case 'scrollTop':
1612				case 'scrollRight':
1613				case 'scrollBottom':
1614				case 'scrollLeft':
1615				case 'scrollHorizontal':
1616				case 'scrollVertical':
1617					_self.transition.fade(_self.objects.case, 'out', _self.settings.speedOut, 0, function () {
1618						_self.transition.fade(_self.objects.overlay, 'out', _self.settings.speedOut, 0, function () {
1619							_self.cleanup();
1620						});
1621					});
1622					break;
1623				case 'elastic':
1624					_self.transition.zoom(_self.objects.case, 'out', _self.settings.speedOut, function () {
1625						_self.transition.fade(_self.objects.overlay, 'out', _self.settings.speedOut, 0, function () {
1626							_self.cleanup();
1627						});
1628					});
1629					break;
1630				default:
1631					_self.cleanup();
1632					break;
1633			}
1634		},
1635
1636		/**
1637		 * Unbinds all given events
1638		 *
1639		 * @return	{void}
1640		 */
1641		_unbindEvents: function () {
1642			// Unbind overlay event
1643			_self.objects.overlay.unbind('click');
1644
1645			// Unbind key events
1646			$(document).unbind('keyup.lightcase');
1647
1648			// Unbind swipe events
1649			_self.objects.case.unbind('swipeleft').unbind('swiperight');
1650
1651			// Unbind navigator events
1652			_self.objects.prev.unbind('click');
1653			_self.objects.next.unbind('click');
1654			_self.objects.play.unbind('click');
1655			_self.objects.pause.unbind('click');
1656
1657			// Unbind close event
1658			_self.objects.close.unbind('click');
1659		},
1660
1661		/**
1662		 * Cleans up the dimensions
1663		 *
1664		 * @return	{void}
1665		 */
1666		_cleanupDimensions: function () {
1667			var opacity = _self.objects.contentInner.css('opacity');
1668
1669			_self.objects.case.css({
1670				'width': '',
1671				'height': '',
1672				'top': '',
1673				'left': '',
1674				'margin-top': '',
1675				'margin-left': ''
1676			});
1677
1678			_self.objects.contentInner.removeAttr('style').css('opacity', opacity);
1679			_self.objects.contentInner.children().removeAttr('style');
1680		},
1681
1682		/**
1683		 * Cleanup after aborting lightcase
1684		 *
1685		 * @return	{void}
1686		 */
1687		cleanup: function () {
1688			_self._cleanupDimensions();
1689
1690			_self.objects.loading.hide();
1691			_self.objects.overlay.hide();
1692			_self.objects.case.hide();
1693			_self.objects.prev.hide();
1694			_self.objects.next.hide();
1695			_self.objects.play.hide();
1696			_self.objects.pause.hide();
1697
1698			_self.objects.case.removeAttr(_self._prefixAttributeName('type'));
1699			_self.objects.nav.removeAttr(_self._prefixAttributeName('ispartofsequence'));
1700
1701			_self.objects.contentInner.empty().hide();
1702			_self.objects.info.children().empty();
1703
1704			if (_self.cache.originalObject) {
1705				_self._restoreObject();
1706			}
1707
1708			// Call onCleanup hook functions
1709			_self._callHooks(_self.settings.onCleanup);
1710
1711			// Restore cache
1712			_self.cache = {};
1713		},
1714
1715		/**
1716		 * Returns the supported match media or undefined if the browser
1717		 * doesn't support match media.
1718		 *
1719		 * @return	{mixed}
1720		 */
1721		_matchMedia: function () {
1722			return window.matchMedia || window.msMatchMedia;
1723		},
1724
1725		/**
1726		 * Returns the devicePixelRatio if supported. Else, it simply returns
1727		 * 1 as the default.
1728		 *
1729		 * @return	{number}
1730		 */
1731		_devicePixelRatio: function () {
1732			return window.devicePixelRatio || 1;
1733		},
1734
1735		/**
1736		 * Checks if method is public
1737		 *
1738		 * @return	{boolean}
1739		 */
1740		_isPublicMethod: function (method) {
1741			return (typeof _self[method] === 'function' && method.charAt(0) !== '_');
1742		},
1743
1744		/**
1745		 * Exports all public methods to be accessible, callable
1746		 * from global scope.
1747		 *
1748		 * @return	{void}
1749		 */
1750		_export: function () {
1751			window.lightcase = {};
1752
1753			$.each(_self, function (property) {
1754				if (_self._isPublicMethod(property)) {
1755					lightcase[property] = _self[property];
1756				}
1757			});
1758		}
1759	};
1760
1761	_self._export();
1762
1763	$.fn.lightcase = function (method) {
1764		// Method calling logic (only public methods are applied)
1765		if (_self._isPublicMethod(method)) {
1766			return _self[method].apply(this, Array.prototype.slice.call(arguments, 1));
1767		} else if (typeof method === 'object' || !method) {
1768			return _self.init.apply(this, arguments);
1769		} else {
1770			$.error('Method ' + method + ' does not exist on jQuery.lightcase');
1771		}
1772	};
1773})(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.