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