You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

859 lines
21 KiB

1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. /*! PhotoSwipe Default UI - 4.1.0 - 2015-09-04
  2. * http://photoswipe.com
  3. * Copyright (c) 2015 Dmitry Semenov; */
  4. /**
  5. *
  6. * UI on top of main sliding area (caption, arrows, close button, etc.).
  7. * Built just using public methods/properties of PhotoSwipe.
  8. *
  9. */
  10. (function (root, factory) {
  11. if (typeof define === 'function' && define.amd) {
  12. define(factory);
  13. } else if (typeof exports === 'object') {
  14. module.exports = factory();
  15. } else {
  16. root.PhotoSwipeUI_Default = factory();
  17. }
  18. })(this, function () {
  19. 'use strict';
  20. var PhotoSwipeUI_Default =
  21. function(pswp, framework) {
  22. var ui = this;
  23. var _overlayUIUpdated = false,
  24. _controlsVisible = true,
  25. _fullscrenAPI,
  26. _controls,
  27. _captionContainer,
  28. _fakeCaptionContainer,
  29. _indexIndicator,
  30. _shareButton,
  31. _shareModal,
  32. _shareModalHidden = true,
  33. _initalCloseOnScrollValue,
  34. _isIdle,
  35. _listen,
  36. _loadingIndicator,
  37. _loadingIndicatorHidden,
  38. _loadingIndicatorTimeout,
  39. _galleryHasOneSlide,
  40. _options,
  41. _defaultUIOptions = {
  42. barsSize: {top:44, bottom:'auto'},
  43. closeElClasses: ['item', 'caption', 'zoom-wrap', 'ui', 'top-bar'],
  44. timeToIdle: 4000,
  45. timeToIdleOutside: 1000,
  46. loadingIndicatorDelay: 1000, // 2s
  47. addCaptionHTMLFn: function(item, captionEl /*, isFake */) {
  48. if(!item.title) {
  49. captionEl.children[0].innerHTML = '';
  50. return false;
  51. }
  52. captionEl.children[0].innerHTML = item.title;
  53. return true;
  54. },
  55. closeEl:true,
  56. captionEl: true,
  57. fullscreenEl: true,
  58. zoomEl: true,
  59. shareEl: true,
  60. counterEl: true,
  61. arrowEl: true,
  62. preloaderEl: true,
  63. tapToClose: false,
  64. tapToToggleControls: true,
  65. clickToCloseNonZoomable: true,
  66. shareButtons: [
  67. {id:'facebook', label:'Share on Facebook', url:'https://www.facebook.com/sharer/sharer.php?u={{url}}'},
  68. {id:'twitter', label:'Tweet', url:'https://twitter.com/intent/tweet?text={{text}}&url={{url}}'},
  69. {id:'pinterest', label:'Pin it', url:'http://www.pinterest.com/pin/create/button/'+
  70. '?url={{url}}&media={{image_url}}&description={{text}}'},
  71. {id:'download', label:'Download image', url:'{{raw_image_url}}', download:true}
  72. ],
  73. getImageURLForShare: function( /* shareButtonData */ ) {
  74. return pswp.currItem.src || '';
  75. },
  76. getPageURLForShare: function( /* shareButtonData */ ) {
  77. return window.location.href;
  78. },
  79. getTextForShare: function( /* shareButtonData */ ) {
  80. return pswp.currItem.title || '';
  81. },
  82. indexIndicatorSep: ' / '
  83. },
  84. _blockControlsTap,
  85. _blockControlsTapTimeout;
  86. var _onControlsTap = function(e) {
  87. if(_blockControlsTap) {
  88. return true;
  89. }
  90. e = e || window.event;
  91. if(_options.timeToIdle && _options.mouseUsed && !_isIdle) {
  92. // reset idle timer
  93. _onIdleMouseMove();
  94. }
  95. var target = e.target || e.srcElement,
  96. uiElement,
  97. clickedClass = target.className,
  98. found;
  99. for(var i = 0; i < _uiElements.length; i++) {
  100. uiElement = _uiElements[i];
  101. if(uiElement.onTap && clickedClass.indexOf('pswp__' + uiElement.name ) > -1 ) {
  102. uiElement.onTap();
  103. found = true;
  104. }
  105. }
  106. if(found) {
  107. if(e.stopPropagation) {
  108. e.stopPropagation();
  109. }
  110. _blockControlsTap = true;
  111. // Some versions of Android don't prevent ghost click event
  112. // when preventDefault() was called on touchstart and/or touchend.
  113. //
  114. // This happens on v4.3, 4.2, 4.1,
  115. // older versions strangely work correctly,
  116. // but just in case we add delay on all of them)
  117. var tapDelay = framework.features.isOldAndroid ? 600 : 30;
  118. _blockControlsTapTimeout = setTimeout(function() {
  119. _blockControlsTap = false;
  120. }, tapDelay);
  121. }
  122. },
  123. _fitControlsInViewport = function() {
  124. return !pswp.likelyTouchDevice || _options.mouseUsed || screen.width > 1200;
  125. },
  126. _togglePswpClass = function(el, cName, add) {
  127. framework[ (add ? 'add' : 'remove') + 'Class' ](el, 'pswp__' + cName);
  128. },
  129. // add class when there is just one item in the gallery
  130. // (by default it hides left/right arrows and 1ofX counter)
  131. _countNumItems = function() {
  132. var hasOneSlide = (_options.getNumItemsFn() === 1);
  133. if(hasOneSlide !== _galleryHasOneSlide) {
  134. _togglePswpClass(_controls, 'ui--one-slide', hasOneSlide);
  135. _galleryHasOneSlide = hasOneSlide;
  136. }
  137. },
  138. _toggleShareModalClass = function() {
  139. _togglePswpClass(_shareModal, 'share-modal--hidden', _shareModalHidden);
  140. },
  141. _toggleShareModal = function() {
  142. _shareModalHidden = !_shareModalHidden;
  143. if(!_shareModalHidden) {
  144. _toggleShareModalClass();
  145. setTimeout(function() {
  146. if(!_shareModalHidden) {
  147. framework.addClass(_shareModal, 'pswp__share-modal--fade-in');
  148. }
  149. }, 30);
  150. } else {
  151. framework.removeClass(_shareModal, 'pswp__share-modal--fade-in');
  152. setTimeout(function() {
  153. if(_shareModalHidden) {
  154. _toggleShareModalClass();
  155. }
  156. }, 300);
  157. }
  158. if(!_shareModalHidden) {
  159. _updateShareURLs();
  160. }
  161. return false;
  162. },
  163. _openWindowPopup = function(e) {
  164. e = e || window.event;
  165. var target = e.target || e.srcElement;
  166. pswp.shout('shareLinkClick', e, target);
  167. if(!target.href) {
  168. return false;
  169. }
  170. if( target.hasAttribute('download') ) {
  171. return true;
  172. }
  173. window.open(target.href, 'pswp_share', 'scrollbars=yes,resizable=yes,toolbar=no,'+
  174. 'location=yes,width=550,height=420,top=100,left=' +
  175. (window.screen ? Math.round(screen.width / 2 - 275) : 100) );
  176. if(!_shareModalHidden) {
  177. _toggleShareModal();
  178. }
  179. return false;
  180. },
  181. _updateShareURLs = function() {
  182. var shareButtonOut = '',
  183. shareButtonData,
  184. shareURL,
  185. image_url,
  186. page_url,
  187. share_text;
  188. for(var i = 0; i < _options.shareButtons.length; i++) {
  189. shareButtonData = _options.shareButtons[i];
  190. image_url = _options.getImageURLForShare(shareButtonData);
  191. page_url = _options.getPageURLForShare(shareButtonData);
  192. share_text = _options.getTextForShare(shareButtonData);
  193. shareURL = shareButtonData.url.replace('{{url}}', encodeURIComponent(page_url) )
  194. .replace('{{image_url}}', encodeURIComponent(image_url) )
  195. .replace('{{raw_image_url}}', image_url )
  196. .replace('{{text}}', encodeURIComponent(share_text) );
  197. shareButtonOut += '<a href="' + shareURL + '" target="_blank" '+
  198. 'class="pswp__share--' + shareButtonData.id + '"' +
  199. (shareButtonData.download ? 'download' : '') + '>' +
  200. shareButtonData.label + '</a>';
  201. if(_options.parseShareButtonOut) {
  202. shareButtonOut = _options.parseShareButtonOut(shareButtonData, shareButtonOut);
  203. }
  204. }
  205. _shareModal.children[0].innerHTML = shareButtonOut;
  206. _shareModal.children[0].onclick = _openWindowPopup;
  207. },
  208. _hasCloseClass = function(target) {
  209. for(var i = 0; i < _options.closeElClasses.length; i++) {
  210. if( framework.hasClass(target, 'pswp__' + _options.closeElClasses[i]) ) {
  211. return true;
  212. }
  213. }
  214. },
  215. _idleInterval,
  216. _idleTimer,
  217. _idleIncrement = 0,
  218. _onIdleMouseMove = function() {
  219. clearTimeout(_idleTimer);
  220. _idleIncrement = 0;
  221. if(_isIdle) {
  222. ui.setIdle(false);
  223. }
  224. },
  225. _onMouseLeaveWindow = function(e) {
  226. e = e ? e : window.event;
  227. var from = e.relatedTarget || e.toElement;
  228. if (!from || from.nodeName === 'HTML') {
  229. clearTimeout(_idleTimer);
  230. _idleTimer = setTimeout(function() {
  231. ui.setIdle(true);
  232. }, _options.timeToIdleOutside);
  233. }
  234. },
  235. _setupFullscreenAPI = function() {
  236. if(_options.fullscreenEl && !framework.features.isOldAndroid) {
  237. if(!_fullscrenAPI) {
  238. _fullscrenAPI = ui.getFullscreenAPI();
  239. }
  240. if(_fullscrenAPI) {
  241. framework.bind(document, _fullscrenAPI.eventK, ui.updateFullscreen);
  242. ui.updateFullscreen();
  243. framework.addClass(pswp.template, 'pswp--supports-fs');
  244. } else {
  245. framework.removeClass(pswp.template, 'pswp--supports-fs');
  246. }
  247. }
  248. },
  249. _setupLoadingIndicator = function() {
  250. // Setup loading indicator
  251. if(_options.preloaderEl) {
  252. _toggleLoadingIndicator(true);
  253. _listen('beforeChange', function() {
  254. clearTimeout(_loadingIndicatorTimeout);
  255. // display loading indicator with delay
  256. _loadingIndicatorTimeout = setTimeout(function() {
  257. if(pswp.currItem && pswp.currItem.loading) {
  258. if( !pswp.allowProgressiveImg() || (pswp.currItem.img && !pswp.currItem.img.naturalWidth) ) {
  259. // show preloader if progressive loading is not enabled,
  260. // or image width is not defined yet (because of slow connection)
  261. _toggleLoadingIndicator(false);
  262. // items-controller.js function allowProgressiveImg
  263. }
  264. } else {
  265. _toggleLoadingIndicator(true); // hide preloader
  266. }
  267. }, _options.loadingIndicatorDelay);
  268. });
  269. _listen('imageLoadComplete', function(index, item) {
  270. if(pswp.currItem === item) {
  271. _toggleLoadingIndicator(true);
  272. }
  273. });
  274. }
  275. },
  276. _toggleLoadingIndicator = function(hide) {
  277. if( _loadingIndicatorHidden !== hide ) {
  278. _togglePswpClass(_loadingIndicator, 'preloader--active', !hide);
  279. _loadingIndicatorHidden = hide;
  280. }
  281. },
  282. _applyNavBarGaps = function(item) {
  283. var gap = item.vGap;
  284. if( _fitControlsInViewport() ) {
  285. var bars = _options.barsSize;
  286. if(_options.captionEl && bars.bottom === 'auto') {
  287. if(!_fakeCaptionContainer) {
  288. _fakeCaptionContainer = framework.createEl('pswp__caption pswp__caption--fake');
  289. _fakeCaptionContainer.appendChild( framework.createEl('pswp__caption__center') );
  290. _controls.insertBefore(_fakeCaptionContainer, _captionContainer);
  291. framework.addClass(_controls, 'pswp__ui--fit');
  292. }
  293. if( _options.addCaptionHTMLFn(item, _fakeCaptionContainer, true) ) {
  294. var captionSize = _fakeCaptionContainer.clientHeight;
  295. gap.bottom = parseInt(captionSize,10) || 44;
  296. } else {
  297. gap.bottom = bars.top; // if no caption, set size of bottom gap to size of top
  298. }
  299. } else {
  300. gap.bottom = bars.bottom === 'auto' ? 0 : bars.bottom;
  301. }
  302. // height of top bar is static, no need to calculate it
  303. gap.top = bars.top;
  304. } else {
  305. gap.top = gap.bottom = 0;
  306. }
  307. },
  308. _setupIdle = function() {
  309. // Hide controls when mouse is used
  310. if(_options.timeToIdle) {
  311. _listen('mouseUsed', function() {
  312. framework.bind(document, 'mousemove', _onIdleMouseMove);
  313. framework.bind(document, 'mouseout', _onMouseLeaveWindow);
  314. _idleInterval = setInterval(function() {
  315. _idleIncrement++;
  316. if(_idleIncrement === 2) {
  317. ui.setIdle(true);
  318. }
  319. }, _options.timeToIdle / 2);
  320. });
  321. }
  322. },
  323. _setupHidingControlsDuringGestures = function() {
  324. // Hide controls on vertical drag
  325. _listen('onVerticalDrag', function(now) {
  326. if(_controlsVisible && now < 0.95) {
  327. ui.hideControls();
  328. } else if(!_controlsVisible && now >= 0.95) {
  329. ui.showControls();
  330. }
  331. });
  332. // Hide controls when pinching to close
  333. var pinchControlsHidden;
  334. _listen('onPinchClose' , function(now) {
  335. if(_controlsVisible && now < 0.9) {
  336. ui.hideControls();
  337. pinchControlsHidden = true;
  338. } else if(pinchControlsHidden && !_controlsVisible && now > 0.9) {
  339. ui.showControls();
  340. }
  341. });
  342. _listen('zoomGestureEnded', function() {
  343. pinchControlsHidden = false;
  344. if(pinchControlsHidden && !_controlsVisible) {
  345. ui.showControls();
  346. }
  347. });
  348. };
  349. var _uiElements = [
  350. {
  351. name: 'caption',
  352. option: 'captionEl',
  353. onInit: function(el) {
  354. _captionContainer = el;
  355. }
  356. },
  357. {
  358. name: 'share-modal',
  359. option: 'shareEl',
  360. onInit: function(el) {
  361. _shareModal = el;
  362. },
  363. onTap: function() {
  364. _toggleShareModal();
  365. }
  366. },
  367. {
  368. name: 'button--share',
  369. option: 'shareEl',
  370. onInit: function(el) {
  371. _shareButton = el;
  372. },
  373. onTap: function() {
  374. _toggleShareModal();
  375. }
  376. },
  377. {
  378. name: 'button--zoom',
  379. option: 'zoomEl',
  380. onTap: pswp.toggleDesktopZoom
  381. },
  382. {
  383. name: 'counter',
  384. option: 'counterEl',
  385. onInit: function(el) {
  386. _indexIndicator = el;
  387. }
  388. },
  389. {
  390. name: 'button--close',
  391. option: 'closeEl',
  392. onTap: pswp.close
  393. },
  394. {
  395. name: 'button--arrow--left',
  396. option: 'arrowEl',
  397. onTap: pswp.prev
  398. },
  399. {
  400. name: 'button--arrow--right',
  401. option: 'arrowEl',
  402. onTap: pswp.next
  403. },
  404. {
  405. name: 'button--fs',
  406. option: 'fullscreenEl',
  407. onTap: function() {
  408. if(_fullscrenAPI.isFullscreen()) {
  409. _fullscrenAPI.exit();
  410. } else {
  411. _fullscrenAPI.enter();
  412. }
  413. }
  414. },
  415. {
  416. name: 'preloader',
  417. option: 'preloaderEl',
  418. onInit: function(el) {
  419. _loadingIndicator = el;
  420. }
  421. }
  422. ];
  423. var _setupUIElements = function() {
  424. var item,
  425. classAttr,
  426. uiElement;
  427. var loopThroughChildElements = function(sChildren) {
  428. if(!sChildren) {
  429. return;
  430. }
  431. var l = sChildren.length;
  432. for(var i = 0; i < l; i++) {
  433. item = sChildren[i];
  434. classAttr = item.className;
  435. for(var a = 0; a < _uiElements.length; a++) {
  436. uiElement = _uiElements[a];
  437. if(classAttr.indexOf('pswp__' + uiElement.name) > -1 ) {
  438. if( _options[uiElement.option] ) { // if element is not disabled from options
  439. framework.removeClass(item, 'pswp__element--disabled');
  440. if(uiElement.onInit) {
  441. uiElement.onInit(item);
  442. }
  443. //item.style.display = 'block';
  444. } else {
  445. framework.addClass(item, 'pswp__element--disabled');
  446. //item.style.display = 'none';
  447. }
  448. }
  449. }
  450. }
  451. };
  452. loopThroughChildElements(_controls.children);
  453. var topBar = framework.getChildByClass(_controls, 'pswp__top-bar');
  454. if(topBar) {
  455. loopThroughChildElements( topBar.children );
  456. }
  457. };
  458. ui.init = function() {
  459. // extend options
  460. framework.extend(pswp.options, _defaultUIOptions, true);
  461. // create local link for fast access
  462. _options = pswp.options;
  463. // find pswp__ui element
  464. _controls = framework.getChildByClass(pswp.scrollWrap, 'pswp__ui');
  465. // create local link
  466. _listen = pswp.listen;
  467. _setupHidingControlsDuringGestures();
  468. // update controls when slides change
  469. _listen('beforeChange', ui.update);
  470. // toggle zoom on double-tap
  471. _listen('doubleTap', function(point) {
  472. var initialZoomLevel = pswp.currItem.initialZoomLevel;
  473. if(pswp.getZoomLevel() !== initialZoomLevel) {
  474. pswp.zoomTo(initialZoomLevel, point, 333);
  475. } else {
  476. pswp.zoomTo(_options.getDoubleTapZoom(false, pswp.currItem), point, 333);
  477. }
  478. });
  479. // Allow text selection in caption
  480. _listen('preventDragEvent', function(e, isDown, preventObj) {
  481. var t = e.target || e.srcElement;
  482. if(
  483. t &&
  484. t.className && e.type.indexOf('mouse') > -1 &&
  485. ( t.className.indexOf('__caption') > 0 || (/(SMALL|STRONG|EM)/i).test(t.tagName) )
  486. ) {
  487. preventObj.prevent = false;
  488. }
  489. });
  490. // bind events for UI
  491. _listen('bindEvents', function() {
  492. framework.bind(_controls, 'pswpTap click', _onControlsTap);
  493. framework.bind(pswp.scrollWrap, 'pswpTap', ui.onGlobalTap);
  494. if(!pswp.likelyTouchDevice) {
  495. framework.bind(pswp.scrollWrap, 'mouseover', ui.onMouseOver);
  496. }
  497. });
  498. // unbind events for UI
  499. _listen('unbindEvents', function() {
  500. if(!_shareModalHidden) {
  501. _toggleShareModal();
  502. }
  503. if(_idleInterval) {
  504. clearInterval(_idleInterval);
  505. }
  506. framework.unbind(document, 'mouseout', _onMouseLeaveWindow);
  507. framework.unbind(document, 'mousemove', _onIdleMouseMove);
  508. framework.unbind(_controls, 'pswpTap click', _onControlsTap);
  509. framework.unbind(pswp.scrollWrap, 'pswpTap', ui.onGlobalTap);
  510. framework.unbind(pswp.scrollWrap, 'mouseover', ui.onMouseOver);
  511. if(_fullscrenAPI) {
  512. framework.unbind(document, _fullscrenAPI.eventK, ui.updateFullscreen);
  513. if(_fullscrenAPI.isFullscreen()) {
  514. _options.hideAnimationDuration = 0;
  515. _fullscrenAPI.exit();
  516. }
  517. _fullscrenAPI = null;
  518. }
  519. });
  520. // clean up things when gallery is destroyed
  521. _listen('destroy', function() {
  522. if(_options.captionEl) {
  523. if(_fakeCaptionContainer) {
  524. _controls.removeChild(_fakeCaptionContainer);
  525. }
  526. framework.removeClass(_captionContainer, 'pswp__caption--empty');
  527. }
  528. if(_shareModal) {
  529. _shareModal.children[0].onclick = null;
  530. }
  531. framework.removeClass(_controls, 'pswp__ui--over-close');
  532. framework.addClass( _controls, 'pswp__ui--hidden');
  533. ui.setIdle(false);
  534. });
  535. if(!_options.showAnimationDuration) {
  536. framework.removeClass( _controls, 'pswp__ui--hidden');
  537. }
  538. _listen('initialZoomIn', function() {
  539. if(_options.showAnimationDuration) {
  540. framework.removeClass( _controls, 'pswp__ui--hidden');
  541. }
  542. });
  543. _listen('initialZoomOut', function() {
  544. framework.addClass( _controls, 'pswp__ui--hidden');
  545. });
  546. _listen('parseVerticalMargin', _applyNavBarGaps);
  547. _setupUIElements();
  548. if(_options.shareEl && _shareButton && _shareModal) {
  549. _shareModalHidden = true;
  550. }
  551. _countNumItems();
  552. _setupIdle();
  553. _setupFullscreenAPI();
  554. _setupLoadingIndicator();
  555. };
  556. ui.setIdle = function(isIdle) {
  557. _isIdle = isIdle;
  558. _togglePswpClass(_controls, 'ui--idle', isIdle);
  559. };
  560. ui.update = function() {
  561. // Don't update UI if it's hidden
  562. if(_controlsVisible && pswp.currItem) {
  563. ui.updateIndexIndicator();
  564. if(_options.captionEl) {
  565. _options.addCaptionHTMLFn(pswp.currItem, _captionContainer);
  566. _togglePswpClass(_captionContainer, 'caption--empty', !pswp.currItem.title);
  567. }
  568. _overlayUIUpdated = true;
  569. } else {
  570. _overlayUIUpdated = false;
  571. }
  572. if(!_shareModalHidden) {
  573. _toggleShareModal();
  574. }
  575. _countNumItems();
  576. };
  577. ui.updateFullscreen = function(e) {
  578. if(e) {
  579. // some browsers change window scroll position during the fullscreen
  580. // so PhotoSwipe updates it just in case
  581. setTimeout(function() {
  582. pswp.setScrollOffset( 0, framework.getScrollY() );
  583. }, 50);
  584. }
  585. // toogle pswp--fs class on root element
  586. framework[ (_fullscrenAPI.isFullscreen() ? 'add' : 'remove') + 'Class' ](pswp.template, 'pswp--fs');
  587. };
  588. ui.updateIndexIndicator = function() {
  589. if(_options.counterEl) {
  590. _indexIndicator.innerHTML = (pswp.getCurrentIndex()+1) +
  591. _options.indexIndicatorSep +
  592. _options.getNumItemsFn();
  593. }
  594. };
  595. ui.onGlobalTap = function(e) {
  596. e = e || window.event;
  597. var target = e.target || e.srcElement;
  598. if(_blockControlsTap) {
  599. return;
  600. }
  601. if(e.detail && e.detail.pointerType === 'mouse') {
  602. // close gallery if clicked outside of the image
  603. if(_hasCloseClass(target)) {
  604. pswp.close();
  605. return;
  606. }
  607. if(framework.hasClass(target, 'pswp__img')) {
  608. if(pswp.getZoomLevel() === 1 && pswp.getZoomLevel() <= pswp.currItem.fitRatio) {
  609. if(_options.clickToCloseNonZoomable) {
  610. pswp.close();
  611. }
  612. } else {
  613. pswp.toggleDesktopZoom(e.detail.releasePoint);
  614. }
  615. }
  616. } else {
  617. // tap anywhere (except buttons) to toggle visibility of controls
  618. if(_options.tapToToggleControls) {
  619. if(_controlsVisible) {
  620. ui.hideControls();
  621. } else {
  622. ui.showControls();
  623. }
  624. }
  625. // tap to close gallery
  626. if(_options.tapToClose && (framework.hasClass(target, 'pswp__img') || _hasCloseClass(target)) ) {
  627. pswp.close();
  628. return;
  629. }
  630. }
  631. };
  632. ui.onMouseOver = function(e) {
  633. e = e || window.event;
  634. var target = e.target || e.srcElement;
  635. // add class when mouse is over an element that should close the gallery
  636. _togglePswpClass(_controls, 'ui--over-close', _hasCloseClass(target));
  637. };
  638. ui.hideControls = function() {
  639. framework.addClass(_controls,'pswp__ui--hidden');
  640. _controlsVisible = false;
  641. };
  642. ui.showControls = function() {
  643. _controlsVisible = true;
  644. if(!_overlayUIUpdated) {
  645. ui.update();
  646. }
  647. framework.removeClass(_controls,'pswp__ui--hidden');
  648. };
  649. ui.supportsFullscreen = function() {
  650. var d = document;
  651. return !!(d.exitFullscreen || d.mozCancelFullScreen || d.webkitExitFullscreen || d.msExitFullscreen);
  652. };
  653. ui.getFullscreenAPI = function() {
  654. var dE = document.documentElement,
  655. api,
  656. tF = 'fullscreenchange';
  657. if (dE.requestFullscreen) {
  658. api = {
  659. enterK: 'requestFullscreen',
  660. exitK: 'exitFullscreen',
  661. elementK: 'fullscreenElement',
  662. eventK: tF
  663. };
  664. } else if(dE.mozRequestFullScreen ) {
  665. api = {
  666. enterK: 'mozRequestFullScreen',
  667. exitK: 'mozCancelFullScreen',
  668. elementK: 'mozFullScreenElement',
  669. eventK: 'moz' + tF
  670. };
  671. } else if(dE.webkitRequestFullscreen) {
  672. api = {
  673. enterK: 'webkitRequestFullscreen',
  674. exitK: 'webkitExitFullscreen',
  675. elementK: 'webkitFullscreenElement',
  676. eventK: 'webkit' + tF
  677. };
  678. } else if(dE.msRequestFullscreen) {
  679. api = {
  680. enterK: 'msRequestFullscreen',
  681. exitK: 'msExitFullscreen',
  682. elementK: 'msFullscreenElement',
  683. eventK: 'MSFullscreenChange'
  684. };
  685. }
  686. if(api) {
  687. api.enter = function() {
  688. // disable close-on-scroll in fullscreen
  689. _initalCloseOnScrollValue = _options.closeOnScroll;
  690. _options.closeOnScroll = false;
  691. if(this.enterK === 'webkitRequestFullscreen') {
  692. pswp.template[this.enterK]( Element.ALLOW_KEYBOARD_INPUT );
  693. } else {
  694. return pswp.template[this.enterK]();
  695. }
  696. };
  697. api.exit = function() {
  698. _options.closeOnScroll = _initalCloseOnScrollValue;
  699. return document[this.exitK]();
  700. };
  701. api.isFullscreen = function() { return document[this.elementK]; };
  702. }
  703. return api;
  704. };
  705. };
  706. return PhotoSwipeUI_Default;
  707. });