PageSourceSearch

https://www.g-sign-1.com/wp-content/themes/sign-1/sign-1/js/lightcase/js/lightcase.js?ver=1.1

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