PageSourceSearch

https://visitbegur.cat/wp-content/themes/visitbegur/resources/ver3/js/lightcase.js?ver=1781856623

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