邓州市源盛农机专业合作社官网

lightcase.js 47KB

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