PageSourceSearch

https://corp.asahi.co.jp/Portals/0/js/lightcase/lightcase.js

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