/* * lightcase - jquery plugin * the smart and flexible lightbox plugin. * * @author cornel boppart * @copyright author * * @version 2.3.4 (29/12/2015) */ $(".fc ul li").hover(function(){ $(this).css("border-color","#005baa") },function(){ $(this).css("border-color","#c3c3c3") }) ;(function ($) { 'use strict'; var _self = { cache: {}, support: {}, objects: {}, /** * initializes the plugin * * @param {object} options * @return {object} */ init: function (options) { return this.each(function () { $(this).unbind('click.lightcase').bind('click.lightcase', function (event) { event.preventdefault(); $(this).lightcase('start', options); }); }); }, /** * starts the plugin * * @param {object} options * @return {void} */ start: function (options) { _self.origin = lightcase.origin = this; _self.settings = lightcase.settings = $.extend(true, { idprefix: 'lightcase-', classprefix: 'lightcase-', attrprefix: 'lc-', transition: 'elastic', transitionin: null, transitionout: null, csstransitions: true, speedin: 250, speedout: 250, maxwidth: 800, maxheight: 500, forcewidth: false, forceheight: false, liveresize: true, fullscreenmodeformobile: true, mobilematchexpression: /(iphone|ipod|ipad|android|blackberry|symbian)/, disableshrink: false, shrinkfactor: .75, overlayopacity: .9, slideshow: false, timeout: 5000, swipe: true, usekeys: true, usecategories: true, navigateendless: true, closeonoverlayclick: true, title: null, caption: null, showtitle: true, showcaption: true, showsequenceinfo: true, inline: { width: 'auto', height: 'auto' }, ajax: { width: 'auto', height: 'auto', type: 'get', datatype: 'html', data: {} }, iframe: { width: 800, height: 500, frameborder: 0 }, flash: { width: 400, height: 205, wmode: 'transparent' }, video: { width: 400, height: 225, poster: '', preload: 'auto', controls: true, autobuffer: true, autoplay: true, loop: false }, attr: 'data-rel', href: null, type: null, typemapping: { 'image': 'jpg,jpeg,gif,png,bmp', 'flash': 'swf', 'video': 'mp4,mov,ogv,ogg,webm', 'iframe': 'html,php', 'ajax': 'json,txt', 'inline': '#' }, errormessage: function () { return '

' + _self.settings.labels['errormessage'] + '

'; }, labels: { 'errormessage': 'source could not be found...', 'sequenceinfo.of': ' of ', 'close': 'close', 'navigator.prev': 'prev', 'navigator.next': 'next', 'navigator.play': 'play', 'navigator.pause': 'pause' }, markup: function () { $('body').append( _self.objects.overlay = $('
'), _self.objects.loading = $('
'), _self.objects.case = $('') ); _self.objects.case.after( _self.objects.nav = $('
') ); _self.objects.nav.append( _self.objects.close = $('' + _self.settings.labels['close'] + ''), _self.objects.prev = $('' + _self.settings.labels['navigator.prev'] + '').hide(), _self.objects.next = $('' + _self.settings.labels['navigator.next'] + '').hide(), _self.objects.play = $('' + _self.settings.labels['navigator.play'] + '').hide(), _self.objects.pause = $('' + _self.settings.labels['navigator.pause'] + '').hide() ); _self.objects.case.append( _self.objects.content = $('
'), _self.objects.info = $('
') ); _self.objects.content.append( _self.objects.contentinner = $('
') ); _self.objects.info.append( _self.objects.sequenceinfo = $('
'), _self.objects.title = $('

'), _self.objects.caption = $('

') ); }, oninit: {}, onstart: {}, onfinish: {}, onclose: {}, oncleanup: {} }, options); // call oninit hook functions _self._callhooks(_self.settings.oninit); _self.objectdata = _self._setobjectdata(this); _self._cachescrollposition(); _self._watchscrollinteraction(); _self._addelements(); _self._open(); _self.dimensions = _self.getviewportdimensions(); }, /** * getter method for objects * * @param {string} name * @return {object} */ get: function (name) { return _self.objects[name]; }, /** * getter method for objectdata * * @return {object} */ getobjectdata: function () { return _self.objectdata; }, /** * sets the object data * * @param {object} object * @return {object} objectdata */ _setobjectdata: function (object) { var $object = $(object), objectdata = { title: _self.settings.title || $object.attr(_self._prefixattributename('title')) || $object.attr('title'), caption: _self.settings.caption || $object.attr(_self._prefixattributename('caption')) || $object.children('img').attr('alt'), url: _self._determineurl(), requesttype: _self.settings.ajax.type, requestdata: _self.settings.ajax.data, requestdatatype: _self.settings.ajax.datatype, rel: $object.attr(_self._determineattributeselector()), type: _self.settings.type || _self._verifydatatype(_self._determineurl()), ispartofsequence: _self._ispartofsequence($object.attr(_self.settings.attr), ':'), ispartofsequencewithslideshow: _self._ispartofsequence($object.attr(_self.settings.attr), ':slideshow'), currentindex: $(_self._determineattributeselector()).index($object), sequencelength: $(_self._determineattributeselector()).length }; // add sequence info to objectdata objectdata.sequenceinfo = (objectdata.currentindex + 1) + _self.settings.labels['sequenceinfo.of'] + objectdata.sequencelength; // add next/prev index objectdata.previndex = objectdata.currentindex - 1; objectdata.nextindex = objectdata.currentindex + 1; return objectdata; }, /** * prefixes a data attribute name with defined name from 'settings.attrprefix' * to ensure more uniqueness for all lightcase related/used attributes. * * @param {string} name * @return {string} */ _prefixattributename: function (name) { return 'data-' + _self.settings.attrprefix + name; }, /** * determines the link target considering 'settings.href' and data attributes * but also with a fallback to the default 'href' value. * * @return {string} */ _determinelinktarget: function () { return _self.settings.href || $(_self.origin).attr(_self._prefixattributename('href')) || $(_self.origin).attr('href'); }, /** * determines the attribute selector to use, depending on * whether categorized collections are beeing used or not. * * @return {string} selector */ _determineattributeselector: function () { var $origin = $(_self.origin), selector = ''; if (typeof _self.cache.selector !== 'undefined') { selector = _self.cache.selector; } else if (_self.settings.usecategories === true && $origin.attr(_self._prefixattributename('categories'))) { var categories = $origin.attr(_self._prefixattributename('categories')).split(' '); $.each(categories, function (index, category) { if (index > 0) { selector += ','; } selector += '[' + _self._prefixattributename('categories') + '~="' + category + '"]'; }); } else { selector = '[' + _self.settings.attr + '="' + $origin.attr(_self.settings.attr) + '"]'; } _self.cache.selector = selector; return selector; }, /** * determines the correct resource according to the * current viewport and density. * * @return {string} url */ _determineurl: function () { var dataurl = _self._verifydataurl(_self._determinelinktarget()), width = 0, density = 0, url; $.each(dataurl, function (index, src) { if ( // check density _self._devicepixelratio() >= src.density && src.density >= density && // check viewport width _self._matchmedia()('screen and (min-width:' + src.width + 'px)') && src.width >= width ) { width = src.width; density = src.density; url = src.url; } }); return url; }, /** * normalizes an url and returns information about the resource path, * the viewport width as well as density if defined. * * @param {string} url path to resource in format of an url or srcset * @return {object} */ _normalizeurl: function (url) { var srcexp = /^\d+$/; return url.split(',').map(function (str) { var src = { width: 0, density: 0 }; str.trim().split(/\s+/).foreach(function (url, i) { if (i === 0) { return src.url = url; } var value = url.substring(0, url.length - 1), lastchar = url[url.length - 1], intval = parseint(value, 10), floatval = parsefloat(value); if (lastchar === 'w' && srcexp.test(value)) { src.width = intval; } else if (lastchar === 'h' && srcexp.test(value)) { src.height = intval; } else if (lastchar === 'x' && !isnan(floatval)) { src.density = floatval; } }); return src; }); }, /** * verifies if the link is part of a sequence * * @param {string} rel * @param {string} expression * @return {boolean} */ _ispartofsequence: function (rel, expression) { var getsimilarlinks = $('[' + _self.settings.attr + '="' + rel + '"]'), regexp = new regexp(expression); return (regexp.test(rel) && getsimilarlinks.length > 1); }, /** * verifies if the slideshow should be enabled * * @return {boolean} */ isslideshowenabled: function () { return (_self.objectdata.ispartofsequence && (_self.settings.slideshow === true || _self.objectdata.ispartofsequencewithslideshow === true)); }, /** * loads the new content to show * * @return {void} */ _loadcontent: function () { if (_self.cache.originalobject) { _self._restoreobject(); } _self._createobject(); }, /** * creates a new object * * @return {void} */ _createobject: function () { var $object; // create object switch (_self.objectdata.type) { case 'image': $object = $(new image()); $object.attr({ // the time expression is required to prevent the binding of an image load 'src': _self.objectdata.url, 'alt': _self.objectdata.title }); break; case 'inline': $object = $('
'); $object.html(_self._cloneobject($(_self.objectdata.url))); // add custom attributes from _self.settings $.each(_self.settings.inline, function (name, value) { $object.attr(_self._prefixattributename(name), value); }); break; case 'ajax': $object = $('
'); // add custom attributes from _self.settings $.each(_self.settings.ajax, function (name, value) { if (name !== 'data') { $object.attr(_self._prefixattributename(name), value); } }); break; case 'flash': $object = $(''); // add custom attributes from _self.settings $.each(_self.settings.flash, function (name, value) { $object.attr(name, value); }); break; case 'video': $object = $(''); $object.attr('src', _self.objectdata.url); // add custom attributes from _self.settings $.each(_self.settings.video, function (name, value) { $object.attr(name, value); }); break; default : $object = $(''); $object.attr({ 'src': _self.objectdata.url }); // add custom attributes from _self.settings $.each(_self.settings.iframe, function (name, value) { $object.attr(name, value); }); break; } _self._addobject($object); _self._loadobject($object); }, /** * adds the new object to the markup * * @param {object} $object * @return {void} */ _addobject: function ($object) { // add object to content holder _self.objects.contentinner.html($object); // start loading _self._loading('start'); // call onstart hook functions _self._callhooks(_self.settings.onstart); // add sequenceinfo to the content holder or hide if its empty if (_self.settings.showsequenceinfo === true && _self.objectdata.ispartofsequence) { _self.objects.sequenceinfo.html(_self.objectdata.sequenceinfo); _self.objects.sequenceinfo.show(); } else { _self.objects.sequenceinfo.empty(); _self.objects.sequenceinfo.hide(); } // add title to the content holder or hide if its empty if (_self.settings.showtitle === true && _self.objectdata.title !== undefined && _self.objectdata.title !== '') { _self.objects.title.html(_self.objectdata.title); _self.objects.title.show(); } else { _self.objects.title.empty(); _self.objects.title.hide(); } // add caption to the content holder or hide if its empty if (_self.settings.showcaption === true && _self.objectdata.caption !== undefined && _self.objectdata.caption !== '') { _self.objects.caption.html(_self.objectdata.caption); _self.objects.caption.show(); } else { _self.objects.caption.empty(); _self.objects.caption.hide(); } }, /** * loads the new object * * @param {object} $object * @return {void} */ _loadobject: function ($object) { // load the object switch (_self.objectdata.type) { case 'inline': if ($(_self.objectdata.url)) { _self._showcontent($object); } else { _self.error(); } break; case 'ajax': $.ajax( $.extend({}, _self.settings.ajax, { url: _self.objectdata.url, type: _self.objectdata.requesttype, datatype: _self.objectdata.requestdatatype, data: _self.objectdata.requestdata, success: function (data, textstatus, jqxhr) { // unserialize if data is transferred as json if (_self.objectdata.requestdatatype === 'json') { _self.objectdata.data = data; } else { $object.html(data); } _self._showcontent($object); }, error: function (jqxhr, textstatus, errorthrown) { _self.error(); } }) ); break; case 'flash': _self._showcontent($object); break; case 'video': if (typeof($object.get(0).canplaytype) === 'function' || _self.objects.case.find('video').length === 0) { _self._showcontent($object); } else { _self.error(); } break; default: if (_self.objectdata.url) { $object.load(function () { _self._showcontent($object); }); $object.error(function () { _self.error(); }); } else { _self.error(); } break; } }, /** * throws an error message if something went wrong * * @return {void} */ error: function () { _self.objectdata.type = 'error'; var $object = $('
'); $object.html(_self.settings.errormessage); _self.objects.contentinner.html($object); _self._showcontent(_self.objects.contentinner); }, /** * calculates the dimensions to fit content * * @param {object} $object * @return {void} */ _calculatedimensions: function ($object) { _self._cleanupdimensions(); // set default dimensions var dimensions = { objectwidth: $object.attr('width') ? $object.attr('width') : $object.attr(_self._prefixattributename('width')), objectheight: $object.attr('height') ? $object.attr('height') : $object.attr(_self._prefixattributename('height')) }; if (!_self.settings.disableshrink) { // add calculated maximum width/height to dimensions dimensions.maxwidth = parseint(_self.dimensions.windowwidth * _self.settings.shrinkfactor); dimensions.maxheight = parseint(_self.dimensions.windowheight * _self.settings.shrinkfactor); // if the auto calculated maxwidth/maxheight greather than the userdefined one, use that. if (dimensions.maxwidth > _self.settings.maxwidth) { dimensions.maxwidth = _self.settings.maxwidth; } if (dimensions.maxheight > _self.settings.maxheight) { dimensions.maxheight = _self.settings.maxheight; } // calculate the difference between screen width/height and image width/height dimensions.differencewidthaspercent = parseint(100 / dimensions.maxwidth * dimensions.objectwidth); dimensions.differenceheightaspercent = parseint(100 / dimensions.maxheight * dimensions.objectheight); switch (_self.objectdata.type) { case 'image': case 'flash': case 'video': if (dimensions.differencewidthaspercent > 100 && dimensions.differencewidthaspercent > dimensions.differenceheightaspercent) { dimensions.objectwidth = dimensions.maxwidth; dimensions.objectheight = parseint(dimensions.objectheight / dimensions.differencewidthaspercent * 100); } if (dimensions.differenceheightaspercent > 100 && dimensions.differenceheightaspercent > dimensions.differencewidthaspercent) { dimensions.objectwidth = parseint(dimensions.objectwidth / dimensions.differenceheightaspercent * 100); dimensions.objectheight = dimensions.maxheight; } if (dimensions.differenceheightaspercent > 100 && dimensions.differencewidthaspercent < dimensions.differenceheightaspercent) { dimensions.objectwidth = parseint(dimensions.maxwidth / dimensions.differenceheightaspercent * dimensions.differencewidthaspercent); dimensions.objectheight = dimensions.maxheight; } break; case 'error': if (!isnan(dimensions.objectwidth) && dimensions.objectwidth > dimensions.maxwidth) { dimensions.objectwidth = dimensions.maxwidth; } break; default: if ((isnan(dimensions.objectwidth) || dimensions.objectwidth > dimensions.maxwidth) && !_self.settings.forcewidth) { dimensions.objectwidth = dimensions.maxwidth; } if (((isnan(dimensions.objectheight) && dimensions.objectheight !== 'auto') || dimensions.objectheight > dimensions.maxheight) && !_self.settings.forceheight) { dimensions.objectheight = dimensions.maxheight; } break; } } if (_self.settings.forcewidth) { dimensions.maxwidth = dimensions.objectwidth; } else if ($object.attr(_self._prefixattributename('max-width'))) { dimensions.maxwidth = $object.attr(_self._prefixattributename('max-width')); } if (_self.settings.forceheight) { dimensions.maxheight = dimensions.objectheight; } else if ($object.attr(_self._prefixattributename('max-height'))) { dimensions.maxheight = $object.attr(_self._prefixattributename('max-height')); } _self._adjustdimensions($object, dimensions); }, /** * adjusts the dimensions * * @param {object} $object * @param {object} dimensions * @return {void} */ _adjustdimensions: function ($object, dimensions) { // adjust width and height $object.css({ 'width': dimensions.objectwidth, 'height': dimensions.objectheight, 'max-width': dimensions.maxwidth, 'max-height': dimensions.maxheight }); _self.objects.contentinner.css({ 'width': $object.outerwidth(), 'height': $object.outerheight(), 'max-width': '100%' }); _self.objects.case.css({ 'width': _self.objects.contentinner.outerwidth() }); // adjust margin _self.objects.case.css({ 'margin-top': parseint(-(_self.objects.case.outerheight() / 2)), 'margin-left': parseint(-(_self.objects.case.outerwidth() / 2)) }); }, /** * handles the _loading * * @param {string} process * @return {void} */ _loading: function (process) { if (process === 'start') { _self.objects.case.addclass(_self.settings.classprefix + 'loading'); _self.objects.loading.show(); } else if (process === 'end') { _self.objects.case.removeclass(_self.settings.classprefix + 'loading'); _self.objects.loading.hide(); } }, /** * gets the client screen dimensions * * @return {object} dimensions */ getviewportdimensions: function () { return { windowwidth: $(window).innerwidth(), windowheight: $(window).innerheight() }; }, /** * verifies the url * * @param {string} dataurl * @return {object} dataurl clean url for processing content */ _verifydataurl: function (dataurl) { if (!dataurl || dataurl === undefined || dataurl === '') { return false; } if (dataurl.indexof('#') > -1) { dataurl = dataurl.split('#'); dataurl = '#' + dataurl[dataurl.length - 1]; } return _self._normalizeurl(dataurl.tostring()); }, /** * verifies the data type of the content to load * * @param {string} url * @return {string|boolean} array key if expression matched, else false */ _verifydatatype: function (url) { var typemapping = _self.settings.typemapping; // early abort if dataurl couldn't be verified if (!url) { return false; } // verify the datatype of url according to typemapping which // has been defined in settings. for (var key in typemapping) { if (typemapping.hasownproperty(key)) { var suffixarr = typemapping[key].split(','); for (var i = 0; i < suffixarr.length; i++) { var suffix = suffixarr[i].tolowercase(), regexp = new regexp('\.(' + suffix + ')$', 'i'), // verify only the last 5 characters of the string str = url.tolowercase().split('?')[0].substr(-5); if (regexp.test(str) === true || (key === 'inline' && (url.indexof(suffix) > -1))) { return key; } } } } // if no expression matched, return 'iframe'. return 'iframe'; }, /** * extends html markup with the essential tags * * @return {void} */ _addelements: function () { if (typeof _self.objects.case !== 'undefined' && $('#' + _self.objects.case.attr('id')).length) { return; } _self.settings.markup(); }, /** * shows the loaded content * * @param {object} $object * @return {void} */ _showcontent: function ($object) { // add data attribute with the object type _self.objects.case.attr(_self._prefixattributename('type'), _self.objectdata.type); _self.cache.object = $object; _self._calculatedimensions($object); // call onfinish hook functions _self._callhooks(_self.settings.onfinish); switch (_self.settings.transitionin) { case 'scrolltop': case 'scrollright': case 'scrollbottom': case 'scrollleft': case 'scrollhorizontal': case 'scrollvertical': _self.transition.scroll(_self.objects.case, 'in', _self.settings.speedin); _self.transition.fade(_self.objects.contentinner, 'in', _self.settings.speedin); break; case 'elastic': if (_self.objects.case.css('opacity') < 1) { _self.transition.zoom(_self.objects.case, 'in', _self.settings.speedin); _self.transition.fade(_self.objects.contentinner, 'in', _self.settings.speedin); } case 'fade': case 'fadeinline': _self.transition.fade(_self.objects.case, 'in', _self.settings.speedin); _self.transition.fade(_self.objects.contentinner, 'in', _self.settings.speedin); break; default: _self.transition.fade(_self.objects.case, 'in', 0); break; } // end loading. _self._loading('end'); _self.isbusy = false; }, /** * processes the content to show * * @return {void} */ _processcontent: function () { _self.isbusy = true; switch (_self.settings.transitionout) { case 'scrolltop': case 'scrollright': case 'scrollbottom': case 'scrollleft': case 'scrollvertical': case 'scrollhorizontal': if (_self.objects.case.is(':hidden')) { _self.transition.fade(_self.objects.case, 'out', 0, 0, function () { _self._loadcontent(); }); _self.transition.fade(_self.objects.contentinner, 'out', 0); } else { _self.transition.scroll(_self.objects.case, 'out', _self.settings.speedout, function () { _self._loadcontent(); }); } break; case 'fade': if (_self.objects.case.is(':hidden')) { _self.transition.fade(_self.objects.case, 'out', 0, 0, function () { _self._loadcontent(); }); } else { _self.transition.fade(_self.objects.case, 'out', _self.settings.speedout, 0, function () { _self._loadcontent(); }); } break; case 'fadeinline': case 'elastic': if (_self.objects.case.is(':hidden')) { _self.transition.fade(_self.objects.case, 'out', 0, 0, function () { _self._loadcontent(); }); } else { _self.transition.fade(_self.objects.contentinner, 'out', _self.settings.speedout, 0, function () { _self._loadcontent(); }); } break; default: _self.transition.fade(_self.objects.case, 'out', 0, 0, function () { _self._loadcontent(); }); break; } }, /** * handles events for gallery buttons * * @return {void} */ _handleevents: function () { _self._unbindevents(); _self.objects.nav.children().not(_self.objects.close).hide(); // if slideshow is enabled, show play/pause and start timeout. if (_self.isslideshowenabled()) { // only start the timeout if slideshow is not pausing if (!_self.objects.nav.hasclass(_self.settings.classprefix + 'paused')) { _self._starttimeout(); } else { _self._stoptimeout(); } } if (_self.settings.liveresize) { _self._watchresizeinteraction(); } _self.objects.close.click(function (event) { event.preventdefault(); _self.close(); }); if (_self.settings.closeonoverlayclick === true) { _self.objects.overlay.css('cursor', 'pointer').click(function (event) { event.preventdefault(); _self.close(); }); } if (_self.settings.usekeys === true) { _self._addkeyevents(); } if (_self.objectdata.ispartofsequence) { _self.objects.nav.attr(_self._prefixattributename('ispartofsequence'), true); _self.objects.nav.data('items', _self._setnavigation()); _self.objects.prev.click(function (event) { event.preventdefault(); if (_self.settings.navigateendless === true || !_self.item.isfirst()) { _self.objects.prev.unbind('click'); _self.cache.action = 'prev'; _self.objects.nav.data('items').prev.click(); if (_self.isslideshowenabled()) { _self._stoptimeout(); } } }); _self.objects.next.click(function (event) { event.preventdefault(); if (_self.settings.navigateendless === true || !_self.item.islast()) { _self.objects.next.unbind('click'); _self.cache.action = 'next'; _self.objects.nav.data('items').next.click(); if (_self.isslideshowenabled()) { _self._stoptimeout(); } } }); if (_self.isslideshowenabled()) { _self.objects.play.click(function (event) { event.preventdefault(); _self._starttimeout(); }); _self.objects.pause.click(function (event) { event.preventdefault(); _self._stoptimeout(); }); } // enable swiping if activated if (_self.settings.swipe === true) { if ($.isplainobject($.event.special.swipeleft)) { _self.objects.case.on('swipeleft', function (event) { event.preventdefault(); _self.objects.next.click(); if (_self.isslideshowenabled()) { _self._stoptimeout(); } }); } if ($.isplainobject($.event.special.swiperight)) { _self.objects.case.on('swiperight', function (event) { event.preventdefault(); _self.objects.prev.click(); if (_self.isslideshowenabled()) { _self._stoptimeout(); } }); } } } }, /** * adds the key events * * @return {void} */ _addkeyevents: function () { $(document).bind('keyup.lightcase', function (event) { // do nothing if lightcase is in process if (_self.isbusy) { return; } switch (event.keycode) { // escape key case 27: _self.objects.close.click(); break; // backward key case 37: if (_self.objectdata.ispartofsequence) { _self.objects.prev.click(); } break; // forward key case 39: if (_self.objectdata.ispartofsequence) { _self.objects.next.click(); } break; } }); }, /** * starts the slideshow timeout * * @return {void} */ _starttimeout: function () { //_self.objects.play.hide(); //_self.objects.pause.show(); _self.cache.action = 'next'; //_self.objects.nav.removeclass(_self.settings.classprefix + 'paused'); //_self.timeout = settimeout(function () { // _self.objects.nav.data('items').next.click(); // }, _self.settings.timeout); }, /** * stops the slideshow timeout * * @return {void} */ _stoptimeout: function () { //_self.objects.play.show(); //_self.objects.pause.hide(); //_self.objects.nav.addclass(_self.settings.classprefix + 'paused'); //cleartimeout(_self.timeout); }, /** * sets the navigator buttons (prev/next) * * @return {object} items */ _setnavigation: function () { var $links = $((_self.cache.selector || _self.settings.attr)), sequencelength = _self.objectdata.sequencelength - 1, items = { prev: $links.eq(_self.objectdata.previndex), next: $links.eq(_self.objectdata.nextindex) }; if (_self.objectdata.currentindex > 0) { _self.objects.prev.show(); } else { items.previtem = $links.eq(sequencelength); } if (_self.objectdata.nextindex <= sequencelength) { _self.objects.next.show(); } else { items.next = $links.eq(0); } if (_self.settings.navigateendless === true) { _self.objects.prev.show(); _self.objects.next.show(); } return items; }, /** * item information/status * */ item: { /** * verifies if the current item is first item. * * @return {boolean} */ isfirst: function () { return (_self.objectdata.currentindex === 0); }, /** * verifies if the current item is last item. * * @return {boolean} */ islast: function () { return (_self.objectdata.currentindex === (_self.objectdata.sequencelength - 1)); } }, /** * clones the object for inline elements * * @param {object} $object * @return {object} $clone */ _cloneobject: function ($object) { var $clone = $object.clone(), objectid = $object.attr('id'); // if element is hidden, cache the object and remove if ($object.is(':hidden')) { _self._cacheobjectdata($object); $object.attr('id', _self.settings.idprefix + 'temp-' + objectid).empty(); } else { // prevent duplicated id's $clone.removeattr('id'); } return $clone.show(); }, /** * verifies if it is a mobile device * * @return {boolean} */ ismobiledevice: function () { var deviceagent = navigator.useragent.tolowercase(), agentid = deviceagent.match(_self.settings.mobilematchexpression); return agentid ? true : false; }, /** * verifies if css transitions are supported * * @return {string|boolean} the transition prefix if supported, else false. */ istransitionsupported: function () { var body = $('body').get(0), istransitionsupported = false, transitionmapping = { 'transition': '', 'webkittransition': '-webkit-', 'moztransition': '-moz-', 'otransition': '-o-', 'mstransition': '-ms-' }; for (var key in transitionmapping) { if (transitionmapping.hasownproperty(key) && key in body.style) { _self.support.transition = transitionmapping[key]; istransitionsupported = true; } } return istransitionsupported; }, /** * transition types * */ transition: { /** * fades in/out the object * * @param {object} $object * @param {string} type * @param {number} speed * @param {number} opacity * @param {function} callback * @return {void} animates an object */ fade: function ($object, type, speed, opacity, callback) { var isintransition = type === 'in', starttransition = {}, startopacity = $object.css('opacity'), endtransition = {}, endopacity = opacity ? opacity: isintransition ? 1 : 0; if (!_self.isopen && isintransition) return; starttransition['opacity'] = startopacity; endtransition['opacity'] = endopacity; $object.css(starttransition).show(); // css transition if (_self.support.transitions) { endtransition[_self.support.transition + 'transition'] = speed + 'ms ease'; settimeout(function () { $object.css(endtransition); settimeout(function () { $object.css(_self.support.transition + 'transition', ''); if (callback && (_self.isopen || !isintransition)) { callback(); } }, speed); }, 15); } else { // fallback to js transition $object.stop(); $object.animate(endtransition, speed, callback); } }, /** * scrolls in/out the object * * @param {object} $object * @param {string} type * @param {number} speed * @param {function} callback * @return {void} animates an object */ scroll: function ($object, type, speed, callback) { var isintransition = type === 'in', transition = isintransition ? _self.settings.transitionin : _self.settings.transitionout, direction = 'left', starttransition = {}, startopacity = isintransition ? 0 : 1, startoffset = isintransition ? '-50%' : '50%', endtransition = {}, endopacity = isintransition ? 1 : 0, endoffset = isintransition ? '50%' : '-50%'; if (!_self.isopen && isintransition) return; switch (transition) { case 'scrolltop': direction = 'top'; break; case 'scrollright': startoffset = isintransition ? '150%' : '50%'; endoffset = isintransition ? '50%' : '150%'; break; case 'scrollbottom': direction = 'top'; startoffset = isintransition ? '150%' : '50%'; endoffset = isintransition ? '50%' : '150%'; break; case 'scrollhorizontal': startoffset = isintransition ? '150%' : '50%'; endoffset = isintransition ? '50%' : '-50%'; break; case 'scrollvertical': direction = 'top'; startoffset = isintransition ? '-50%' : '50%'; endoffset = isintransition ? '50%' : '150%'; break; } if (_self.cache.action === 'prev') { switch (transition) { case 'scrollhorizontal': startoffset = isintransition ? '-50%' : '50%'; endoffset = isintransition ? '50%' : '150%'; break; case 'scrollvertical': startoffset = isintransition ? '150%' : '50%'; endoffset = isintransition ? '50%' : '-50%'; break; } } starttransition['opacity'] = startopacity; starttransition[direction] = startoffset; endtransition['opacity'] = endopacity; endtransition[direction] = endoffset; $object.css(starttransition).show(); // css transition if (_self.support.transitions) { endtransition[_self.support.transition + 'transition'] = speed + 'ms ease'; settimeout(function () { $object.css(endtransition); settimeout(function () { $object.css(_self.support.transition + 'transition', ''); if (callback && (_self.isopen || !isintransition)) { callback(); } }, speed); }, 15); } else { // fallback to js transition $object.stop(); $object.animate(endtransition, speed, callback); } }, /** * zooms in/out the object * * @param {object} $object * @param {string} type * @param {number} speed * @param {function} callback * @return {void} animates an object */ zoom: function ($object, type, speed, callback) { var isintransition = type === 'in', starttransition = {}, startopacity = $object.css('opacity'), startscale = isintransition ? 'scale(0.75)' : 'scale(1)', endtransition = {}, endopacity = isintransition ? 1 : 0, endscale = isintransition ? 'scale(1)' : 'scale(0.75)'; if (!_self.isopen && isintransition) return; starttransition['opacity'] = startopacity; starttransition[_self.support.transition + 'transform'] = startscale; endtransition['opacity'] = endopacity; $object.css(starttransition).show(); // css transition if (_self.support.transitions) { endtransition[_self.support.transition + 'transform'] = endscale; endtransition[_self.support.transition + 'transition'] = speed + 'ms ease'; settimeout(function () { $object.css(endtransition); settimeout(function () { $object.css(_self.support.transition + 'transform', ''); $object.css(_self.support.transition + 'transition', ''); if (callback && (_self.isopen || !isintransition)) { callback(); } }, speed); }, 15); } else { // fallback to js transition $object.stop(); $object.animate(endtransition, speed, callback); } } }, /** * calls all the registered functions of a specific hook * * @param {object} hooks * @return {void} */ _callhooks: function (hooks) { if (typeof(hooks) === 'object') { $.each(hooks, function(index, hook) { if (typeof(hook) === 'function') { hook.call(_self.origin); } }); } }, /** * caches the object data * * @param {object} $object * @return {void} */ _cacheobjectdata: function ($object) { $.data($object, 'cache', { id: $object.attr('id'), content: $object.html() }); _self.cache.originalobject = $object; }, /** * restores the object from cache * * @return void */ _restoreobject: function () { var $object = $('[id^="' + _self.settings.idprefix + 'temp-"]'); $object.attr('id', $.data(_self.cache.originalobject, 'cache').id); $object.html($.data(_self.cache.originalobject, 'cache').content); }, /** * executes functions for a window resize. * it stops an eventual timeout and recalculates dimenstions. * * @return {void} */ resize: function () { if (!_self.isopen) return; if (_self.isslideshowenabled()) { _self._stoptimeout(); } _self.dimensions = _self.getviewportdimensions(); _self._calculatedimensions(_self.cache.object); }, /** * caches the actual scroll coordinates. * * @return {void} */ _cachescrollposition: function () { var $window = $(window), $document = $(document), offset = { 'top': $window.scrolltop(), 'left': $window.scrollleft() }; _self.cache.scrollposition = _self.cache.scrollposition || {}; if ($document.width() > $window.width()) { _self.cache.scrollposition.left = offset.left; } if ($document.height() > $window.height()) { _self.cache.scrollposition.top = offset.top; } }, /** * watches for any resize interaction and caches the new sizes. * * @return {void} */ _watchresizeinteraction: function () { $(window).resize(_self.resize); }, /** * stop watching any resize interaction related to _self. * * @return {void} */ _unwatchresizeinteraction: function () { $(window).off('resize', _self.resize); }, /** * watches for any scroll interaction and caches the new position. * * @return {void} */ _watchscrollinteraction: function () { $(window).scroll(_self._cachescrollposition); }, /** * stop watching any scroll interaction related to _self. * * @return {void} */ _unwatchscrollinteraction: function () { $(window).off('scroll', _self._cachescrollposition); }, /** * restores to the original scoll position before * lightcase got initialized. * * @return {void} */ _restorescrollposition: function () { $(window) .scrolltop(parseint(_self.cache.scrollposition.top)) .scrollleft(parseint(_self.cache.scrollposition.left)) .resize(); }, /** * switches to the fullscreen mode * * @return {void} */ _switchtofullscreenmode: function () { _self.settings.shrinkfactor = 1; _self.settings.overlayopacity = 1; $('html').addclass(_self.settings.classprefix + 'fullscreenmode'); }, /** * enters into the lightcase view * * @return {void} */ _open: function () { _self.isopen = true; _self.support.transitions = _self.settings.csstransitions ? _self.istransitionsupported() : false; _self.support.mobiledevice = _self.ismobiledevice(); if (_self.support.mobiledevice) { $('html').addclass(_self.settings.classprefix + 'ismobiledevice'); if (_self.settings.fullscreenmodeformobile) { _self._switchtofullscreenmode(); } } if (!_self.settings.transitionin) { _self.settings.transitionin = _self.settings.transition; } if (!_self.settings.transitionout) { _self.settings.transitionout = _self.settings.transition; } switch (_self.settings.transitionin) { case 'fade': case 'fadeinline': case 'elastic': case 'scrolltop': case 'scrollright': case 'scrollbottom': case 'scrollleft': case 'scrollvertical': case 'scrollhorizontal': if (_self.objects.case.is(':hidden')) { _self.objects.close.css('opacity', 0); _self.objects.overlay.css('opacity', 0); _self.objects.case.css('opacity', 0); _self.objects.contentinner.css('opacity', 0); } _self.transition.fade(_self.objects.overlay, 'in', _self.settings.speedin, _self.settings.overlayopacity, function () { _self.transition.fade(_self.objects.close, 'in', _self.settings.speedin); _self._handleevents(); _self._processcontent(); }); break; default: _self.transition.fade(_self.objects.overlay, 'in', 0, _self.settings.overlayopacity, function () { _self.transition.fade(_self.objects.close, 'in', 0); _self._handleevents(); _self._processcontent(); }); break; } $('html').addclass(_self.settings.classprefix + 'open'); _self.objects.case.attr('aria-hidden', 'false'); }, /** * escapes from the lightcase view * * @return {void} */ close: function () { _self.isopen = false; if (_self.isslideshowenabled()) { _self._stoptimeout(); _self.objects.nav.removeclass(_self.settings.classprefix + 'paused'); } _self.objects.loading.hide(); _self._unbindevents(); _self._unwatchresizeinteraction(); _self._unwatchscrollinteraction(); $('html').removeclass(_self.settings.classprefix + 'open'); _self.objects.case.attr('aria-hidden', 'true'); _self.objects.nav.children().hide(); _self._restorescrollposition(); // call onclose hook functions _self._callhooks(_self.settings.onclose); switch (_self.settings.transitionout) { case 'fade': case 'fadeinline': case 'scrolltop': case 'scrollright': case 'scrollbottom': case 'scrollleft': case 'scrollhorizontal': case 'scrollvertical': _self.transition.fade(_self.objects.case, 'out', _self.settings.speedout, 0, function () { _self.transition.fade(_self.objects.overlay, 'out', _self.settings.speedout, 0, function () { _self.cleanup(); }); }); break; case 'elastic': _self.transition.zoom(_self.objects.case, 'out', _self.settings.speedout, function () { _self.transition.fade(_self.objects.overlay, 'out', _self.settings.speedout, 0, function () { _self.cleanup(); }); }); break; default: _self.cleanup(); break; } }, /** * unbinds all given events * * @return {void} */ _unbindevents: function () { // unbind overlay event _self.objects.overlay.unbind('click'); // unbind key events $(document).unbind('keyup.lightcase'); // unbind swipe events _self.objects.case.unbind('swipeleft').unbind('swiperight'); // unbind navigator events _self.objects.prev.unbind('click'); _self.objects.next.unbind('click'); _self.objects.play.unbind('click'); _self.objects.pause.unbind('click'); // unbind close event _self.objects.close.unbind('click'); }, /** * cleans up the dimensions * * @return {void} */ _cleanupdimensions: function () { var opacity = _self.objects.contentinner.css('opacity'); _self.objects.case.css({ 'width': '', 'height': '', 'top': '', 'left': '', 'margin-top': '', 'margin-left': '' }); _self.objects.contentinner.removeattr('style').css('opacity', opacity); _self.objects.contentinner.children().removeattr('style'); }, /** * cleanup after aborting lightcase * * @return {void} */ cleanup: function () { _self._cleanupdimensions(); _self.objects.loading.hide(); _self.objects.overlay.hide(); _self.objects.case.hide(); _self.objects.prev.hide(); _self.objects.next.hide(); _self.objects.play.hide(); _self.objects.pause.hide(); _self.objects.case.removeattr(_self._prefixattributename('type')); _self.objects.nav.removeattr(_self._prefixattributename('ispartofsequence')); _self.objects.contentinner.empty().hide(); _self.objects.info.children().empty(); if (_self.cache.originalobject) { _self._restoreobject(); } // call oncleanup hook functions _self._callhooks(_self.settings.oncleanup); // restore cache _self.cache = {}; }, /** * returns the supported match media or undefined if the browser * doesn't support match media. * * @return {mixed} */ _matchmedia: function () { return window.matchmedia || window.msmatchmedia; }, /** * returns the devicepixelratio if supported. else, it simply returns * 1 as the default. * * @return {number} */ _devicepixelratio: function () { return window.devicepixelratio || 1; }, /** * checks if method is public * * @return {boolean} */ _ispublicmethod: function (method) { return (typeof _self[method] === 'function' && method.charat(0) !== '_'); }, /** * exports all public methods to be accessible, callable * from global scope. * * @return {void} */ _export: function () { window.lightcase = {}; $.each(_self, function (property) { if (_self._ispublicmethod(property)) { lightcase[property] = _self[property]; } }); } }; _self._export(); $.fn.lightcase = function (method) { // method calling logic (only public methods are applied) if (_self._ispublicmethod(method)) { return _self[method].apply(this, array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return _self.init.apply(this, arguments); } else { $.error('method ' + method + ' does not exist on jquery.lightcase'); } }; })(jquery);