From 2c3e794cb330808d993a27763c9c350356f3c6ee Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Tue, 7 Apr 2020 15:51:10 +0100 Subject: [PATCH 01/39] website: Fix inline style and indentation (mix of spaces and tabs). --- website/index.html | 70 +++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/website/index.html b/website/index.html index c7db06c6f..4037c9abf 100644 --- a/website/index.html +++ b/website/index.html @@ -164,7 +164,7 @@

Browser history API

-

“Back” button to close gallery

+

“Back” button to close gallery

PhotoSwipe adds a history record when the gallery is opened, which allows the user to close it via the browser’s “back” button.

@@ -518,54 +518,54 @@

Please spread the word if you find the script useful

-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
- + - + - + - + -
-
-
-
-
+
+
+
+
+
+
-
- + - + - - -
-
-
-
-
+ + +
+
+
+
+
From fa8dc3ffc375e327f79712acd1e6ac3338e5c87b Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 16 Apr 2020 11:55:28 +0100 Subject: [PATCH 02/39] Rename framework.createEl to framework.createElement for clarity --- src/js/framework-bridge.js | 4 ++-- src/js/items-controller.js | 11 ++++++----- src/js/ui/photoswipe-ui-default.js | 5 ++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/js/framework-bridge.js b/src/js/framework-bridge.js index 9c6c84fab..6dd2bfd83 100644 --- a/src/js/framework-bridge.js +++ b/src/js/framework-bridge.js @@ -19,7 +19,7 @@ var framework = { isArray: function(obj) { return (obj instanceof Array); }, - createEl: function(classes, tag) { + createElement: function(classes, tag) { var el = document.createElement(tag || 'div'); if(classes) { el.className = classes; @@ -125,7 +125,7 @@ var framework = { if(framework.features) { return framework.features; } - var helperEl = framework.createEl(), + var helperEl = framework.createElement(), helperStyle = helperEl.style, vendor = '', features = {}; diff --git a/src/js/items-controller.js b/src/js/items-controller.js index b1a36cf88..db8bfd0fe 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -150,7 +150,7 @@ var _getItemAt, _preloadImage = function(item) { item.loading = true; item.loaded = false; - var img = item.img = framework.createEl('pswp__img', 'img'); + var img = item.img = framework.createElement('pswp__img', 'img'); var onComplete = function() { item.loading = false; item.loaded = true; @@ -347,7 +347,7 @@ _registerModule('Controller', { allowProgressiveImg: function() { // 1. Progressive image loading isn't working on webkit/blink // when hw-acceleration (e.g. translateZ) is applied to IMG element. - // That's why in PhotoSwipe parent element gets zoom transform, not image itself. + // That's why in PhotoSwipe parent element (.pwsp__zoom-wrap) gets zoom transform, not image itself. // // 2. Progressive image loading sometimes blinks in webkit/blink when applying animation to parent element. // That's why it's disabled on touch devices (mainly because of swipe transition) @@ -385,7 +385,7 @@ _registerModule('Controller', { holder.item = item; // base container DIV is created only once for each of 3 holders - var baseDiv = item.container = framework.createEl('pswp__zoom-wrap'); + var baseDiv = item.container = framework.createElement('pswp__zoom-wrap'); @@ -423,6 +423,7 @@ _registerModule('Controller', { } return; } + if( !item.imageAppended ) { if(_features.transform && (_mainScrollAnimating || _initialZoomRunning) ) { _imagesToAppendPool.push({ @@ -456,7 +457,7 @@ _registerModule('Controller', { var placeholderClassName = 'pswp__img pswp__img--placeholder'; placeholderClassName += (item.msrc ? '' : ' pswp__img--placeholder--blank'); - var placeholder = framework.createEl(placeholderClassName, item.msrc ? 'img' : ''); + var placeholder = framework.createElement(placeholderClassName, item.msrc ? 'img' : ''); if(item.msrc) { placeholder.src = item.msrc; } @@ -493,7 +494,7 @@ _registerModule('Controller', { } else if(item.src && !item.loadError) { // image object is created every time, due to bugs of image loading & delay when switching images - img = framework.createEl('pswp__img', 'img'); + img = framework.createElement('pswp__img', 'img'); img.style.opacity = 1; img.src = item.src; _setImageSize(item, img); diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index eee3552f7..cf39c5175 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -343,13 +343,12 @@ var PhotoSwipeUI_Default = var bars = _options.barsSize; if(_options.captionEl && bars.bottom === 'auto') { if(!_fakeCaptionContainer) { - _fakeCaptionContainer = framework.createEl('pswp__caption pswp__caption--fake'); - _fakeCaptionContainer.appendChild( framework.createEl('pswp__caption__center') ); + _fakeCaptionContainer = framework.createElement('pswp__caption pswp__caption--fake'); + _fakeCaptionContainer.appendChild( framework.createElement('pswp__caption__center') ); _controls.insertBefore(_fakeCaptionContainer, _captionContainer); framework.addClass(_controls, 'pswp__ui--fit'); } if( _options.addCaptionHTMLFn(item, _fakeCaptionContainer, true) ) { - var captionSize = _fakeCaptionContainer.clientHeight; gap.bottom = parseInt(captionSize,10) || 44; } else { From 21ae2604f309b67be39ef3a39ef8a77cbed55756 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 16 Apr 2020 11:55:28 +0100 Subject: [PATCH 03/39] Question about fake caption container - was part of commit "Rename framework.createEl to framework.createElement for clarity" --- src/js/ui/photoswipe-ui-default.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index cf39c5175..e053034c2 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -342,13 +342,16 @@ var PhotoSwipeUI_Default = var bars = _options.barsSize; if(_options.captionEl && bars.bottom === 'auto') { + // Why is this fake caption container create with visibility:hidden + // and why only when bottom bar height is 'auto'? if(!_fakeCaptionContainer) { _fakeCaptionContainer = framework.createElement('pswp__caption pswp__caption--fake'); _fakeCaptionContainer.appendChild( framework.createElement('pswp__caption__center') ); _controls.insertBefore(_fakeCaptionContainer, _captionContainer); framework.addClass(_controls, 'pswp__ui--fit'); } - if( _options.addCaptionHTMLFn(item, _fakeCaptionContainer, true) ) { + + if( _options.addCaptionHTMLFn(item, _fakeCaptionContainer /*, true */) ) { var captionSize = _fakeCaptionContainer.clientHeight; gap.bottom = parseInt(captionSize,10) || 44; } else { From 203a335087d53ed603b0719dabb7b95016ec91d3 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 16 Apr 2020 12:46:34 +0100 Subject: [PATCH 04/39] Rename function argument of a DOM node from 'captionEl' to 'captionElement' to avoid confusion with the boolean option of the same name a few lines below. --- src/js/ui/photoswipe-ui-default.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index e053034c2..3dc34cfdb 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -50,12 +50,12 @@ var PhotoSwipeUI_Default = timeToIdleOutside: 1000, loadingIndicatorDelay: 1000, // 2s - addCaptionHTMLFn: function(item, captionEl /*, isFake */) { + addCaptionHTMLFn: function(item, captionElement /*, isFake */) { if(!item.title) { - captionEl.children[0].innerHTML = ''; + captionElement.children[0].innerHTML = ''; return false; } - captionEl.children[0].innerHTML = item.title; + captionElement.children[0].innerHTML = item.title; return true; }, From c3e971e5ede810f1f7eddf42d7ce66c3255274da Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 16 Apr 2020 12:46:34 +0100 Subject: [PATCH 05/39] Add some extra whitespace to separate functions. --- src/js/ui/photoswipe-ui-default.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 3dc34cfdb..4c7ee482a 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -81,12 +81,15 @@ var PhotoSwipeUI_Default = '?url={{url}}&media={{image_url}}&description={{text}}'}, {id:'download', label:'Download image', url:'{{raw_image_url}}', download:true} ], + getImageURLForShare: function( /* shareButtonData */ ) { return pswp.currItem.src || ''; }, + getPageURLForShare: function( /* shareButtonData */ ) { return window.location.href; }, + getTextForShare: function( /* shareButtonData */ ) { return pswp.currItem.title || ''; }, @@ -147,9 +150,11 @@ var PhotoSwipeUI_Default = } }, + _fitControlsInViewport = function() { return !pswp.likelyTouchDevice || _options.mouseUsed || screen.width > _options.fitControlsWidth; }, + _togglePswpClass = function(el, cName, add) { framework[ (add ? 'add' : 'remove') + 'Class' ](el, 'pswp__' + cName); }, @@ -164,9 +169,11 @@ var PhotoSwipeUI_Default = _galleryHasOneSlide = hasOneSlide; } }, + _toggleShareModalClass = function() { _togglePswpClass(_shareModal, 'share-modal--hidden', _shareModalHidden); }, + _toggleShareModal = function() { _shareModalHidden = !_shareModalHidden; @@ -218,6 +225,7 @@ var PhotoSwipeUI_Default = return false; }, + _updateShareURLs = function() { var shareButtonOut = '', shareButtonData, @@ -251,6 +259,7 @@ var PhotoSwipeUI_Default = _shareModal.children[0].onclick = _openWindowPopup; }, + _hasCloseClass = function(target) { for(var i = 0; i < _options.closeElClasses.length; i++) { if( framework.hasClass(target, 'pswp__' + _options.closeElClasses[i]) ) { @@ -258,9 +267,11 @@ var PhotoSwipeUI_Default = } } }, + _idleInterval, _idleTimer, _idleIncrement = 0, + _onIdleMouseMove = function() { clearTimeout(_idleTimer); _idleIncrement = 0; @@ -268,6 +279,7 @@ var PhotoSwipeUI_Default = ui.setIdle(false); } }, + _onMouseLeaveWindow = function(e) { e = e ? e : window.event; var from = e.relatedTarget || e.toElement; @@ -278,6 +290,7 @@ var PhotoSwipeUI_Default = }, _options.timeToIdleOutside); } }, + _setupFullscreenAPI = function() { if(_options.fullscreenEl && !framework.features.isOldAndroid) { if(!_fullscrenAPI) { @@ -292,6 +305,7 @@ var PhotoSwipeUI_Default = } } }, + _setupLoadingIndicator = function() { // Setup loading indicator if(_options.preloaderEl) { @@ -319,8 +333,8 @@ var PhotoSwipeUI_Default = } }, _options.loadingIndicatorDelay); - }); + _listen('imageLoadComplete', function(index, item) { if(pswp.currItem === item) { _toggleLoadingIndicator(true); @@ -329,12 +343,14 @@ var PhotoSwipeUI_Default = } }, + _toggleLoadingIndicator = function(hide) { if( _loadingIndicatorHidden !== hide ) { _togglePswpClass(_loadingIndicator, 'preloader--active', !hide); _loadingIndicatorHidden = hide; } }, + _applyNavBarGaps = function(item) { var gap = item.vGap; @@ -342,7 +358,7 @@ var PhotoSwipeUI_Default = var bars = _options.barsSize; if(_options.captionEl && bars.bottom === 'auto') { - // Why is this fake caption container create with visibility:hidden + // Why is this fake caption container created with visibility:hidden // and why only when bottom bar height is 'auto'? if(!_fakeCaptionContainer) { _fakeCaptionContainer = framework.createElement('pswp__caption pswp__caption--fake'); @@ -367,6 +383,7 @@ var PhotoSwipeUI_Default = gap.top = gap.bottom = 0; } }, + _setupIdle = function() { // Hide controls when mouse is used if(_options.timeToIdle) { @@ -384,6 +401,7 @@ var PhotoSwipeUI_Default = }); } }, + _setupHidingControlsDuringGestures = function() { // Hide controls on vertical drag From af9e8d78ca20cd79ac6064363dc8159bec71ba2c Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 16 Apr 2020 14:50:08 +0100 Subject: [PATCH 06/39] Rename options to make clear that these are booleans, not DOM elements. So confusing the way it was. --- src/js/ui/photoswipe-ui-default.js | 41 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 4c7ee482a..57482bf88 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -59,13 +59,14 @@ var PhotoSwipeUI_Default = return true; }, - closeEl:true, - captionEl: true, - fullscreenEl: true, - zoomEl: true, - shareEl: true, - counterEl: true, - arrowEl: true, + showCloseCtrl:true, + showCaption: true, + showFullscreenCtrl: true, + showZoomCtrl: true, + showShareCtrl: true, + showCounter: true, + showNextPreviousArrows: true, + preloaderEl: true, closeOnOutsideClick: true, @@ -357,7 +358,7 @@ var PhotoSwipeUI_Default = if( _fitControlsInViewport() ) { var bars = _options.barsSize; - if(_options.captionEl && bars.bottom === 'auto') { + if(_options.showCaption && bars.bottom === 'auto') { // Why is this fake caption container created with visibility:hidden // and why only when bottom bar height is 'auto'? if(!_fakeCaptionContainer) { @@ -438,14 +439,14 @@ var PhotoSwipeUI_Default = var _uiElements = [ { name: 'caption', - option: 'captionEl', + option: 'showCaption', onInit: function(el) { _captionContainer = el; } }, { name: 'share-modal', - option: 'shareEl', + option: 'showShareCtrl', onInit: function(el) { _shareModal = el; }, @@ -455,7 +456,7 @@ var PhotoSwipeUI_Default = }, { name: 'button--share', - option: 'shareEl', + option: 'showShareCtrl', onInit: function(el) { _shareButton = el; }, @@ -465,36 +466,36 @@ var PhotoSwipeUI_Default = }, { name: 'button--zoom', - option: 'zoomEl', + option: 'showZoomCtrl', onTap: pswp.toggleDesktopZoom }, { name: 'counter', - option: 'counterEl', + option: 'showCounter', onInit: function(el) { _indexIndicator = el; } }, { name: 'button--close', - option: 'closeEl', + option: 'showCloseCtrl', onTap: function() { setTimeout(pswp.close); } }, { name: 'button--arrow--left', - option: 'arrowEl', + option: 'showNextPreviousArrows', onTap: pswp.prev }, { name: 'button--arrow--right', - option: 'arrowEl', + option: 'showNextPreviousArrows', onTap: pswp.next }, { name: 'button--fs', - option: 'fullscreenEl', + option: 'showFullscreenCtrl', onTap: function() { if(_fullscrenAPI.isFullscreen()) { _fullscrenAPI.exit(); @@ -640,7 +641,7 @@ var PhotoSwipeUI_Default = // clean up things when gallery is destroyed _listen('destroy', function() { - if(_options.captionEl) { + if(_options.showCaption) { if(_fakeCaptionContainer) { _controls.removeChild(_fakeCaptionContainer); } @@ -696,7 +697,7 @@ var PhotoSwipeUI_Default = ui.updateIndexIndicator(); - if(_options.captionEl) { + if(_options.showCaption) { _options.addCaptionHTMLFn(pswp.currItem, _captionContainer); _togglePswpClass(_captionContainer, 'caption--empty', !pswp.currItem.title); @@ -730,7 +731,7 @@ var PhotoSwipeUI_Default = }; ui.updateIndexIndicator = function() { - if(_options.counterEl) { + if(_options.showCounter) { _indexIndicator.innerHTML = (pswp.getCurrentIndex()+1) + _options.indexIndicatorSep + _options.getNumItemsFn(); From e71b03023aaf6ab44eae9f5a091308d3f73dc407 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 16 Apr 2020 12:28:25 +0100 Subject: [PATCH 07/39] Capture the calculated size of the image and set an option for the caption to go under the picture and be able to scroll to see it. --- src/js/core.js | 1 + src/js/items-controller.js | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 1f2e9436d..7d86b08f1 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -100,6 +100,7 @@ var _isOpen, _windowVisibleSize = {}, _renderMaxResolution = false, _orientationChangeTimeout, + _verticalScrollForCaptions = false, // Registers PhotoSWipe module (History, Controller ...) diff --git a/src/js/items-controller.js b/src/js/items-controller.js index db8bfd0fe..9f4534e85 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -202,8 +202,8 @@ var _getItemAt, img = item.container.lastChild; } - var w = maxRes ? item.w : Math.round(item.w * item.fitRatio), - h = maxRes ? item.h : Math.round(item.h * item.fitRatio); + var w = item.calculatedWidth = maxRes ? item.w : Math.round(item.w * item.fitRatio), + h = item.calculatedHeight = maxRes ? item.h : Math.round(item.h * item.fitRatio); // ensure correct aspect ratio if(img.naturalHeight && img.naturalWidth) { @@ -226,6 +226,8 @@ var _getItemAt, img.style.width = w + 'px'; img.style.height = h + 'px'; }, + + // What is this? _appendImagesPool = function() { if(_imagesToAppendPool.length) { From e0aa68d98765bf06df1ed62d4c9e2b3b295d438b Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 16 Apr 2020 16:19:21 +0100 Subject: [PATCH 08/39] Move new option to the UI file. --- src/js/core.js | 1 - src/js/ui/photoswipe-ui-default.js | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 7d86b08f1..1f2e9436d 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -100,7 +100,6 @@ var _isOpen, _windowVisibleSize = {}, _renderMaxResolution = false, _orientationChangeTimeout, - _verticalScrollForCaptions = false, // Registers PhotoSWipe module (History, Controller ...) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 57482bf88..3bceecc99 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -60,12 +60,13 @@ var PhotoSwipeUI_Default = }, showCloseCtrl:true, - showCaption: true, showFullscreenCtrl: true, showZoomCtrl: true, showShareCtrl: true, showCounter: true, showNextPreviousArrows: true, + showCaption: true, + verticalScrollForCaptions: false, preloaderEl: true, closeOnOutsideClick: true, @@ -358,6 +359,7 @@ var PhotoSwipeUI_Default = if( _fitControlsInViewport() ) { var bars = _options.barsSize; + if(_options.showCaption && bars.bottom === 'auto') { // Why is this fake caption container created with visibility:hidden // and why only when bottom bar height is 'auto'? From 14b3c7232a735fbe97d27e44f61cb4e3c0dba138 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Tue, 21 Apr 2020 17:04:29 +0100 Subject: [PATCH 09/39] Fix whitespace in photoswipe-ui-default.js. Add some explanatory comments. --- src/js/core.js | 2 +- src/js/items-controller.js | 8 +- src/js/ui/photoswipe-ui-default.js | 1439 ++++++++++++++-------------- 3 files changed, 717 insertions(+), 732 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 1f2e9436d..5797ae8ad 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -576,7 +576,7 @@ var publicMethods = { self['init' + _modules[i]](); } - // init + // Create new PhotoSwipeUI_Default object and run init if(UiClass) { var ui = self.ui = new UiClass(self, framework); ui.init(); diff --git a/src/js/items-controller.js b/src/js/items-controller.js index 9f4534e85..5cd21ef4c 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -63,7 +63,6 @@ var _getItemAt, _shout('parseVerticalMargin', item); } - _tempPanAreaSize.x = viewportSize.x; _tempPanAreaSize.y = viewportSize.y - item.vGap.top - item.vGap.bottom; @@ -390,7 +389,7 @@ _registerModule('Controller', { var baseDiv = item.container = framework.createElement('pswp__zoom-wrap'); - + // Insert HTML if that is specified instead of an image. if(!item.src && item.html) { if(item.html.tagName) { baseDiv.appendChild(item.html); @@ -468,17 +467,12 @@ _registerModule('Controller', { baseDiv.appendChild(placeholder); item.placeholder = placeholder; - } - - - if(!item.loading) { _preloadImage(item); } - if( self.allowProgressiveImg() ) { // just append image if(!_initialContentSet && _features.transform) { diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 3bceecc99..1266efceb 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -3,6 +3,7 @@ * UI on top of main sliding area (caption, arrows, close button, etc.). * Built just using public methods/properties of PhotoSwipe. * +* Using UMD (Universal Module Definition) https://www.davidbcalhoun.com/2014/what-is-amd-commonjs-and-umd/ */ (function (root, factory) { if (typeof define === 'function' && define.amd) { @@ -16,875 +17,865 @@ 'use strict'; + var PhotoSwipeUI_Default = + function(pswp, framework) { + + var ui = this; + var _overlayUIUpdated = false, + _controlsVisible = true, + _fullscrenAPI, + _controls, + _captionContainer, + _fakeCaptionContainer, + _indexIndicator, + _shareButton, + _shareModal, + _shareModalHidden = true, + _initalCloseOnScrollValue, + _isIdle, + _listen, + + _loadingIndicator, + _loadingIndicatorHidden, + _loadingIndicatorTimeout, + + _galleryHasOneSlide, + + _options, + _defaultUIOptions = { + barsSize: {top:44, bottom:'auto'}, + closeElClasses: ['item', 'caption', 'zoom-wrap', 'ui', 'top-bar'], + timeToIdle: 4000, + timeToIdleOutside: 1000, + loadingIndicatorDelay: 1000, // 2s - -var PhotoSwipeUI_Default = - function(pswp, framework) { - - var ui = this; - var _overlayUIUpdated = false, - _controlsVisible = true, - _fullscrenAPI, - _controls, - _captionContainer, - _fakeCaptionContainer, - _indexIndicator, - _shareButton, - _shareModal, - _shareModalHidden = true, - _initalCloseOnScrollValue, - _isIdle, - _listen, - - _loadingIndicator, - _loadingIndicatorHidden, - _loadingIndicatorTimeout, - - _galleryHasOneSlide, - - _options, - _defaultUIOptions = { - barsSize: {top:44, bottom:'auto'}, - closeElClasses: ['item', 'caption', 'zoom-wrap', 'ui', 'top-bar'], - timeToIdle: 4000, - timeToIdleOutside: 1000, - loadingIndicatorDelay: 1000, // 2s - addCaptionHTMLFn: function(item, captionElement /*, isFake */) { - if(!item.title) { - captionElement.children[0].innerHTML = ''; - return false; - } - captionElement.children[0].innerHTML = item.title; - return true; - }, + if(!item.title) { + captionElement.children[0].innerHTML = ''; + return false; + } + captionElement.children[0].innerHTML = item.title; + return true; + }, - showCloseCtrl:true, - showFullscreenCtrl: true, - showZoomCtrl: true, - showShareCtrl: true, - showCounter: true, - showNextPreviousArrows: true, - showCaption: true, - verticalScrollForCaptions: false, - - preloaderEl: true, - closeOnOutsideClick: true, - - tapToClose: false, - tapToToggleControls: true, - - clickToCloseNonZoomable: true, - - shareButtons: [ - {id:'facebook', label:'Share on Facebook', url:'https://www.facebook.com/sharer/sharer.php?u={{url}}'}, - {id:'twitter', label:'Tweet', url:'https://twitter.com/intent/tweet?text={{text}}&url={{url}}'}, - {id:'pinterest', label:'Pin it', url:'http://www.pinterest.com/pin/create/button/'+ - '?url={{url}}&media={{image_url}}&description={{text}}'}, - {id:'download', label:'Download image', url:'{{raw_image_url}}', download:true} - ], - - getImageURLForShare: function( /* shareButtonData */ ) { - return pswp.currItem.src || ''; - }, + showCloseCtrl:true, + showFullscreenCtrl: true, + showZoomCtrl: true, + showShareCtrl: true, + showCounter: true, + showNextPreviousArrows: true, + showCaption: true, - getPageURLForShare: function( /* shareButtonData */ ) { - return window.location.href; - }, + preloaderEl: true, - getTextForShare: function( /* shareButtonData */ ) { - return pswp.currItem.title || ''; - }, - - indexIndicatorSep: ' / ', - fitControlsWidth: 1200 + closeOnOutsideClick: true, + tapToClose: false, + tapToToggleControls: true, - }, - _blockControlsTap, - _blockControlsTapTimeout; + clickToCloseNonZoomable: true, + shareButtons: [ + {id:'facebook', label:'Share on Facebook', url:'https://www.facebook.com/sharer/sharer.php?u={{url}}'}, + {id:'twitter', label:'Tweet', url:'https://twitter.com/intent/tweet?text={{text}}&url={{url}}'}, + {id:'pinterest', label:'Pin it', url:'http://www.pinterest.com/pin/create/button/'+ + '?url={{url}}&media={{image_url}}&description={{text}}'}, + {id:'download', label:'Download image', url:'{{raw_image_url}}', download:true} + ], + getImageURLForShare: function( /* shareButtonData */ ) { + return pswp.currItem.src || ''; + }, - var _onControlsTap = function(e) { - if(_blockControlsTap) { - return true; - } + getPageURLForShare: function( /* shareButtonData */ ) { + return window.location.href; + }, + getTextForShare: function( /* shareButtonData */ ) { + return pswp.currItem.title || ''; + }, - e = e || window.event; + indexIndicatorSep: ' / ', + fitControlsWidth: 1200 - if(_options.timeToIdle && _options.mouseUsed && !_isIdle) { - // reset idle timer - _onIdleMouseMove(); - } + }, + _blockControlsTap, + _blockControlsTapTimeout; - var target = e.target || e.srcElement, - uiElement, - clickedClass = target.getAttribute('class') || '', - found; - for(var i = 0; i < _uiElements.length; i++) { - uiElement = _uiElements[i]; - if(uiElement.onTap && clickedClass.indexOf('pswp__' + uiElement.name ) > -1 ) { - uiElement.onTap(); - found = true; + var _onControlsTap = function(e) { + if(_blockControlsTap) { + return true; + } + + + e = e || window.event; + if(_options.timeToIdle && _options.mouseUsed && !_isIdle) { + // reset idle timer + _onIdleMouseMove(); } - } - if(found) { - if(e.stopPropagation) { - e.stopPropagation(); - } - _blockControlsTap = true; - - // Some versions of Android don't prevent ghost click event - // when preventDefault() was called on touchstart and/or touchend. - // - // This happens on v4.3, 4.2, 4.1, - // older versions strangely work correctly, - // but just in case we add delay on all of them) - var tapDelay = framework.features.isOldAndroid ? 600 : 30; - _blockControlsTapTimeout = setTimeout(function() { - _blockControlsTap = false; - }, tapDelay); - } - }, + var target = e.target || e.srcElement, + uiElement, + clickedClass = target.getAttribute('class') || '', + found; - _fitControlsInViewport = function() { - return !pswp.likelyTouchDevice || _options.mouseUsed || screen.width > _options.fitControlsWidth; - }, + for(var i = 0; i < _uiElements.length; i++) { + uiElement = _uiElements[i]; + if(uiElement.onTap && clickedClass.indexOf('pswp__' + uiElement.name ) > -1 ) { + uiElement.onTap(); + found = true; - _togglePswpClass = function(el, cName, add) { - framework[ (add ? 'add' : 'remove') + 'Class' ](el, 'pswp__' + cName); - }, + } + } - // add class when there is just one item in the gallery - // (by default it hides left/right arrows and 1ofX counter) - _countNumItems = function() { - var hasOneSlide = (_options.getNumItemsFn() === 1); + if(found) { + if(e.stopPropagation) { + e.stopPropagation(); + } + _blockControlsTap = true; + + // Some versions of Android don't prevent ghost click event + // when preventDefault() was called on touchstart and/or touchend. + // + // This happens on v4.3, 4.2, 4.1, + // older versions strangely work correctly, + // but just in case we add delay on all of them) + var tapDelay = framework.features.isOldAndroid ? 600 : 30; + _blockControlsTapTimeout = setTimeout(function() { + _blockControlsTap = false; + }, tapDelay); + } - if(hasOneSlide !== _galleryHasOneSlide) { - _togglePswpClass(_controls, 'ui--one-slide', hasOneSlide); - _galleryHasOneSlide = hasOneSlide; - } - }, + }, - _toggleShareModalClass = function() { - _togglePswpClass(_shareModal, 'share-modal--hidden', _shareModalHidden); - }, + _fitControlsInViewport = function() { + return !pswp.likelyTouchDevice || _options.mouseUsed || screen.width > _options.fitControlsWidth; + }, - _toggleShareModal = function() { + _togglePswpClass = function(el, cName, add) { + framework[ (add ? 'add' : 'remove') + 'Class' ](el, 'pswp__' + cName); + }, - _shareModalHidden = !_shareModalHidden; - - - if(!_shareModalHidden) { - _toggleShareModalClass(); - setTimeout(function() { - if(!_shareModalHidden) { - framework.addClass(_shareModal, 'pswp__share-modal--fade-in'); - } - }, 30); - } else { - framework.removeClass(_shareModal, 'pswp__share-modal--fade-in'); - setTimeout(function() { - if(_shareModalHidden) { - _toggleShareModalClass(); - } - }, 300); - } - - if(!_shareModalHidden) { - _updateShareURLs(); - } - return false; - }, + // add class when there is just one item in the gallery + // (by default it hides left/right arrows and 1ofX counter) + _countNumItems = function() { + var hasOneSlide = (_options.getNumItemsFn() === 1); - _openWindowPopup = function(e) { - e = e || window.event; - var target = e.target || e.srcElement; + if(hasOneSlide !== _galleryHasOneSlide) { + _togglePswpClass(_controls, 'ui--one-slide', hasOneSlide); + _galleryHasOneSlide = hasOneSlide; + } + }, - pswp.shout('shareLinkClick', e, target); + _toggleShareModalClass = function() { + _togglePswpClass(_shareModal, 'share-modal--hidden', _shareModalHidden); + }, - if(!target.href) { - return false; - } + _toggleShareModal = function() { - if( target.hasAttribute('download') ) { - return true; - } + _shareModalHidden = !_shareModalHidden; - window.open(target.href, 'pswp_share', 'scrollbars=yes,resizable=yes,toolbar=no,'+ - 'location=yes,width=550,height=420,top=100,left=' + - (window.screen ? Math.round(screen.width / 2 - 275) : 100) ); - if(!_shareModalHidden) { - _toggleShareModal(); - } - - return false; - }, - - _updateShareURLs = function() { - var shareButtonOut = '', - shareButtonData, - shareURL, - image_url, - page_url, - share_text; - - for(var i = 0; i < _options.shareButtons.length; i++) { - shareButtonData = _options.shareButtons[i]; - - image_url = _options.getImageURLForShare(shareButtonData); - page_url = _options.getPageURLForShare(shareButtonData); - share_text = _options.getTextForShare(shareButtonData); - - shareURL = shareButtonData.url.replace('{{url}}', encodeURIComponent(page_url) ) - .replace('{{image_url}}', encodeURIComponent(image_url) ) - .replace('{{raw_image_url}}', image_url ) - .replace('{{text}}', encodeURIComponent(share_text) ); - - shareButtonOut += '' + - shareButtonData.label + ''; - - if(_options.parseShareButtonOut) { - shareButtonOut = _options.parseShareButtonOut(shareButtonData, shareButtonOut); + if(!_shareModalHidden) { + _toggleShareModalClass(); + setTimeout(function() { + if(!_shareModalHidden) { + framework.addClass(_shareModal, 'pswp__share-modal--fade-in'); + } + }, 30); + } else { + framework.removeClass(_shareModal, 'pswp__share-modal--fade-in'); + setTimeout(function() { + if(_shareModalHidden) { + _toggleShareModalClass(); + } + }, 300); } - } - _shareModal.children[0].innerHTML = shareButtonOut; - _shareModal.children[0].onclick = _openWindowPopup; - }, + if(!_shareModalHidden) { + _updateShareURLs(); + } + return false; + }, + + _openWindowPopup = function(e) { + e = e || window.event; + var target = e.target || e.srcElement; - _hasCloseClass = function(target) { - for(var i = 0; i < _options.closeElClasses.length; i++) { - if( framework.hasClass(target, 'pswp__' + _options.closeElClasses[i]) ) { + pswp.shout('shareLinkClick', e, target); + + if(!target.href) { + return false; + } + + if( target.hasAttribute('download') ) { return true; } - } - }, - _idleInterval, - _idleTimer, - _idleIncrement = 0, + window.open(target.href, 'pswp_share', 'scrollbars=yes,resizable=yes,toolbar=no,'+ + 'location=yes,width=550,height=420,top=100,left=' + + (window.screen ? Math.round(screen.width / 2 - 275) : 100) ); - _onIdleMouseMove = function() { - clearTimeout(_idleTimer); - _idleIncrement = 0; - if(_isIdle) { - ui.setIdle(false); - } - }, + if(!_shareModalHidden) { + _toggleShareModal(); + } + + return false; + }, + + _updateShareURLs = function() { + var shareButtonOut = '', + shareButtonData, + shareURL, + image_url, + page_url, + share_text; + + for(var i = 0; i < _options.shareButtons.length; i++) { + shareButtonData = _options.shareButtons[i]; + + image_url = _options.getImageURLForShare(shareButtonData); + page_url = _options.getPageURLForShare(shareButtonData); + share_text = _options.getTextForShare(shareButtonData); + + shareURL = shareButtonData.url.replace('{{url}}', encodeURIComponent(page_url) ) + .replace('{{image_url}}', encodeURIComponent(image_url) ) + .replace('{{raw_image_url}}', image_url ) + .replace('{{text}}', encodeURIComponent(share_text) ); + + shareButtonOut += '' + + shareButtonData.label + ''; + + if(_options.parseShareButtonOut) { + shareButtonOut = _options.parseShareButtonOut(shareButtonData, shareButtonOut); + } + } + _shareModal.children[0].innerHTML = shareButtonOut; + _shareModal.children[0].onclick = _openWindowPopup; - _onMouseLeaveWindow = function(e) { - e = e ? e : window.event; - var from = e.relatedTarget || e.toElement; - if (!from || from.nodeName === 'HTML') { + }, + + _hasCloseClass = function(target) { + for(var i = 0; i < _options.closeElClasses.length; i++) { + if( framework.hasClass(target, 'pswp__' + _options.closeElClasses[i]) ) { + return true; + } + } + }, + + _idleInterval, + _idleTimer, + _idleIncrement = 0, + + _onIdleMouseMove = function() { clearTimeout(_idleTimer); - _idleTimer = setTimeout(function() { - ui.setIdle(true); - }, _options.timeToIdleOutside); - } - }, + _idleIncrement = 0; + if(_isIdle) { + ui.setIdle(false); + } + }, - _setupFullscreenAPI = function() { - if(_options.fullscreenEl && !framework.features.isOldAndroid) { - if(!_fullscrenAPI) { - _fullscrenAPI = ui.getFullscreenAPI(); + _onMouseLeaveWindow = function(e) { + e = e ? e : window.event; + var from = e.relatedTarget || e.toElement; + if (!from || from.nodeName === 'HTML') { + clearTimeout(_idleTimer); + _idleTimer = setTimeout(function() { + ui.setIdle(true); + }, _options.timeToIdleOutside); } - if(_fullscrenAPI) { - framework.bind(document, _fullscrenAPI.eventK, ui.updateFullscreen); - ui.updateFullscreen(); - framework.addClass(pswp.template, 'pswp--supports-fs'); - } else { - framework.removeClass(pswp.template, 'pswp--supports-fs'); + }, + + _setupFullscreenAPI = function() { + if(_options.fullscreenEl && !framework.features.isOldAndroid) { + if(!_fullscrenAPI) { + _fullscrenAPI = ui.getFullscreenAPI(); + } + if(_fullscrenAPI) { + framework.bind(document, _fullscrenAPI.eventK, ui.updateFullscreen); + ui.updateFullscreen(); + framework.addClass(pswp.template, 'pswp--supports-fs'); + } else { + framework.removeClass(pswp.template, 'pswp--supports-fs'); + } } - } - }, + }, + + _setupLoadingIndicator = function() { + // Setup loading indicator + if(_options.preloaderEl) { + + _toggleLoadingIndicator(true); - _setupLoadingIndicator = function() { - // Setup loading indicator - if(_options.preloaderEl) { - - _toggleLoadingIndicator(true); + _listen('beforeChange', function() { - _listen('beforeChange', function() { + clearTimeout(_loadingIndicatorTimeout); - clearTimeout(_loadingIndicatorTimeout); + // display loading indicator with delay + _loadingIndicatorTimeout = setTimeout(function() { - // display loading indicator with delay - _loadingIndicatorTimeout = setTimeout(function() { + if(pswp.currItem && pswp.currItem.loading) { - if(pswp.currItem && pswp.currItem.loading) { + if( !pswp.allowProgressiveImg() || (pswp.currItem.img && !pswp.currItem.img.naturalWidth) ) { + // show preloader if progressive loading is not enabled, + // or image width is not defined yet (because of slow connection) + _toggleLoadingIndicator(false); + // items-controller.js function allowProgressiveImg + } - if( !pswp.allowProgressiveImg() || (pswp.currItem.img && !pswp.currItem.img.naturalWidth) ) { - // show preloader if progressive loading is not enabled, - // or image width is not defined yet (because of slow connection) - _toggleLoadingIndicator(false); - // items-controller.js function allowProgressiveImg + } else { + _toggleLoadingIndicator(true); // hide preloader } - - } else { - _toggleLoadingIndicator(true); // hide preloader + + }, _options.loadingIndicatorDelay); + }); + + _listen('imageLoadComplete', function(index, item) { + if(pswp.currItem === item) { + _toggleLoadingIndicator(true); } + }); - }, _options.loadingIndicatorDelay); - }); + } + }, - _listen('imageLoadComplete', function(index, item) { - if(pswp.currItem === item) { - _toggleLoadingIndicator(true); - } - }); + _toggleLoadingIndicator = function(hide) { + if( _loadingIndicatorHidden !== hide ) { + _togglePswpClass(_loadingIndicator, 'preloader--active', !hide); + _loadingIndicatorHidden = hide; + } + }, - } - }, + _applyNavBarGaps = function(item) { + var gap = item.vGap; - _toggleLoadingIndicator = function(hide) { - if( _loadingIndicatorHidden !== hide ) { - _togglePswpClass(_loadingIndicator, 'preloader--active', !hide); - _loadingIndicatorHidden = hide; - } - }, - - _applyNavBarGaps = function(item) { - var gap = item.vGap; - - if( _fitControlsInViewport() ) { - - var bars = _options.barsSize; - - if(_options.showCaption && bars.bottom === 'auto') { - // Why is this fake caption container created with visibility:hidden - // and why only when bottom bar height is 'auto'? - if(!_fakeCaptionContainer) { - _fakeCaptionContainer = framework.createElement('pswp__caption pswp__caption--fake'); - _fakeCaptionContainer.appendChild( framework.createElement('pswp__caption__center') ); - _controls.insertBefore(_fakeCaptionContainer, _captionContainer); - framework.addClass(_controls, 'pswp__ui--fit'); - } + if( _fitControlsInViewport() ) { + + var bars = _options.barsSize; + + if(_options.showCaption && bars.bottom === 'auto') { + // The _fakeCaptionContainer allows the height of the caption to be determined and the leftover + // space is available for the image i.e. as the caption expands, the image above it shrinks. + if(!_fakeCaptionContainer) { + _fakeCaptionContainer = framework.createElement('pswp__caption pswp__caption--fake'); + _fakeCaptionContainer.appendChild( framework.createElement('pswp__caption__center') ); + _controls.insertBefore(_fakeCaptionContainer, _captionContainer); + framework.addClass(_controls, 'pswp__ui--fit'); + } if( _options.addCaptionHTMLFn(item, _fakeCaptionContainer /*, true */) ) { - var captionSize = _fakeCaptionContainer.clientHeight; - gap.bottom = parseInt(captionSize,10) || 44; + var captionSize = _fakeCaptionContainer.clientHeight; + gap.bottom = parseInt(captionSize,10) || 44; + } else { + gap.bottom = bars.top; // if no caption, set size of bottom gap to size of top + } } else { - gap.bottom = bars.top; // if no caption, set size of bottom gap to size of top + gap.bottom = bars.bottom === 'auto' ? 0 : bars.bottom; } + + // height of top bar is static, no need to calculate it + gap.top = bars.top; } else { - gap.bottom = bars.bottom === 'auto' ? 0 : bars.bottom; + gap.top = gap.bottom = 0; } - - // height of top bar is static, no need to calculate it - gap.top = bars.top; - } else { - gap.top = gap.bottom = 0; - } - }, - - _setupIdle = function() { - // Hide controls when mouse is used - if(_options.timeToIdle) { - _listen('mouseUsed', function() { - - framework.bind(document, 'mousemove', _onIdleMouseMove); - framework.bind(document, 'mouseout', _onMouseLeaveWindow); - - _idleInterval = setInterval(function() { - _idleIncrement++; - if(_idleIncrement === 2) { - ui.setIdle(true); - } - }, _options.timeToIdle / 2); - }); - } - }, + }, - _setupHidingControlsDuringGestures = function() { + _setupIdle = function() { + // Hide controls when mouse is used + if(_options.timeToIdle) { + _listen('mouseUsed', function() { - // Hide controls on vertical drag - _listen('onVerticalDrag', function(now) { - if(_controlsVisible && now < 0.95) { - ui.hideControls(); - } else if(!_controlsVisible && now >= 0.95) { - ui.showControls(); - } - }); + framework.bind(document, 'mousemove', _onIdleMouseMove); + framework.bind(document, 'mouseout', _onMouseLeaveWindow); - // Hide controls when pinching to close - var pinchControlsHidden; - _listen('onPinchClose' , function(now) { - if(_controlsVisible && now < 0.9) { - ui.hideControls(); - pinchControlsHidden = true; - } else if(pinchControlsHidden && !_controlsVisible && now > 0.9) { - ui.showControls(); + _idleInterval = setInterval(function() { + _idleIncrement++; + if(_idleIncrement === 2) { + ui.setIdle(true); + } + }, _options.timeToIdle / 2); + }); } - }); + }, - _listen('zoomGestureEnded', function() { - pinchControlsHidden = false; - if(pinchControlsHidden && !_controlsVisible) { - ui.showControls(); - } - }); + _setupHidingControlsDuringGestures = function() { - }; + // Hide controls on vertical drag + _listen('onVerticalDrag', function(now) { + if(_controlsVisible && now < 0.95) { + ui.hideControls(); + } else if(!_controlsVisible && now >= 0.95) { + ui.showControls(); + } + }); + // Hide controls when pinching to close + var pinchControlsHidden; + _listen('onPinchClose' , function(now) { + if(_controlsVisible && now < 0.9) { + ui.hideControls(); + pinchControlsHidden = true; + } else if(pinchControlsHidden && !_controlsVisible && now > 0.9) { + ui.showControls(); + } + }); + _listen('zoomGestureEnded', function() { + pinchControlsHidden = false; + if(pinchControlsHidden && !_controlsVisible) { + ui.showControls(); + } + }); + + }; - var _uiElements = [ - { - name: 'caption', - option: 'showCaption', - onInit: function(el) { - _captionContainer = el; - } - }, - { - name: 'share-modal', - option: 'showShareCtrl', - onInit: function(el) { - _shareModal = el; + + + var _uiElements = [ + { + name: 'caption', + option: 'showCaption', + onInit: function(el) { + _captionContainer = el; + } }, - onTap: function() { - _toggleShareModal(); - } - }, - { - name: 'button--share', - option: 'showShareCtrl', - onInit: function(el) { - _shareButton = el; + { + name: 'share-modal', + option: 'showShareCtrl', + onInit: function(el) { + _shareModal = el; + }, + onTap: function() { + _toggleShareModal(); + } }, - onTap: function() { - _toggleShareModal(); - } - }, - { - name: 'button--zoom', - option: 'showZoomCtrl', - onTap: pswp.toggleDesktopZoom - }, - { - name: 'counter', - option: 'showCounter', - onInit: function(el) { - _indexIndicator = el; - } - }, - { - name: 'button--close', - option: 'showCloseCtrl', - onTap: function() { - setTimeout(pswp.close); - } - }, - { - name: 'button--arrow--left', - option: 'showNextPreviousArrows', - onTap: pswp.prev - }, - { - name: 'button--arrow--right', - option: 'showNextPreviousArrows', - onTap: pswp.next - }, - { - name: 'button--fs', - option: 'showFullscreenCtrl', - onTap: function() { - if(_fullscrenAPI.isFullscreen()) { - _fullscrenAPI.exit(); - } else { - _fullscrenAPI.enter(); - } - } - }, - { - name: 'preloader', - option: 'preloaderEl', - onInit: function(el) { - _loadingIndicator = el; - } - } - - ]; - - var _setupUIElements = function() { - var item, - classAttr, - uiElement; - - var loopThroughChildElements = function(sChildren) { - if(!sChildren) { - return; + { + name: 'button--share', + option: 'showShareCtrl', + onInit: function(el) { + _shareButton = el; + }, + onTap: function() { + _toggleShareModal(); + } + }, + { + name: 'button--zoom', + option: 'showZoomCtrl', + onTap: pswp.toggleDesktopZoom + }, + { + name: 'counter', + option: 'showCounter', + onInit: function(el) { + _indexIndicator = el; + } + }, + { + name: 'button--close', + option: 'showCloseCtrl', + onTap: function() { + setTimeout(pswp.close); + } + }, + { + name: 'button--arrow--left', + option: 'showNextPreviousArrows', + onTap: pswp.prev + }, + { + name: 'button--arrow--right', + option: 'showNextPreviousArrows', + onTap: pswp.next + }, + { + name: 'button--fs', + option: 'showFullscreenCtrl', + onTap: function() { + if(_fullscrenAPI.isFullscreen()) { + _fullscrenAPI.exit(); + } else { + _fullscrenAPI.enter(); + } + } + }, + { + name: 'preloader', + option: 'preloaderEl', + onInit: function(el) { + _loadingIndicator = el; + } } - var l = sChildren.length; - for(var i = 0; i < l; i++) { - item = sChildren[i]; - classAttr = item.className; + ]; + + var _setupUIElements = function() { + var item, + classAttr, + uiElement; - for(var a = 0; a < _uiElements.length; a++) { - uiElement = _uiElements[a]; + var loopThroughChildElements = function(sChildren) { + if(!sChildren) { + return; + } - if(classAttr.indexOf('pswp__' + uiElement.name) > -1 ) { + var l = sChildren.length; + for(var i = 0; i < l; i++) { + item = sChildren[i]; + classAttr = item.className; - if( _options[uiElement.option] ) { // if element is not disabled from options - - framework.removeClass(item, 'pswp__element--disabled'); - if(uiElement.onInit) { - uiElement.onInit(item); + for(var a = 0; a < _uiElements.length; a++) { + uiElement = _uiElements[a]; + + if(classAttr.indexOf('pswp__' + uiElement.name) > -1 ) { + + if( _options[uiElement.option] ) { // if element is not disabled from options + + framework.removeClass(item, 'pswp__element--disabled'); + if(uiElement.onInit) { + uiElement.onInit(item); + } + + //item.style.display = 'block'; + } else { + framework.addClass(item, 'pswp__element--disabled'); + //item.style.display = 'none'; } - - //item.style.display = 'block'; - } else { - framework.addClass(item, 'pswp__element--disabled'); - //item.style.display = 'none'; } } } + }; + loopThroughChildElements(_controls.children); + + var topBar = framework.getChildByClass(_controls, 'pswp__top-bar'); + if(topBar) { + loopThroughChildElements( topBar.children ); } }; - loopThroughChildElements(_controls.children); - var topBar = framework.getChildByClass(_controls, 'pswp__top-bar'); - if(topBar) { - loopThroughChildElements( topBar.children ); - } - }; - - ui.init = function() { + ui.init = function() { - // extend options - framework.extend(pswp.options, _defaultUIOptions, true); + // extend options + framework.extend(pswp.options, _defaultUIOptions, true); - // create local link for fast access - _options = pswp.options; + // create local link for fast access + _options = pswp.options; - // find pswp__ui element - _controls = framework.getChildByClass(pswp.scrollWrap, 'pswp__ui'); + // find pswp__ui element + _controls = framework.getChildByClass(pswp.scrollWrap, 'pswp__ui'); - // create local link - _listen = pswp.listen; + // create local link + _listen = pswp.listen; - _setupHidingControlsDuringGestures(); + _setupHidingControlsDuringGestures(); - // update controls when slides change - _listen('beforeChange', ui.update); + // update controls when slides change + _listen('beforeChange', ui.update); - // toggle zoom on double-tap - _listen('doubleTap', function(point) { - var initialZoomLevel = pswp.currItem.initialZoomLevel; - if(pswp.getZoomLevel() !== initialZoomLevel) { - pswp.zoomTo(initialZoomLevel, point, 333); - } else { - pswp.zoomTo(_options.getDoubleTapZoom(false, pswp.currItem), point, 333); - } - }); - - // Allow text selection in caption - _listen('preventDragEvent', function(e, isDown, preventObj) { - var t = e.target || e.srcElement; - if( - t && - t.getAttribute('class') && e.type.indexOf('mouse') > -1 && - ( t.getAttribute('class').indexOf('__caption') > 0 || (/(SMALL|STRONG|EM)/i).test(t.tagName) ) - ) { - preventObj.prevent = false; - } - }); - - // bind events for UI - _listen('bindEvents', function() { - framework.bind(_controls, 'pswpTap click', _onControlsTap); - framework.bind(pswp.scrollWrap, 'pswpTap', ui.onGlobalTap); - - if(!pswp.likelyTouchDevice) { - framework.bind(pswp.scrollWrap, 'mouseover', ui.onMouseOver); - } - }); - - // unbind events for UI - _listen('unbindEvents', function() { - if(!_shareModalHidden) { - _toggleShareModal(); - } + // toggle zoom on double-tap + _listen('doubleTap', function(point) { + var initialZoomLevel = pswp.currItem.initialZoomLevel; + if(pswp.getZoomLevel() !== initialZoomLevel) { + pswp.zoomTo(initialZoomLevel, point, 333); + } else { + pswp.zoomTo(_options.getDoubleTapZoom(false, pswp.currItem), point, 333); + } + }); - if(_idleInterval) { - clearInterval(_idleInterval); - } - framework.unbind(document, 'mouseout', _onMouseLeaveWindow); - framework.unbind(document, 'mousemove', _onIdleMouseMove); - framework.unbind(_controls, 'pswpTap click', _onControlsTap); - framework.unbind(pswp.scrollWrap, 'pswpTap', ui.onGlobalTap); - framework.unbind(pswp.scrollWrap, 'mouseover', ui.onMouseOver); - - if(_fullscrenAPI) { - framework.unbind(document, _fullscrenAPI.eventK, ui.updateFullscreen); - if(_fullscrenAPI.isFullscreen()) { - _options.hideAnimationDuration = 0; - _fullscrenAPI.exit(); - } - _fullscrenAPI = null; - } - }); + // Allow text selection in caption + _listen('preventDragEvent', function(e, isDown, preventObj) { + var t = e.target || e.srcElement; + if( + t && + t.getAttribute('class') && e.type.indexOf('mouse') > -1 && + ( t.getAttribute('class').indexOf('__caption') > 0 || (/(SMALL|STRONG|EM)/i).test(t.tagName) ) + ) { + preventObj.prevent = false; + } + }); + // bind events for UI + _listen('bindEvents', function() { + framework.bind(_controls, 'pswpTap click', _onControlsTap); + framework.bind(pswp.scrollWrap, 'pswpTap', ui.onGlobalTap); - // clean up things when gallery is destroyed - _listen('destroy', function() { - if(_options.showCaption) { - if(_fakeCaptionContainer) { - _controls.removeChild(_fakeCaptionContainer); + if(!pswp.likelyTouchDevice) { + framework.bind(pswp.scrollWrap, 'mouseover', ui.onMouseOver); } - framework.removeClass(_captionContainer, 'pswp__caption--empty'); - } + }); - if(_shareModal) { - _shareModal.children[0].onclick = null; - } - framework.removeClass(_controls, 'pswp__ui--over-close'); - framework.addClass( _controls, 'pswp__ui--hidden'); - ui.setIdle(false); - }); - - - if(!_options.showAnimationDuration) { - framework.removeClass( _controls, 'pswp__ui--hidden'); - } - _listen('initialZoomIn', function() { - if(_options.showAnimationDuration) { - framework.removeClass( _controls, 'pswp__ui--hidden'); - } - }); - _listen('initialZoomOut', function() { - framework.addClass( _controls, 'pswp__ui--hidden'); - }); + // unbind events for UI + _listen('unbindEvents', function() { + if(!_shareModalHidden) { + _toggleShareModal(); + } - _listen('parseVerticalMargin', _applyNavBarGaps); - - _setupUIElements(); + if(_idleInterval) { + clearInterval(_idleInterval); + } + framework.unbind(document, 'mouseout', _onMouseLeaveWindow); + framework.unbind(document, 'mousemove', _onIdleMouseMove); + framework.unbind(_controls, 'pswpTap click', _onControlsTap); + framework.unbind(pswp.scrollWrap, 'pswpTap', ui.onGlobalTap); + framework.unbind(pswp.scrollWrap, 'mouseover', ui.onMouseOver); - if(_options.shareEl && _shareButton && _shareModal) { - _shareModalHidden = true; - } + if(_fullscrenAPI) { + framework.unbind(document, _fullscrenAPI.eventK, ui.updateFullscreen); + if(_fullscrenAPI.isFullscreen()) { + _options.hideAnimationDuration = 0; + _fullscrenAPI.exit(); + } + _fullscrenAPI = null; + } + }); - _countNumItems(); - _setupIdle(); + // clean up things when gallery is destroyed + _listen('destroy', function() { + if(_options.showCaption) { + if(_fakeCaptionContainer) { + _controls.removeChild(_fakeCaptionContainer); + } + framework.removeClass(_captionContainer, 'pswp__caption--empty'); + } - _setupFullscreenAPI(); + if(_shareModal) { + _shareModal.children[0].onclick = null; + } + framework.removeClass(_controls, 'pswp__ui--over-close'); + framework.addClass( _controls, 'pswp__ui--hidden'); + ui.setIdle(false); + }); - _setupLoadingIndicator(); - }; - ui.setIdle = function(isIdle) { - _isIdle = isIdle; - _togglePswpClass(_controls, 'ui--idle', isIdle); - }; + if(!_options.showAnimationDuration) { + framework.removeClass( _controls, 'pswp__ui--hidden'); + } + _listen('initialZoomIn', function() { + if(_options.showAnimationDuration) { + framework.removeClass( _controls, 'pswp__ui--hidden'); + } + }); + _listen('initialZoomOut', function() { + framework.addClass( _controls, 'pswp__ui--hidden'); + }); - ui.update = function() { - // Don't update UI if it's hidden - if(_controlsVisible && pswp.currItem) { - - ui.updateIndexIndicator(); + _listen('parseVerticalMargin', _applyNavBarGaps); - if(_options.showCaption) { - _options.addCaptionHTMLFn(pswp.currItem, _captionContainer); + _setupUIElements(); - _togglePswpClass(_captionContainer, 'caption--empty', !pswp.currItem.title); + if(_options.shareEl && _shareButton && _shareModal) { + _shareModalHidden = true; } - _overlayUIUpdated = true; - - } else { - _overlayUIUpdated = false; - } + _countNumItems(); - if(!_shareModalHidden) { - _toggleShareModal(); - } + _setupIdle(); - _countNumItems(); - }; + _setupFullscreenAPI(); - ui.updateFullscreen = function(e) { - - if(e) { - // some browsers change window scroll position during the fullscreen - // so PhotoSwipe updates it just in case - setTimeout(function() { - pswp.setScrollOffset( 0, framework.getScrollY() ); - }, 50); - } - - // toogle pswp--fs class on root element - framework[ (_fullscrenAPI.isFullscreen() ? 'add' : 'remove') + 'Class' ](pswp.template, 'pswp--fs'); - }; + _setupLoadingIndicator(); + }; - ui.updateIndexIndicator = function() { - if(_options.showCounter) { - _indexIndicator.innerHTML = (pswp.getCurrentIndex()+1) + - _options.indexIndicatorSep + - _options.getNumItemsFn(); - } - }; - - ui.onGlobalTap = function(e) { - e = e || window.event; - var target = e.target || e.srcElement; + ui.setIdle = function(isIdle) { + _isIdle = isIdle; + _togglePswpClass(_controls, 'ui--idle', isIdle); + }; - if(_blockControlsTap) { - return; - } + ui.update = function() { + // Don't update UI if it's hidden + if(_controlsVisible && pswp.currItem) { - if(e.detail && e.detail.pointerType === 'mouse') { + ui.updateIndexIndicator(); - // Silently ignore right-click events. - if (!e.detail.rightClick) { + if(_options.showCaption) { + _options.addCaptionHTMLFn(pswp.currItem, _captionContainer); - // close gallery if clicked outside of the image - if(_options.closeOnOutsideClick && _hasCloseClass(target)) { - pswp.close(); - return; + _togglePswpClass(_captionContainer, 'caption--empty', !pswp.currItem.title); } - if(framework.hasClass(target, 'pswp__img')) { - if(pswp.getZoomLevel() === 1 && pswp.getZoomLevel() <= pswp.currItem.fitRatio) { - if(_options.clickToCloseNonZoomable) { - pswp.close(); - } - } else { - pswp.toggleDesktopZoom(e.detail.releasePoint); - } - } - - } - - } else { + _overlayUIUpdated = true; - // tap anywhere (except buttons) to toggle visibility of controls - if(_options.tapToToggleControls) { - if(_controlsVisible) { - ui.hideControls(); - } else { - ui.showControls(); - } + } else { + _overlayUIUpdated = false; } - // tap to close gallery - if(_options.tapToClose && (framework.hasClass(target, 'pswp__img') || - _options.closeOnOutsideClick && _hasCloseClass(target)) ) { - pswp.close(); - return; + if(!_shareModalHidden) { + _toggleShareModal(); } - - } - }; - ui.onMouseOver = function(e) { - e = e || window.event; - var target = e.target || e.srcElement; - // add class when mouse is over an element that should close the gallery - _togglePswpClass(_controls, 'ui--over-close', _hasCloseClass(target)); - }; + _countNumItems(); + }; - ui.hideControls = function() { - framework.addClass(_controls,'pswp__ui--hidden'); - _controlsVisible = false; - }; + ui.updateFullscreen = function(e) { - ui.showControls = function() { - _controlsVisible = true; - if(!_overlayUIUpdated) { - ui.update(); - } - framework.removeClass(_controls,'pswp__ui--hidden'); - }; + if(e) { + // some browsers change window scroll position during the fullscreen + // so PhotoSwipe updates it just in case + setTimeout(function() { + pswp.setScrollOffset( 0, framework.getScrollY() ); + }, 50); + } - ui.supportsFullscreen = function() { - var d = document; - return !!(d.exitFullscreen || d.mozCancelFullScreen || d.webkitExitFullscreen || d.msExitFullscreen); - }; + // toogle pswp--fs class on root element + framework[ (_fullscrenAPI.isFullscreen() ? 'add' : 'remove') + 'Class' ](pswp.template, 'pswp--fs'); + }; - ui.getFullscreenAPI = function() { - var dE = document.documentElement, - api, - tF = 'fullscreenchange'; - - if (dE.requestFullscreen) { - api = { - enterK: 'requestFullscreen', - exitK: 'exitFullscreen', - elementK: 'fullscreenElement', - eventK: tF - }; + ui.updateIndexIndicator = function() { + if(_options.showCounter) { + _indexIndicator.innerHTML = (pswp.getCurrentIndex()+1) + + _options.indexIndicatorSep + + _options.getNumItemsFn(); + } + }; - } else if(dE.mozRequestFullScreen ) { - api = { - enterK: 'mozRequestFullScreen', - exitK: 'mozCancelFullScreen', - elementK: 'mozFullScreenElement', - eventK: 'moz' + tF - }; + ui.onGlobalTap = function(e) { + e = e || window.event; + var target = e.target || e.srcElement; + + if(_blockControlsTap) { + return; + } - + if(e.detail && e.detail.pointerType === 'mouse') { - } else if(dE.webkitRequestFullscreen) { - api = { - enterK: 'webkitRequestFullscreen', - exitK: 'webkitExitFullscreen', - elementK: 'webkitFullscreenElement', - eventK: 'webkit' + tF - }; + // Silently ignore right-click events. + if (!e.detail.rightClick) { + // close gallery if clicked outside of the image + if(_options.closeOnOutsideClick && _hasCloseClass(target)) { + pswp.close(); + return; + } - } else if(dE.msRequestFullscreen) { - api = { - enterK: 'msRequestFullscreen', - exitK: 'msExitFullscreen', - elementK: 'msFullscreenElement', - eventK: 'MSFullscreenChange' - }; - } + if(framework.hasClass(target, 'pswp__img')) { + if(pswp.getZoomLevel() === 1 && pswp.getZoomLevel() <= pswp.currItem.fitRatio) { + if(_options.clickToCloseNonZoomable) { + pswp.close(); + } + } else { + pswp.toggleDesktopZoom(e.detail.releasePoint); + } + } + } + } else { - if(api) { - api.enter = function() { - // disable close-on-scroll in fullscreen - _initalCloseOnScrollValue = _options.closeOnScroll; - _options.closeOnScroll = false; + // tap anywhere (except buttons) to toggle visibility of controls + if(_options.tapToToggleControls) { + if(_controlsVisible) { + ui.hideControls(); + } else { + ui.showControls(); + } + } - if(this.enterK === 'webkitRequestFullscreen') { - pswp.template[this.enterK]( Element.ALLOW_KEYBOARD_INPUT ); - } else { - return pswp.template[this.enterK](); + // tap to close gallery + if(_options.tapToClose && (framework.hasClass(target, 'pswp__img') || + _options.closeOnOutsideClick && _hasCloseClass(target)) ) { + pswp.close(); + return; } - }; - api.exit = function() { - _options.closeOnScroll = _initalCloseOnScrollValue; - return document[this.exitK](); + } + }; + ui.onMouseOver = function(e) { + e = e || window.event; + var target = e.target || e.srcElement; - }; - api.isFullscreen = function() { return document[this.elementK]; }; - } + // add class when mouse is over an element that should close the gallery + _togglePswpClass(_controls, 'ui--over-close', _hasCloseClass(target)); + }; - return api; - }; + ui.hideControls = function() { + framework.addClass(_controls,'pswp__ui--hidden'); + _controlsVisible = false; + }; + ui.showControls = function() { + _controlsVisible = true; + if(!_overlayUIUpdated) { + ui.update(); + } + framework.removeClass(_controls,'pswp__ui--hidden'); + }; + ui.supportsFullscreen = function() { + var d = document; + return !!(d.exitFullscreen || d.mozCancelFullScreen || d.webkitExitFullscreen || d.msExitFullscreen); + }; + + ui.getFullscreenAPI = function() { + var dE = document.documentElement, + api, + tF = 'fullscreenchange'; + + if (dE.requestFullscreen) { + api = { + enterK: 'requestFullscreen', + exitK: 'exitFullscreen', + elementK: 'fullscreenElement', + eventK: tF + }; + + } else if(dE.mozRequestFullScreen ) { + api = { + enterK: 'mozRequestFullScreen', + exitK: 'mozCancelFullScreen', + elementK: 'mozFullScreenElement', + eventK: 'moz' + tF + }; + + + + } else if(dE.webkitRequestFullscreen) { + api = { + enterK: 'webkitRequestFullscreen', + exitK: 'webkitExitFullscreen', + elementK: 'webkitFullscreenElement', + eventK: 'webkit' + tF + }; + + } else if(dE.msRequestFullscreen) { + api = { + enterK: 'msRequestFullscreen', + exitK: 'msExitFullscreen', + elementK: 'msFullscreenElement', + eventK: 'MSFullscreenChange' + }; + } + + if(api) { + api.enter = function() { + // disable close-on-scroll in fullscreen + _initalCloseOnScrollValue = _options.closeOnScroll; + _options.closeOnScroll = false; + + if(this.enterK === 'webkitRequestFullscreen') { + pswp.template[this.enterK]( Element.ALLOW_KEYBOARD_INPUT ); + } else { + return pswp.template[this.enterK](); + } + }; + api.exit = function() { + _options.closeOnScroll = _initalCloseOnScrollValue; -}; -return PhotoSwipeUI_Default; + return document[this.exitK](); + }; + api.isFullscreen = function() { return document[this.elementK]; }; + } + + return api; + }; + }; + return PhotoSwipeUI_Default; }); From bfb2560f3fa34946596ff235199beb4afb28a0e2 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 23 Apr 2020 19:49:32 +0100 Subject: [PATCH 10/39] First pass with something that works. Need to fix z-index on captionElement and arrows and figure out why it is failing on mobile. --- src/css/default-skin/default-skin.scss | 2 +- src/js/items-controller.js | 6 ++- src/js/ui/photoswipe-ui-default.js | 51 +++++++++++++++++++++++--- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index a11a6f36d..42fcac040 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -349,7 +349,7 @@ a.pswp__share--download { max-width: 420px; margin: 0 auto; font-size: 13px; - padding: 10px; + padding: 20px 10px 10px 10px; line-height: 20px; color: #CCC; } diff --git a/src/js/items-controller.js b/src/js/items-controller.js index 5cd21ef4c..7476e5339 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -201,8 +201,10 @@ var _getItemAt, img = item.container.lastChild; } - var w = item.calculatedWidth = maxRes ? item.w : Math.round(item.w * item.fitRatio), - h = item.calculatedHeight = maxRes ? item.h : Math.round(item.h * item.fitRatio); + item.calculatedSize = {}; + + var w = item.calculatedSize.x = maxRes ? item.w : Math.round(item.w * item.fitRatio), + h = item.calculatedSize.y = maxRes ? item.h : Math.round(item.h * item.fitRatio); // ensure correct aspect ratio if(img.naturalHeight && img.naturalWidth) { diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 1266efceb..0d48e3595 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -49,12 +49,28 @@ timeToIdleOutside: 1000, loadingIndicatorDelay: 1000, // 2s - addCaptionHTMLFn: function(item, captionElement /*, isFake */) { + addCaptionHTMLFn: function(item, captionElement /*, isFake */) { + var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); if(!item.title) { - captionElement.children[0].innerHTML = ''; + innerCaptionElement.innerHTML = ''; return false; } - captionElement.children[0].innerHTML = item.title; + innerCaptionElement.innerHTML = item.title; + + // If verticalScrollForCaption it true, position caption from top rather than bottom. + if(_options.verticalScrollForCaption) { + item.imageBottomAt = item.vGap.top + item.calculatedSize.y; + captionElement.style.bottom = 'auto'; + captionElement.style.top = item.imageBottomAt + "px"; + + // Show the 'expand' control if caption extends out of view + if(innerCaptionElement.clientHeight > item.vGap.bottom) { + var captionCtrl = captionElement.querySelector(".pswp__caption__handle"); + captionCtrl.classList.add("pswp__caption__handle--expand"); + captionCtrl.addEventListener("click", toggleCaption.bind(null, item, captionElement, captionCtrl)); + } + } + return true; }, @@ -65,6 +81,7 @@ showCounter: true, showNextPreviousArrows: true, showCaption: true, + verticalScrollForCaption: true, preloaderEl: true, @@ -101,7 +118,31 @@ _blockControlsTap, _blockControlsTapTimeout; + var toggleCaption = function(item, captionElement, captionCtrl) { + var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); + if(captionCtrl.classList.contains("pswp__caption__handle--expand")){ + var topAfterExpansion = item.vGap.top; + if(captionElement.clientHeight < item.calculatedSize.y + item.vGap.bottom) { + topAfterExpansion = item.vGap.top + item.vGap.bottom + (item.calculatedSize.y - captionElement.clientHeight); + captionElement.style.height = 'auto'; + } + else { + innerCaptionElement.style.height = item.calculatedSize.y + item.vGap.bottom + "px"; + innerCaptionElement.style.overflowY = "auto"; + } + + captionElement.style.top = topAfterExpansion + "px"; + captionCtrl.classList.remove("pswp__caption__handle--expand"); + captionCtrl.classList.add("pswp__caption__handle--collapse"); + } + else { + innerCaptionElement.style.height = 'auto'; + captionElement.style.top = (item.vGap.top + item.calculatedSize.y) + "px"; + captionCtrl.classList.add("pswp__caption__handle--expand"); + captionCtrl.classList.remove("pswp__caption__handle--collapse"); + } + }; var _onControlsTap = function(e) { if(_blockControlsTap) { @@ -360,7 +401,7 @@ if(_options.showCaption && bars.bottom === 'auto') { // The _fakeCaptionContainer allows the height of the caption to be determined and the leftover - // space is available for the image i.e. as the caption expands, the image above it shrinks. + // space is available for the image and top bar i.e. as the caption expands, the image above it shrinks. if(!_fakeCaptionContainer) { _fakeCaptionContainer = framework.createElement('pswp__caption pswp__caption--fake'); _fakeCaptionContainer.appendChild( framework.createElement('pswp__caption__center') ); @@ -368,7 +409,7 @@ framework.addClass(_controls, 'pswp__ui--fit'); } - if( _options.addCaptionHTMLFn(item, _fakeCaptionContainer /*, true */) ) { + if( _options.addCaptionHTMLFn(item, _fakeCaptionContainer /*, true */) ) { var captionSize = _fakeCaptionContainer.clientHeight; gap.bottom = parseInt(captionSize,10) || 44; } else { From 140bdce598df62228cfa01116b33038144fa62fe Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 23 Apr 2020 19:49:32 +0100 Subject: [PATCH 11/39] Add some lines to seperate functions --- Gruntfile.js | 4 ++-- src/js/core.js | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index f640b04a7..2a3c3c338 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -173,7 +173,6 @@ module.exports = function(grunt) { } } - }); @@ -185,7 +184,8 @@ module.exports = function(grunt) { basePath = this.data.basePath, newContents = this.data.banner; - newContents += "(function (root, factory) { \n"+ + newContents += "// Using UMD (Universal Module Definition) https://www.davidbcalhoun.com/2014/what-is-amd-commonjs-and-umd/\n" + + "(function (root, factory) { \n"+ "\tif (typeof define === 'function' && define.amd) {\n" + "\t\tdefine(factory);\n" + "\t} else if (typeof exports === 'object') {\n" + diff --git a/src/js/core.js b/src/js/core.js index 5797ae8ad..181cc6569 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -775,9 +775,11 @@ var publicMethods = { self.updateCurrItem(); }, + next: function() { self.goTo( parseInt(_currentItemIndex) + 1); }, + prev: function() { self.goTo( parseInt(_currentItemIndex) - 1); }, @@ -873,6 +875,7 @@ var publicMethods = { _containerShiftIndex += _indexDiff + (_indexDiff > 0 ? -NUM_HOLDERS : NUM_HOLDERS); diffAbs = NUM_HOLDERS; } + for(var i = 0; i < diffAbs; i++) { if(_indexDiff > 0) { tempHolder = _itemHolders.shift(); From 1d3b1c71c075b254a648e8ef72233358d4c66e2f Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 23 Apr 2020 22:08:02 +0100 Subject: [PATCH 12/39] Rename button to be consistent pattern with others. Fix z-index issue so arrows are above expanded caption. --- src/css/default-skin/default-skin.scss | 50 ++++++++++++++++++++++++++ src/js/ui/photoswipe-ui-default.js | 14 ++++---- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index 42fcac040..031411ebd 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -142,6 +142,7 @@ width: 70px; height: 100px; position: absolute; + z-index: 3; } .pswp__button--arrow--left { @@ -333,6 +334,7 @@ a.pswp__share--download { .pswp__caption { position: absolute; + z-index: 2; left: 0; bottom: 0; width: 100%; @@ -352,6 +354,53 @@ a.pswp__share--download { padding: 20px 10px 10px 10px; line-height: 20px; color: #CCC; + background-color: #000; + + a { + color: #CCC; + } + a:hover { + color: #FFF; + } +} + +.pswp__button--caption--ctrl { + display: none; + width: 44px; + height: 44px; + background-image: none; + background-color: #000; + color: #999; + border-radius: 22px; + border: 1px solid #999; + overflow: hidden; + position: absolute; + top: -22px; + left: 50%; + transform: translateX(-50%); + text-decoration: none; + opacity: 1; +} +.pswp__button--caption--ctrl:hover { + color: #fff; + border-color: #fff; +} +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand, +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse { + display:block; +} +.pswp__button--caption--ctrl::before { + position: relative; + top: -8px; + left: 1px; + font-size: 42px; +} + +.pswp__button--caption--ctrl--expand::before { + content: "\02b9d"; +} +.pswp__button--caption--ctrl--collapse::before { + content: "\02b9f"; } .pswp__caption--empty { @@ -491,6 +540,7 @@ a.pswp__share--download { /* top black bar with buttons and "1 of X" indicator */ .pswp__top-bar { position: absolute; + z-index: 1; left: 0; top: 0; height: 44px; diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 0d48e3595..7339b9456 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -65,8 +65,8 @@ // Show the 'expand' control if caption extends out of view if(innerCaptionElement.clientHeight > item.vGap.bottom) { - var captionCtrl = captionElement.querySelector(".pswp__caption__handle"); - captionCtrl.classList.add("pswp__caption__handle--expand"); + var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); + captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.addEventListener("click", toggleCaption.bind(null, item, captionElement, captionCtrl)); } } @@ -121,7 +121,7 @@ var toggleCaption = function(item, captionElement, captionCtrl) { var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); - if(captionCtrl.classList.contains("pswp__caption__handle--expand")){ + if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")){ var topAfterExpansion = item.vGap.top; if(captionElement.clientHeight < item.calculatedSize.y + item.vGap.bottom) { topAfterExpansion = item.vGap.top + item.vGap.bottom + (item.calculatedSize.y - captionElement.clientHeight); @@ -133,14 +133,14 @@ } captionElement.style.top = topAfterExpansion + "px"; - captionCtrl.classList.remove("pswp__caption__handle--expand"); - captionCtrl.classList.add("pswp__caption__handle--collapse"); + captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); + captionCtrl.classList.add("pswp__button--caption--ctrl--collapse"); } else { innerCaptionElement.style.height = 'auto'; captionElement.style.top = (item.vGap.top + item.calculatedSize.y) + "px"; - captionCtrl.classList.add("pswp__caption__handle--expand"); - captionCtrl.classList.remove("pswp__caption__handle--collapse"); + captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); + captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); } }; From 940d89822dfe9f5d56b5fc9f10dda4b9bdc8abed Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 23 Apr 2020 22:29:30 +0100 Subject: [PATCH 13/39] Fix display/hiding of expand control when switching photos. --- src/js/ui/photoswipe-ui-default.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 7339b9456..83d6b454b 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -63,12 +63,17 @@ captionElement.style.bottom = 'auto'; captionElement.style.top = item.imageBottomAt + "px"; - // Show the 'expand' control if caption extends out of view + // Show the 'expand' control if caption extends out of view. Reset height first. + innerCaptionElement.style.height = 'auto'; + var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); if(innerCaptionElement.clientHeight > item.vGap.bottom) { - var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.addEventListener("click", toggleCaption.bind(null, item, captionElement, captionCtrl)); } + else { + captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); + captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); + } } return true; @@ -125,7 +130,6 @@ var topAfterExpansion = item.vGap.top; if(captionElement.clientHeight < item.calculatedSize.y + item.vGap.bottom) { topAfterExpansion = item.vGap.top + item.vGap.bottom + (item.calculatedSize.y - captionElement.clientHeight); - captionElement.style.height = 'auto'; } else { innerCaptionElement.style.height = item.calculatedSize.y + item.vGap.bottom + "px"; From dfe1ec5aadb4f65570320594006c93c26231be54 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Fri, 24 Apr 2020 19:28:30 +0100 Subject: [PATCH 14/39] Set data attributes on .pswp__item to carry initial image height and top/bottom gaps so that caption function can be initiated with just the event. Not sure if this is better or just different. --- src/js/items-controller.js | 26 ++++++++++++++++-------- src/js/ui/photoswipe-ui-default.js | 32 ++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/js/items-controller.js b/src/js/items-controller.js index 7476e5339..46b2cd2ec 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -145,11 +145,11 @@ var _getItemAt, }, - _preloadImage = function(item) { item.loading = true; item.loaded = false; var img = item.img = framework.createElement('pswp__img', 'img'); + var onComplete = function() { item.loading = false; item.loaded = true; @@ -170,7 +170,9 @@ var _getItemAt, img.onload = img.onerror = null; img = null; }; + img.onload = onComplete; + img.onerror = function() { item.loadError = true; onComplete(); @@ -201,10 +203,8 @@ var _getItemAt, img = item.container.lastChild; } - item.calculatedSize = {}; - - var w = item.calculatedSize.x = maxRes ? item.w : Math.round(item.w * item.fitRatio), - h = item.calculatedSize.y = maxRes ? item.h : Math.round(item.h * item.fitRatio); + var w = maxRes ? item.w : Math.round(item.w * item.fitRatio), + h = maxRes ? item.h : Math.round(item.h * item.fitRatio); // ensure correct aspect ratio if(img.naturalHeight && img.naturalWidth) { @@ -226,6 +226,10 @@ var _getItemAt, img.style.width = w + 'px'; img.style.height = h + 'px'; + + img.dataset.initialHeight = h; + + return {width: w, height: h}; }, // What is this? @@ -266,6 +270,7 @@ _registerModule('Controller', { _preloadImage(item); }, + initController: function() { framework.extend(_options, _controllerDefaultOptions, true); self.items = _items = items; @@ -374,7 +379,8 @@ _registerModule('Controller', { } var item = self.getItemAt(index), - img; + img, + imageSize; if(!item) { holder.el.innerHTML = ''; @@ -465,7 +471,7 @@ _registerModule('Controller', { placeholder.src = item.msrc; } - _setImageSize(item, placeholder); + imageSize = _setImageSize(item, placeholder); baseDiv.appendChild(placeholder); item.placeholder = placeholder; @@ -495,7 +501,7 @@ _registerModule('Controller', { img = framework.createElement('pswp__img', 'img'); img.style.opacity = 1; img.src = item.src; - _setImageSize(item, img); + imageSize = _setImageSize(item, img); _appendImage(index, item, baseDiv, img, true); } @@ -509,6 +515,10 @@ _registerModule('Controller', { holder.el.innerHTML = ''; holder.el.appendChild(baseDiv); + + holder.el.dataset.topGap = item.vGap.top; + holder.el.dataset.bottomGap = item.vGap.bottom; + holder.el.dataset.imageHeight = imageSize ? imageSize.height : ""; }, cleanSlide: function( item ) { diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 83d6b454b..5729a3cf8 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -59,16 +59,21 @@ // If verticalScrollForCaption it true, position caption from top rather than bottom. if(_options.verticalScrollForCaption) { - item.imageBottomAt = item.vGap.top + item.calculatedSize.y; + var currentItemElement = captionElement.closest(".pswp__scroll-wrap").querySelector(".pswp__container > .pswp__item:nth-child(2)"); + var gapTop = parseInt(currentItemElement.dataset.topGap, 10); + var gapBottom = parseInt(currentItemElement.dataset.bottomGap, 10); + var imgInitialHeight = parseInt(currentItemElement.dataset.imageHeight, 10); + var imageBottomAt = gapTop + imgInitialHeight; + captionElement.style.bottom = 'auto'; - captionElement.style.top = item.imageBottomAt + "px"; + captionElement.style.top = imageBottomAt + "px"; // Show the 'expand' control if caption extends out of view. Reset height first. innerCaptionElement.style.height = 'auto'; var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); - if(innerCaptionElement.clientHeight > item.vGap.bottom) { + if(innerCaptionElement.clientHeight > gapBottom) { captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); - captionCtrl.addEventListener("click", toggleCaption.bind(null, item, captionElement, captionCtrl)); + captionCtrl.addEventListener("click", toggleCaption); } else { captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); @@ -123,16 +128,22 @@ _blockControlsTap, _blockControlsTapTimeout; - var toggleCaption = function(item, captionElement, captionCtrl) { + var toggleCaption = function(e) { + var captionCtrl = e.target || e.srcElement; + var captionElement = captionCtrl.parentNode; var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); + var currentItemElement = captionCtrl.closest(".pswp__scroll-wrap").querySelector(".pswp__container > .pswp__item:nth-child(2)"); + var gapTop = parseInt(currentItemElement.dataset.topGap, 10); + var gapBottom = parseInt(currentItemElement.dataset.bottomGap, 10); + var imgInitialHeight = parseInt(currentItemElement.dataset.imageHeight, 10); if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")){ - var topAfterExpansion = item.vGap.top; - if(captionElement.clientHeight < item.calculatedSize.y + item.vGap.bottom) { - topAfterExpansion = item.vGap.top + item.vGap.bottom + (item.calculatedSize.y - captionElement.clientHeight); + var topAfterExpansion = gapTop; + if(captionElement.clientHeight < imgInitialHeight + gapBottom) { + topAfterExpansion = gapTop + gapBottom + (imgInitialHeight - captionElement.clientHeight); } else { - innerCaptionElement.style.height = item.calculatedSize.y + item.vGap.bottom + "px"; + innerCaptionElement.style.height = imgInitialHeight + gapBottom + "px"; innerCaptionElement.style.overflowY = "auto"; } @@ -142,7 +153,7 @@ } else { innerCaptionElement.style.height = 'auto'; - captionElement.style.top = (item.vGap.top + item.calculatedSize.y) + "px"; + captionElement.style.top = (gapTop + imgInitialHeight) + "px"; captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); } @@ -595,6 +606,7 @@ } } }; + loopThroughChildElements(_controls.children); var topBar = framework.getChildByClass(_controls, 'pswp__top-bar'); From dcf99266f5c579f331809299e95015d1ea67a462 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sat, 25 Apr 2020 13:16:10 +0100 Subject: [PATCH 15/39] Rename function to indicate that it is private. --- src/js/ui/photoswipe-ui-default.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 5729a3cf8..5dc7e66ab 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -73,7 +73,7 @@ var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); if(innerCaptionElement.clientHeight > gapBottom) { captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); - captionCtrl.addEventListener("click", toggleCaption); + captionCtrl.addEventListener("click", _toggleCaption); } else { captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); @@ -128,7 +128,7 @@ _blockControlsTap, _blockControlsTapTimeout; - var toggleCaption = function(e) { + var _toggleCaption = function(e) { var captionCtrl = e.target || e.srcElement; var captionElement = captionCtrl.parentNode; var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); @@ -560,6 +560,13 @@ } } }, + { + name: 'button--caption--ctrl', + option: 'verticalScrollForCaption'/*, + onTap: function(evt) { + _toggleCaption(evt); + }*/ + }, { name: 'preloader', option: 'preloaderEl', From 38d5dfbb95c0767113bb45ce61e7fa61262f644d Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Wed, 29 Apr 2020 22:14:23 +0100 Subject: [PATCH 16/39] Save so far now that positioning is correct. Need to fix hiding and showing. --- src/css/default-skin/default-skin.scss | 41 ++++++++++---------- src/js/items-controller.js | 9 +++-- src/js/ui/photoswipe-ui-default.js | 52 ++++++++++++++++---------- 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index 031411ebd..2ef953774 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -366,42 +366,41 @@ a.pswp__share--download { .pswp__button--caption--ctrl { display: none; - width: 44px; - height: 44px; + width: 36px; + height: 36px; background-image: none; - background-color: #000; - color: #999; - border-radius: 22px; - border: 1px solid #999; + border-radius: 18px; + border: none; overflow: hidden; position: absolute; - top: -22px; + top: -18px; left: 50%; transform: translateX(-50%); text-decoration: none; opacity: 1; + +} + +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand { + background: url('data:image/svg+xml;utf8,'); } -.pswp__button--caption--ctrl:hover { - color: #fff; - border-color: #fff; +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse { + background: url('data:image/svg+xml;utf8,'); } +/* This must come after setting the background above */ .pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand, .pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse { display:block; + width: 36px; + height: 36px; + background-color: #ccc; + background-size: cover; } -.pswp__button--caption--ctrl::before { - position: relative; - top: -8px; - left: 1px; - font-size: 42px; +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand:hover, +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse:hover { + background-color: #fff; } -.pswp__button--caption--ctrl--expand::before { - content: "\02b9d"; -} -.pswp__button--caption--ctrl--collapse::before { - content: "\02b9f"; -} .pswp__caption--empty { display: none; diff --git a/src/js/items-controller.js b/src/js/items-controller.js index 46b2cd2ec..c2ff767f9 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -227,7 +227,7 @@ var _getItemAt, img.style.width = w + 'px'; img.style.height = h + 'px'; - img.dataset.initialHeight = h; + //img.dataset.initialHeight = h; return {width: w, height: h}; }, @@ -516,9 +516,10 @@ _registerModule('Controller', { holder.el.innerHTML = ''; holder.el.appendChild(baseDiv); - holder.el.dataset.topGap = item.vGap.top; - holder.el.dataset.bottomGap = item.vGap.bottom; - holder.el.dataset.imageHeight = imageSize ? imageSize.height : ""; + holder.el.dataset.viewportHeight = _viewportSize.y; + holder.el.dataset.gapTop = item.vGap.top; + holder.el.dataset.imagePositionTop = item.initialPosition.y; + holder.el.dataset.imageHeight = imageSize.height; }, cleanSlide: function( item ) { diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 5dc7e66ab..ab4fed666 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -59,19 +59,15 @@ // If verticalScrollForCaption it true, position caption from top rather than bottom. if(_options.verticalScrollForCaption) { - var currentItemElement = captionElement.closest(".pswp__scroll-wrap").querySelector(".pswp__container > .pswp__item:nth-child(2)"); - var gapTop = parseInt(currentItemElement.dataset.topGap, 10); - var gapBottom = parseInt(currentItemElement.dataset.bottomGap, 10); - var imgInitialHeight = parseInt(currentItemElement.dataset.imageHeight, 10); - var imageBottomAt = gapTop + imgInitialHeight; + var layoutData = _getLayoutData(captionElement); captionElement.style.bottom = 'auto'; - captionElement.style.top = imageBottomAt + "px"; + captionElement.style.top = layoutData.captionInitialPositionTop + "px"; - // Show the 'expand' control if caption extends out of view. Reset height first. + // Show the 'expand' control only if caption extends out of view. Reset height first. innerCaptionElement.style.height = 'auto'; var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); - if(innerCaptionElement.clientHeight > gapBottom) { + if(innerCaptionElement.clientHeight > layoutData.captionInitialHeight) { captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.addEventListener("click", _toggleCaption); } @@ -128,32 +124,48 @@ _blockControlsTap, _blockControlsTapTimeout; + var _getLayoutData = function(captionElement) { + var layoutData = {}; + //var toggleCtrlHeight = 36; + + var currentItemElement = captionElement.closest(".pswp__scroll-wrap").querySelector(".pswp__container > .pswp__item:nth-child(2)") + + layoutData.viewportHeight = parseInt(currentItemElement.dataset.viewportHeight, 10); + layoutData.gapTop = parseInt(currentItemElement.dataset.gapTop, 10); + layoutData.imagePositionTop = parseInt(currentItemElement.dataset.imagePositionTop, 10); + layoutData.imageHeight = parseInt(currentItemElement.dataset.imageHeight, 10); + + layoutData.captionInitialPositionTop = layoutData.imagePositionTop + layoutData.imageHeight; // + toggleCtrlHeight/2 + 2; + layoutData.captionInitialHeight = layoutData.viewportHeight - layoutData.captionInitialPositionTop; + layoutData.captionMaxHeight = layoutData.viewportHeight - layoutData.gapTop; + + return layoutData; + }; + var _toggleCaption = function(e) { var captionCtrl = e.target || e.srcElement; var captionElement = captionCtrl.parentNode; var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); - var currentItemElement = captionCtrl.closest(".pswp__scroll-wrap").querySelector(".pswp__container > .pswp__item:nth-child(2)"); - var gapTop = parseInt(currentItemElement.dataset.topGap, 10); - var gapBottom = parseInt(currentItemElement.dataset.bottomGap, 10); - var imgInitialHeight = parseInt(currentItemElement.dataset.imageHeight, 10); + var layoutData = _getLayoutData(captionElement); - if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")){ - var topAfterExpansion = gapTop; - if(captionElement.clientHeight < imgInitialHeight + gapBottom) { - topAfterExpansion = gapTop + gapBottom + (imgInitialHeight - captionElement.clientHeight); + if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")) { // Expand caption + if(captionElement.clientHeight < layoutData.captionMaxHeight) { // It fits in space below top bar + captionElement.style.top = (layoutData.captionMaxHeight - captionElement.clientHeight) + "px"; + innerCaptionElement.style.height = 'auto'; } else { - innerCaptionElement.style.height = imgInitialHeight + gapBottom + "px"; + captionElement.style.top = layoutData.gapTop + "px"; + innerCaptionElement.style.height = layoutData.captionMaxHeight + "px"; innerCaptionElement.style.overflowY = "auto"; } - captionElement.style.top = topAfterExpansion + "px"; captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); captionCtrl.classList.add("pswp__button--caption--ctrl--collapse"); } - else { + else { // Collapse caption innerCaptionElement.style.height = 'auto'; - captionElement.style.top = (gapTop + imgInitialHeight) + "px"; + captionElement.style.top = layoutData.captionInitialPositionTop + "px"; + captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); } From 398619a16ab948ae47bc180d1164fa6a6f4daee5 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Fri, 1 May 2020 21:58:33 +0100 Subject: [PATCH 17/39] Somewhat closer. Accounting for scale but only on first load. :-( Caption toggles now. Adding more whitespace for clarity. --- src/js/core.js | 21 ++++++++++++++++++--- src/js/items-controller.js | 22 ++++++++++++++++------ src/js/ui/photoswipe-ui-default.js | 18 ++++++++---------- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 181cc6569..9ba1e1d49 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -112,7 +112,7 @@ var _isOpen, var numSlides = _getNumItems(); if(index > numSlides - 1) { return index - numSlides; - } else if(index < 0) { + } else if(index < 0) { return numSlides + index; } return index; @@ -126,6 +126,7 @@ var _isOpen, } return _listeners[name].push(fn); }, + _shout = function(name) { var listeners = _listeners[name]; @@ -142,18 +143,20 @@ var _isOpen, _getCurrentTime = function() { return new Date().getTime(); }, + _applyBgOpacity = function(opacity) { _bgOpacity = opacity; self.bg.style.opacity = opacity * _options.bgOpacity; }, - _applyZoomTransform = function(styleObj,x,y,zoom,item) { + _applyZoomTransform = function(styleObj, x, y, zoom, item) { if(!_renderMaxResolution || (item && item !== self.currItem) ) { zoom = zoom / (item ? item.fitRatio : self.currItem.fitRatio); } styleObj[_transformKey] = _translatePrefix + x + 'px, ' + y + 'px' + _translateSufix + ' scale(' + zoom + ')'; }, + _applyCurrentZoomPan = function( allowRenderResolution ) { if(_currZoomElementStyle && !self.currItem.loadError) { @@ -171,10 +174,10 @@ var _isOpen, } } - _applyZoomTransform(_currZoomElementStyle, _panOffset.x, _panOffset.y, _currZoomLevel); } }, + _applyZoomPanToItem = function(item) { if(item.container) { @@ -185,9 +188,11 @@ var _isOpen, item); } }, + _setTranslateX = function(x, elStyle) { elStyle[_transformKey] = _translatePrefix + x + 'px, 0px' + _translateSufix; }, + _moveMainScroll = function(x, dragging) { if(!_options.loop && dragging) { @@ -203,6 +208,13 @@ var _isOpen, _mainScrollPos.x = x; _setTranslateX(x, _containerStyle); }, + + _resetCaptionCtrl = function() { + var captionCtrl = self.scrollWrap.querySelector(".pswp__button--caption--ctrl"); + captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); + captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); + }, + _calculatePanOffset = function(axis, zoomLevel) { var m = _midZoomPoint[axis] - _offset[axis]; return _startPanOffset[axis] + _currPanDist[axis] + m - m * ( zoomLevel / _startZoomLevel ); @@ -215,6 +227,7 @@ var _isOpen, p1.id = p2.id; } }, + _roundPoint = function(p) { p.x = Math.round(p.x); p.y = Math.round(p.y); @@ -286,6 +299,7 @@ var _isOpen, } return item.initialZoomLevel; }, + _getMaxZoomLevel = function(item) { if(!item) { item = self.currItem; @@ -769,6 +783,7 @@ var publicMethods = { _moveMainScroll(_slideSize.x * _currPositionIndex); + _resetCaptionCtrl(); _stopAllAnimations(); _mainScrollAnimating = false; diff --git a/src/js/items-controller.js b/src/js/items-controller.js index c2ff767f9..3dccdb15d 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -23,6 +23,7 @@ var _items, var _getItemAt, _getNumItems, _initialIsLoop, + _getZeroBounds = function() { return { center:{x:0,y:0}, @@ -30,6 +31,7 @@ var _getItemAt, min:{x:0,y:0} }; }, + _calculateSingleItemPanBounds = function(item, realPanElementW, realPanElementH ) { var bounds = item.bounds; @@ -50,6 +52,7 @@ var _getItemAt, bounds.min.x = (realPanElementW > _tempPanAreaSize.x) ? 0 : bounds.center.x; bounds.min.y = (realPanElementH > _tempPanAreaSize.y) ? item.vGap.top : bounds.center.y; }, + _calculateItemSize = function(item, viewportSize, zoomLevel) { if (item.src && !item.loadError) { @@ -116,9 +119,6 @@ var _getItemAt, }, - - - _appendImage = function(index, item, baseDiv, img, preventAnimation, keepPlaceholder) { @@ -182,6 +182,7 @@ var _getItemAt, return img; }, + _checkForError = function(item, cleanUp) { if(item.src && item.loadError && item.container) { @@ -194,6 +195,7 @@ var _getItemAt, } }, + _setImageSize = function(item, img, maxRes) { if(!item.src) { return; @@ -425,10 +427,12 @@ _registerModule('Controller', { item.loadComplete = item.img = null; _calculateItemSize(item, _viewportSize); _applyZoomPanToItem(item); + console.log("index: " + index + ", item.container.style.transform: " + item.container.style.transform); if(holder.index === _currentItemIndex) { // recalculate dimensions self.updateCurrZoomItem(); + console.log("index: " + index + ", item.container.style.transform: " + item.container.style.transform); } return; } @@ -505,10 +509,17 @@ _registerModule('Controller', { _appendImage(index, item, baseDiv, img, true); } - + var scale = 1; if(!_initialContentSet && index === _currentItemIndex) { _currZoomElementStyle = baseDiv.style; _showOrHide(item, (img ||item.img) ); + + var cssTransform = baseDiv.style.transform; // e.g. "translate3d(65px, 87px, 0px) scale(0.875912)"; + if(/^translate.*scale.*$/.test(cssTransform)) { + var translateY = cssTransform.replace(/^translate(3d)?\([0-9]*px, /, "").replace(/px.*$/, ""); + scale = cssTransform.replace(/^.*scale\(/, "").replace(/\)/, ""); + console.log("scale: " + scale + ", image height: " + imageSize.height); + } } else { _applyZoomPanToItem(item); } @@ -519,7 +530,7 @@ _registerModule('Controller', { holder.el.dataset.viewportHeight = _viewportSize.y; holder.el.dataset.gapTop = item.vGap.top; holder.el.dataset.imagePositionTop = item.initialPosition.y; - holder.el.dataset.imageHeight = imageSize.height; + holder.el.dataset.imageHeight = Math.round(imageSize.height * parseFloat(scale)); }, cleanSlide: function( item ) { @@ -528,6 +539,5 @@ _registerModule('Controller', { } item.loaded = item.loading = item.img = item.imageAppended = false; } - } }); diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index ab4fed666..c940beeed 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -69,7 +69,7 @@ var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); if(innerCaptionElement.clientHeight > layoutData.captionInitialHeight) { captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); - captionCtrl.addEventListener("click", _toggleCaption); + //captionCtrl.addEventListener("click", _toggleCaption); } else { captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); @@ -142,8 +142,8 @@ return layoutData; }; - var _toggleCaption = function(e) { - var captionCtrl = e.target || e.srcElement; + var _toggleCaption = function(el) { + var captionCtrl = el; //e.target || e.srcElement; var captionElement = captionCtrl.parentNode; var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); var layoutData = _getLayoutData(captionElement); @@ -176,7 +176,6 @@ return true; } - e = e || window.event; if(_options.timeToIdle && _options.mouseUsed && !_isIdle) { @@ -193,9 +192,8 @@ for(var i = 0; i < _uiElements.length; i++) { uiElement = _uiElements[i]; if(uiElement.onTap && clickedClass.indexOf('pswp__' + uiElement.name ) > -1 ) { - uiElement.onTap(); + uiElement.onTap(target); found = true; - } } @@ -574,10 +572,10 @@ }, { name: 'button--caption--ctrl', - option: 'verticalScrollForCaption'/*, - onTap: function(evt) { - _toggleCaption(evt); - }*/ + option: 'verticalScrollForCaption', + onTap: function(el) { + _toggleCaption(el); + } }, { name: 'preloader', From dcf57fd64c4c9e4d532423f79971da3252ab8a5e Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sun, 3 May 2020 12:32:55 +0100 Subject: [PATCH 18/39] Seems to work. --- src/js/core.js | 9 ++++++--- src/js/items-controller.js | 29 ++++++++++++--------------- src/js/ui/photoswipe-ui-default.js | 32 +++++++++++++++++++----------- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 9ba1e1d49..844b4c27c 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -345,6 +345,7 @@ var _isOpen, _setTranslateX = function(x, elStyle) { elStyle.left = x + 'px'; }; + _applyZoomPanToItem = function(item) { var zoomRatio = item.fitRatio > 1 ? 1 : item.fitRatio, @@ -357,7 +358,12 @@ var _isOpen, s.left = item.initialPosition.x + 'px'; s.top = item.initialPosition.y + 'px'; + console.log("This is _applyZoomPanToItem at line 355"); + item.zoom = zoomRatio; + item.apparentImageHeight = h; + item.imageFromTop = item.initialPosition; }; + _applyCurrentZoomPan = function() { if(_currZoomElementStyle) { @@ -370,7 +376,6 @@ var _isOpen, s.width = w + 'px'; s.height = h + 'px'; - s.left = _panOffset.x + 'px'; s.top = _panOffset.y + 'px'; } @@ -953,8 +958,6 @@ var publicMethods = { template.style.height = _windowVisibleSize.y + 'px'; } - - _viewportSize.x = self.scrollWrap.clientWidth; _viewportSize.y = self.scrollWrap.clientHeight; diff --git a/src/js/items-controller.js b/src/js/items-controller.js index 3dccdb15d..607c1dc83 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -74,7 +74,6 @@ var _getItemAt, var vRatio = _tempPanAreaSize.y / item.h; item.fitRatio = hRatio < vRatio ? hRatio : vRatio; - //item.fillRatio = hRatio > vRatio ? hRatio : vRatio; var scaleMode = _options.scaleMode; @@ -228,10 +227,6 @@ var _getItemAt, img.style.width = w + 'px'; img.style.height = h + 'px'; - - //img.dataset.initialHeight = h; - - return {width: w, height: h}; }, // What is this? @@ -509,28 +504,30 @@ _registerModule('Controller', { _appendImage(index, item, baseDiv, img, true); } - var scale = 1; + // var scale = 1; + // var transform = {}; if(!_initialContentSet && index === _currentItemIndex) { _currZoomElementStyle = baseDiv.style; _showOrHide(item, (img ||item.img) ); - var cssTransform = baseDiv.style.transform; // e.g. "translate3d(65px, 87px, 0px) scale(0.875912)"; - if(/^translate.*scale.*$/.test(cssTransform)) { - var translateY = cssTransform.replace(/^translate(3d)?\([0-9]*px, /, "").replace(/px.*$/, ""); - scale = cssTransform.replace(/^.*scale\(/, "").replace(/\)/, ""); - console.log("scale: " + scale + ", image height: " + imageSize.height); - } + // var cssTransform = baseDiv.style.transform; // e.g. "translate3d(65px, 87px, 0px) scale(0.875912)"; + // if(/^translate.*scale.*$/.test(cssTransform)) { + // var translateY = cssTransform.replace(/^translate(3d)?\([0-9]*px, /, "").replace(/px.*$/, ""); + // scale = cssTransform.replace(/^.*scale\(/, "").replace(/\)/, ""); + // console.log("scale: " + scale + ", image height: " + imageSize.height); + // } } else { + // console.log("Doing applyZoomPanToItem instead"); _applyZoomPanToItem(item); } holder.el.innerHTML = ''; holder.el.appendChild(baseDiv); - holder.el.dataset.viewportHeight = _viewportSize.y; - holder.el.dataset.gapTop = item.vGap.top; - holder.el.dataset.imagePositionTop = item.initialPosition.y; - holder.el.dataset.imageHeight = Math.round(imageSize.height * parseFloat(scale)); + // holder.el.dataset.viewportHeight = _viewportSize.y; + // holder.el.dataset.gapTop = item.vGap.top; + // holder.el.dataset.imagePositionTop = item.initialPosition.y; + // holder.el.dataset.imageHeight = Math.round(imageSize.height * parseFloat(scale)); }, cleanSlide: function( item ) { diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index c940beeed..c7fd15501 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -57,8 +57,14 @@ } innerCaptionElement.innerHTML = item.title; - // If verticalScrollForCaption it true, position caption from top rather than bottom. + // If verticalScrollForCaption is true, position caption from top rather than bottom. if(_options.verticalScrollForCaption) { + var imagePositionTop = item.initialPosition.y; + var apparentImageHeight = Math.round(item.h * item.initialZoomLevel); + var gapTop = item.vGap.top; + //var gapBottom = item.vGap.bottom; + + _setLayoutData(captionElement, imagePositionTop, apparentImageHeight, gapTop); var layoutData = _getLayoutData(captionElement); captionElement.style.bottom = 'auto'; @@ -124,20 +130,22 @@ _blockControlsTap, _blockControlsTapTimeout; + var _setLayoutData = function(captionElement, imagePositionTop, apparentImageHeight, gapTop, gapBottom){ + captionElement.dataset.imagePositionTop = imagePositionTop; + captionElement.dataset.apparentImageHeight = apparentImageHeight; + captionElement.dataset.gapTop = gapTop; + }; + var _getLayoutData = function(captionElement) { var layoutData = {}; - //var toggleCtrlHeight = 36; - - var currentItemElement = captionElement.closest(".pswp__scroll-wrap").querySelector(".pswp__container > .pswp__item:nth-child(2)") - layoutData.viewportHeight = parseInt(currentItemElement.dataset.viewportHeight, 10); - layoutData.gapTop = parseInt(currentItemElement.dataset.gapTop, 10); - layoutData.imagePositionTop = parseInt(currentItemElement.dataset.imagePositionTop, 10); - layoutData.imageHeight = parseInt(currentItemElement.dataset.imageHeight, 10); + layoutData.gapTop = parseInt(captionElement.dataset.gapTop, 10); + layoutData.imagePositionTop = parseInt(captionElement.dataset.imagePositionTop, 10); + layoutData.apparentImageHeight = parseInt(captionElement.dataset.apparentImageHeight, 10); - layoutData.captionInitialPositionTop = layoutData.imagePositionTop + layoutData.imageHeight; // + toggleCtrlHeight/2 + 2; - layoutData.captionInitialHeight = layoutData.viewportHeight - layoutData.captionInitialPositionTop; - layoutData.captionMaxHeight = layoutData.viewportHeight - layoutData.gapTop; + layoutData.captionInitialPositionTop = layoutData.imagePositionTop + layoutData.apparentImageHeight; + layoutData.captionInitialHeight = window.innerHeight - layoutData.captionInitialPositionTop; + layoutData.captionMaxHeight = window.innerHeight - layoutData.gapTop; return layoutData; }; @@ -150,7 +158,7 @@ if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")) { // Expand caption if(captionElement.clientHeight < layoutData.captionMaxHeight) { // It fits in space below top bar - captionElement.style.top = (layoutData.captionMaxHeight - captionElement.clientHeight) + "px"; + captionElement.style.top = (window.innerHeight - captionElement.clientHeight) + "px"; innerCaptionElement.style.height = 'auto'; } else { From ef3c99d92e4309d3259faca9e06aca80de43b0db Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Tue, 5 May 2020 13:10:36 +0100 Subject: [PATCH 19/39] Stop accidental scroll on close. Add a box at the end of the caption to indicate the end. Make caption text white so people like me can actually read it. --- src/css/default-skin/default-skin.scss | 15 +++++++++++++-- src/js/core.js | 2 +- src/js/desktop-zoom.js | 5 ++++- src/js/ui/photoswipe-ui-default.js | 6 ++++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index 2ef953774..65a546c25 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -353,15 +353,26 @@ a.pswp__share--download { font-size: 13px; padding: 20px 10px 10px 10px; line-height: 20px; - color: #CCC; + color: #FFF; background-color: #000; a { - color: #CCC; + color: #CCF; } a:hover { color: #FFF; } + + p:last-child::after { + display: inline-block; + height: 10px; + width: 10px; + background-color: white; + margin-left: 6px; + margin-bottom: -1px; + content: ' '; + + } } .pswp__button--caption--ctrl { diff --git a/src/js/core.js b/src/js/core.js index 844b4c27c..88b7df1b5 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -735,8 +735,8 @@ var publicMethods = { framework.unbind(window, 'scroll', self); _stopDragUpdateLoop(); - _stopAllAnimations(); + _resetCaptionCtrl(); _listeners = {}; }, diff --git a/src/js/desktop-zoom.js b/src/js/desktop-zoom.js index 8e64757b0..01a157302 100644 --- a/src/js/desktop-zoom.js +++ b/src/js/desktop-zoom.js @@ -94,7 +94,10 @@ _registerModule('DesktopZoom', { if( _options.modal ) { if (!_options.closeOnScroll || _numAnimations || _isDragging) { - e.preventDefault(); + var source = e.target || e.srcElement; + if(!source.classList.contains("pswp__caption__center")) { + e.preventDefault(); + } } else if(_transformKey && Math.abs(e.deltaY) > 2) { // close PhotoSwipe // if browser supports transforms & scroll changed enough diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index c7fd15501..cc73abeb3 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -62,7 +62,6 @@ var imagePositionTop = item.initialPosition.y; var apparentImageHeight = Math.round(item.h * item.initialZoomLevel); var gapTop = item.vGap.top; - //var gapBottom = item.vGap.bottom; _setLayoutData(captionElement, imagePositionTop, apparentImageHeight, gapTop); var layoutData = _getLayoutData(captionElement); @@ -130,7 +129,7 @@ _blockControlsTap, _blockControlsTapTimeout; - var _setLayoutData = function(captionElement, imagePositionTop, apparentImageHeight, gapTop, gapBottom){ + var _setLayoutData = function(captionElement, imagePositionTop, apparentImageHeight, gapTop){ captionElement.dataset.imagePositionTop = imagePositionTop; captionElement.dataset.apparentImageHeight = apparentImageHeight; captionElement.dataset.gapTop = gapTop; @@ -143,6 +142,7 @@ layoutData.imagePositionTop = parseInt(captionElement.dataset.imagePositionTop, 10); layoutData.apparentImageHeight = parseInt(captionElement.dataset.apparentImageHeight, 10); + console.log("height: " + window.innerHeight); layoutData.captionInitialPositionTop = layoutData.imagePositionTop + layoutData.apparentImageHeight; layoutData.captionInitialHeight = window.innerHeight - layoutData.captionInitialPositionTop; layoutData.captionMaxHeight = window.innerHeight - layoutData.gapTop; @@ -158,10 +158,12 @@ if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")) { // Expand caption if(captionElement.clientHeight < layoutData.captionMaxHeight) { // It fits in space below top bar + console.log("caption height: "+ captionElement.clientHeight + ", space available: " + layoutData.captionMaxHeight); captionElement.style.top = (window.innerHeight - captionElement.clientHeight) + "px"; innerCaptionElement.style.height = 'auto'; } else { + console.log("Caption won't fit. Gap at top: " + layoutData.gapTop); captionElement.style.top = layoutData.gapTop + "px"; innerCaptionElement.style.height = layoutData.captionMaxHeight + "px"; innerCaptionElement.style.overflowY = "auto"; From 704889138248c1d5a38953046b905da08b13833e Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 7 May 2020 13:06:03 +0100 Subject: [PATCH 20/39] Various fixes --- src/css/default-skin/default-skin.scss | 9 ++++--- src/js/desktop-zoom.js | 6 ++++- src/js/framework-bridge.js | 23 +++++++++++++++- src/js/items-controller.js | 13 --------- src/js/ui/photoswipe-ui-default.js | 37 +++++++++++++++++--------- 5 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index 65a546c25..b023de24e 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -142,7 +142,7 @@ width: 70px; height: 100px; position: absolute; - z-index: 3; + z-index: 1; } .pswp__button--arrow--left { @@ -351,7 +351,7 @@ a.pswp__share--download { max-width: 420px; margin: 0 auto; font-size: 13px; - padding: 20px 10px 10px 10px; + padding: 18px 10px 10px 10px; line-height: 20px; color: #FFF; background-color: #000; @@ -363,6 +363,10 @@ a.pswp__share--download { color: #FFF; } + p { + margin: 0 0 0 10px; + } + p:last-child::after { display: inline-block; height: 10px; @@ -371,7 +375,6 @@ a.pswp__share--download { margin-left: 6px; margin-bottom: -1px; content: ' '; - } } diff --git a/src/js/desktop-zoom.js b/src/js/desktop-zoom.js index 01a157302..6acc5d566 100644 --- a/src/js/desktop-zoom.js +++ b/src/js/desktop-zoom.js @@ -95,7 +95,11 @@ _registerModule('DesktopZoom', { if (!_options.closeOnScroll || _numAnimations || _isDragging) { var source = e.target || e.srcElement; - if(!source.classList.contains("pswp__caption__center")) { + if(source.classList.contains("pswp__caption__center")) { + if(source.class.contains("pswp__button--caption--ctrl--expand")) { + toggleCaption(source.parentNode); + } + } else { e.preventDefault(); } } else if(_transformKey && Math.abs(e.deltaY) > 2) { diff --git a/src/js/framework-bridge.js b/src/js/framework-bridge.js index 6dd2bfd83..c9da03b87 100644 --- a/src/js/framework-bridge.js +++ b/src/js/framework-bridge.js @@ -274,4 +274,25 @@ if(framework.features.oldIE) { } }; -} \ No newline at end of file +} + +// Polyfill for closest() for IE11 from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest. +// Not bothering with versions older than 11 and it is debatable whether we should worry even about 11 now. +if (!Element.prototype.matches) { + Element.prototype.matches = Element.prototype.msMatchesSelector || + Element.prototype.webkitMatchesSelector; + } + + if (!Element.prototype.closest) { + Element.prototype.closest = function(s) { + var el = this; + + do { + if (Element.prototype.matches.call(el, s)) { + return el; + } + el = el.parentElement || el.parentNode; + } while (el !== null && el.nodeType === 1); + return null; + }; + } \ No newline at end of file diff --git a/src/js/items-controller.js b/src/js/items-controller.js index 607c1dc83..ba8119166 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -509,25 +509,12 @@ _registerModule('Controller', { if(!_initialContentSet && index === _currentItemIndex) { _currZoomElementStyle = baseDiv.style; _showOrHide(item, (img ||item.img) ); - - // var cssTransform = baseDiv.style.transform; // e.g. "translate3d(65px, 87px, 0px) scale(0.875912)"; - // if(/^translate.*scale.*$/.test(cssTransform)) { - // var translateY = cssTransform.replace(/^translate(3d)?\([0-9]*px, /, "").replace(/px.*$/, ""); - // scale = cssTransform.replace(/^.*scale\(/, "").replace(/\)/, ""); - // console.log("scale: " + scale + ", image height: " + imageSize.height); - // } } else { - // console.log("Doing applyZoomPanToItem instead"); _applyZoomPanToItem(item); } holder.el.innerHTML = ''; holder.el.appendChild(baseDiv); - - // holder.el.dataset.viewportHeight = _viewportSize.y; - // holder.el.dataset.gapTop = item.vGap.top; - // holder.el.dataset.imagePositionTop = item.initialPosition.y; - // holder.el.dataset.imageHeight = Math.round(imageSize.height * parseFloat(scale)); }, cleanSlide: function( item ) { diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index cc73abeb3..4670402c1 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -72,9 +72,8 @@ // Show the 'expand' control only if caption extends out of view. Reset height first. innerCaptionElement.style.height = 'auto'; var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); - if(innerCaptionElement.clientHeight > layoutData.captionInitialHeight) { + if(innerCaptionElement.clientHeight - 10 > layoutData.captionInitialHeight) { captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); - //captionCtrl.addEventListener("click", _toggleCaption); } else { captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); @@ -124,7 +123,6 @@ indexIndicatorSep: ' / ', fitControlsWidth: 1200 - }, _blockControlsTap, _blockControlsTapTimeout; @@ -158,12 +156,10 @@ if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")) { // Expand caption if(captionElement.clientHeight < layoutData.captionMaxHeight) { // It fits in space below top bar - console.log("caption height: "+ captionElement.clientHeight + ", space available: " + layoutData.captionMaxHeight); captionElement.style.top = (window.innerHeight - captionElement.clientHeight) + "px"; innerCaptionElement.style.height = 'auto'; } else { - console.log("Caption won't fit. Gap at top: " + layoutData.gapTop); captionElement.style.top = layoutData.gapTop + "px"; innerCaptionElement.style.height = layoutData.captionMaxHeight + "px"; innerCaptionElement.style.overflowY = "auto"; @@ -228,7 +224,7 @@ }, _fitControlsInViewport = function() { - return !pswp.likelyTouchDevice || _options.mouseUsed || screen.width > _options.fitControlsWidth; + return !pswp.likelyTouchDevice || _options.mouseUsed || screen.width > _options.fitControlsWidth || _options.verticalScrollForCaption; }, _togglePswpClass = function(el, cName, add) { @@ -254,7 +250,6 @@ _shareModalHidden = !_shareModalHidden; - if(!_shareModalHidden) { _toggleShareModalClass(); setTimeout(function() { @@ -479,6 +474,19 @@ } }, + _overrideOptionsIfVerticalScrollForCaptionsTrue = function() { + // Don't close gallery when tapping on caption + if(_options.verticalScrollForCaption) { + var index = _options.closeElClasses.indexOf('caption'); + if (index > -1) { + _options.closeElClasses.splice(index, 1); + } + } + + // Don't hide/show controls on tap + _options.tapToToggleControls = false; + }, + _setupHidingControlsDuringGestures = function() { // Hide controls on vertical drag @@ -659,7 +667,7 @@ // create local link _listen = pswp.listen; - + _overrideOptionsIfVerticalScrollForCaptionsTrue(); _setupHidingControlsDuringGestures(); // update controls when slides change @@ -852,8 +860,8 @@ } } else { - // tap anywhere (except buttons) to toggle visibility of controls - if(_options.tapToToggleControls) { + // tap anywhere (except buttons and caption) to toggle visibility of controls + if(_options.tapToToggleControls && !target.classList.contains("pswp__caption__center")) { if(_controlsVisible) { ui.hideControls(); } else { @@ -870,6 +878,7 @@ } }; + ui.onMouseOver = function(e) { e = e || window.event; var target = e.target || e.srcElement; @@ -917,8 +926,6 @@ eventK: 'moz' + tF }; - - } else if(dE.webkitRequestFullscreen) { api = { enterK: 'webkitRequestFullscreen', @@ -948,13 +955,17 @@ return pswp.template[this.enterK](); } }; + api.exit = function() { _options.closeOnScroll = _initalCloseOnScrollValue; return document[this.exitK](); }; - api.isFullscreen = function() { return document[this.elementK]; }; + + api.isFullscreen = function() { + return document[this.elementK]; + }; } return api; From 5da7317ba74597f220a260f003b851e935486cdf Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 7 May 2020 22:39:20 +0100 Subject: [PATCH 21/39] Sorted out weirdness with tap behavior. Now preventing closing when tapping on the caption because it is too easy to close accidentally when you thought you were swiping. --- src/js/ui/photoswipe-ui-default.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 4670402c1..f8693e24a 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -140,7 +140,6 @@ layoutData.imagePositionTop = parseInt(captionElement.dataset.imagePositionTop, 10); layoutData.apparentImageHeight = parseInt(captionElement.dataset.apparentImageHeight, 10); - console.log("height: " + window.innerHeight); layoutData.captionInitialPositionTop = layoutData.imagePositionTop + layoutData.apparentImageHeight; layoutData.captionInitialHeight = window.innerHeight - layoutData.captionInitialPositionTop; layoutData.captionMaxHeight = window.innerHeight - layoutData.gapTop; @@ -203,6 +202,11 @@ } } + // Long captions will contain HTML so caption element will be an ancestor of target + if(target.closest(".pswp__caption__center")) { + found = true; + } + if(found) { if(e.stopPropagation) { e.stopPropagation(); @@ -482,9 +486,6 @@ _options.closeElClasses.splice(index, 1); } } - - // Don't hide/show controls on tap - _options.tapToToggleControls = false; }, _setupHidingControlsDuringGestures = function() { @@ -861,7 +862,7 @@ } else { // tap anywhere (except buttons and caption) to toggle visibility of controls - if(_options.tapToToggleControls && !target.classList.contains("pswp__caption__center")) { + if(_options.tapToToggleControls) { if(_controlsVisible) { ui.hideControls(); } else { From 61e5806242d840400072d1cafc40e295a33f55dc Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Fri, 8 May 2020 12:10:47 +0100 Subject: [PATCH 22/39] Renaming option name and removing redundant code. --- src/js/ui/photoswipe-ui-default.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index f8693e24a..5474656d9 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -57,8 +57,8 @@ } innerCaptionElement.innerHTML = item.title; - // If verticalScrollForCaption is true, position caption from top rather than bottom. - if(_options.verticalScrollForCaption) { + // If allowLongCaptions is true, position caption from top rather than bottom. + if(_options.allowLongCaptions) { var imagePositionTop = item.initialPosition.y; var apparentImageHeight = Math.round(item.h * item.initialZoomLevel); var gapTop = item.vGap.top; @@ -91,7 +91,7 @@ showCounter: true, showNextPreviousArrows: true, showCaption: true, - verticalScrollForCaption: true, + allowLongCaptions: true, preloaderEl: true, @@ -228,7 +228,8 @@ }, _fitControlsInViewport = function() { - return !pswp.likelyTouchDevice || _options.mouseUsed || screen.width > _options.fitControlsWidth || _options.verticalScrollForCaption; + return !pswp.likelyTouchDevice || _options.mouseUsed || screen.width > _options.fitControlsWidth || + _options.allowLongCaptions; }, _togglePswpClass = function(el, cName, add) { @@ -478,13 +479,14 @@ } }, - _overrideOptionsIfVerticalScrollForCaptionsTrue = function() { - // Don't close gallery when tapping on caption - if(_options.verticalScrollForCaption) { - var index = _options.closeElClasses.indexOf('caption'); - if (index > -1) { - _options.closeElClasses.splice(index, 1); - } + _overrideOptionsIfAllowLongCaptionsTrue = function() { + if(_options.closeOnScroll) { + console.info("Resetting _options.closeOnScroll to false because _options.allowLongCaptions is true."); + _options.closeOnScroll = false; + } + if(_options.closeOnVerticalDrag) { + console.info("Resetting _options.closeOnVerticalDrag to false because _options.allowLongCaptions is true."); + _options.closeOnVerticalDrag = false; } }, @@ -591,7 +593,7 @@ }, { name: 'button--caption--ctrl', - option: 'verticalScrollForCaption', + option: 'allowLongCaptions', onTap: function(el) { _toggleCaption(el); } @@ -668,7 +670,7 @@ // create local link _listen = pswp.listen; - _overrideOptionsIfVerticalScrollForCaptionsTrue(); + _overrideOptionsIfAllowLongCaptionsTrue(); _setupHidingControlsDuringGestures(); // update controls when slides change From 3fcd8400df41164903f1f31d67dad0327d6a774d Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Fri, 8 May 2020 19:36:00 +0100 Subject: [PATCH 23/39] Drag up on collapsed caption will expand it. --- src/js/core.js | 4 ++-- src/js/gestures.js | 28 ++++++++++++++++------------ src/js/ui/photoswipe-ui-default.js | 4 ++++ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 88b7df1b5..8820d306e 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -18,8 +18,8 @@ var _options = { mouseUsed: false, loop: true, pinchToClose: true, - closeOnScroll: true, - closeOnVerticalDrag: true, + closeOnScroll: true, // Will be overridden if allowLongCaptions is true + closeOnVerticalDrag: true, // Will be overridden if allowLongCaptions is true verticalDragRange: 0.75, hideAnimationDuration: 333, showAnimationDuration: 333, diff --git a/src/js/gestures.js b/src/js/gestures.js index a5e235547..505e1d6c7 100644 --- a/src/js/gestures.js +++ b/src/js/gestures.js @@ -49,6 +49,7 @@ var _gestureStartTime, _opacityChanged, _bgOpacity, _wasOverInitialZoom, + _target, _isEqualPoints = function(p1, p2) { return p1.x === p2.x && p1.y === p2.y; @@ -246,11 +247,7 @@ var _gestureStartTime, newPanPos = newOffset; } } - } - - - // } if(axis === 'x') { @@ -316,10 +313,10 @@ var _gestureStartTime, e.preventDefault(); } - - _shout('pointerDown'); + _target = e.target || e.srcElement; + if(_pointerEventEnabled) { var pointerIndex = framework.arraySearch(_currPointers, e.pointerId, 'id'); if(pointerIndex < 0) { @@ -327,8 +324,6 @@ var _gestureStartTime, } _currPointers[pointerIndex] = {x:e.pageX, y:e.pageY, id: e.pointerId}; } - - var startPointsList = _getTouchPoints(e), numPoints = startPointsList.length; @@ -340,8 +335,6 @@ var _gestureStartTime, // init drag if(!_isDragging || numPoints === 1) { - - _isDragging = _isFirstMove = true; framework.bind(window, _upMoveEvents, self); @@ -380,7 +373,6 @@ var _gestureStartTime, // Start rendering _stopDragUpdateLoop(); _dragUpdateLoop(); - } // init zoom @@ -441,7 +433,7 @@ var _gestureStartTime, } } }, - // + _renderMovement = function() { if(!_currentPoints) { @@ -550,6 +542,8 @@ var _gestureStartTime, return; } + // if dragging up on collapsed caption then open it. + if(_isFirstMove) { _isFirstMove = false; @@ -572,6 +566,16 @@ var _gestureStartTime, return; } + // if dragging up on a collapsed long caption, expand the caption + var targetCaption = _target.closest(".pswp__caption"); + if(_direction === 'v' && delta.y > -DIRECTION_CHECK_OFFSET && targetCaption) { + var toggleCaptionBtn = targetCaption.querySelector(".pswp__button--caption--ctrl"); + if(toggleCaptionBtn && toggleCaptionBtn.classList.contains("pswp__button--caption--ctrl--expand")) { + self.ui.toggleCaption(toggleCaptionBtn); + return; + } + } + if(_direction === 'v' && _options.closeOnVerticalDrag) { if(!_canPan()) { _currPanDist.y += delta.y; diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 5474656d9..b24dc0535 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -973,6 +973,10 @@ return api; }; + + ui.toggleCaption = function(el) { + _toggleCaption(el); + }; }; return PhotoSwipeUI_Default; From 44fabb2147153f51490e961cfdd523636a5e52ec Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sat, 9 May 2020 13:31:50 +0100 Subject: [PATCH 24/39] Expand and collapse caption with just the mouse wheel. Had to override _likelyTouchDevice since navigator.maxTouchPoints is reporting 2 on my laptop so need to figure that out next. --- src/js/desktop-zoom.js | 32 +++++++++++++++++++++++--------- src/js/gestures.js | 1 + 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/js/desktop-zoom.js b/src/js/desktop-zoom.js index 6acc5d566..9a73ff89d 100644 --- a/src/js/desktop-zoom.js +++ b/src/js/desktop-zoom.js @@ -89,26 +89,40 @@ _registerModule('DesktopZoom', { }, handleMouseWheel: function(e) { + // If scrolling down on a collapsed long caption, expand the caption + var _target = e.target || e.srcElement; + var targetCaption = _target.closest(".pswp__caption"); + if(targetCaption) { + var toggleCaptionBtn = targetCaption.querySelector(".pswp__button--caption--ctrl"); + if(toggleCaptionBtn) { + + if(toggleCaptionBtn.classList.contains("pswp__button--caption--ctrl--expand") && e.wheelDeltaY < -50) { + self.ui.toggleCaption(toggleCaptionBtn); + } else if(toggleCaptionBtn.classList.contains("pswp__button--caption--ctrl--collapse")) { + // Collapse the caption if scrolled to the top and user scrolls further + var innerCaptionElement = targetCaption.querySelector(".pswp__caption__center"); + if(innerCaptionElement.scrollTop === 0 && e.wheelDeltaY > 50) { + self.ui.toggleCaption(toggleCaptionBtn); + } + } else { + e.preventDefault(); + } + + return; + } + } if(_currZoomLevel <= self.currItem.fitRatio) { if( _options.modal ) { if (!_options.closeOnScroll || _numAnimations || _isDragging) { - var source = e.target || e.srcElement; - if(source.classList.contains("pswp__caption__center")) { - if(source.class.contains("pswp__button--caption--ctrl--expand")) { - toggleCaption(source.parentNode); - } - } else { - e.preventDefault(); - } + e.preventDefault(); } else if(_transformKey && Math.abs(e.deltaY) > 2) { // close PhotoSwipe // if browser supports transforms & scroll changed enough _closedByScroll = true; self.close(); } - } return true; } diff --git a/src/js/gestures.js b/src/js/gestures.js index 505e1d6c7..8cce71b20 100644 --- a/src/js/gestures.js +++ b/src/js/gestures.js @@ -1129,6 +1129,7 @@ _registerModule('Gestures', { if(_pointerEventEnabled && !_likelyTouchDevice) { _likelyTouchDevice = (navigator.maxTouchPoints > 1) || (navigator.msMaxTouchPoints > 1); } + _likelyTouchDevice = false; // make variable public self.likelyTouchDevice = _likelyTouchDevice; From a69fb0b6df4f8c7547a24fc1eb2f31b1fa007082 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sat, 9 May 2020 14:31:40 +0100 Subject: [PATCH 25/39] Run setupDesktopZoom regardless. As noted in the comment, a timing issue seems to be preventing this running when _likelyTouchDevice is true. --- src/js/desktop-zoom.js | 6 +++++- src/js/gestures.js | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/js/desktop-zoom.js b/src/js/desktop-zoom.js index 9a73ff89d..7bc31b4b7 100644 --- a/src/js/desktop-zoom.js +++ b/src/js/desktop-zoom.js @@ -22,6 +22,10 @@ _registerModule('DesktopZoom', { return; } + self.setupDesktopZoom(); + + /* There seems to be a timing problem so this may run before a mouseevent is detected in which case + setupDesktopZoom is not run if _likelyTouchDevice was set to true. Just run it all the time. if(_likelyTouchDevice) { // if detected hardware touch support, we wait until mouse is used, // and only then apply desktop-zoom features @@ -31,7 +35,7 @@ _registerModule('DesktopZoom', { } else { self.setupDesktopZoom(true); } - + */ }, setupDesktopZoom: function(onInit) { diff --git a/src/js/gestures.js b/src/js/gestures.js index 8cce71b20..0d35ef439 100644 --- a/src/js/gestures.js +++ b/src/js/gestures.js @@ -1127,9 +1127,10 @@ _registerModule('Gestures', { _downEvents = _dragStartEvent; if(_pointerEventEnabled && !_likelyTouchDevice) { + // 'likely' - Windows 10 laptop with trackpad, TrackPoint and mouse but no touch support reports maxTouchPoints = 2. _likelyTouchDevice = (navigator.maxTouchPoints > 1) || (navigator.msMaxTouchPoints > 1); } - _likelyTouchDevice = false; + // make variable public self.likelyTouchDevice = _likelyTouchDevice; From 6a80c85a89f07e0fa063b9fa1c3e4aad90db3775 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sat, 9 May 2020 22:47:38 +0100 Subject: [PATCH 26/39] Swap out two lines of SVG for two dozen lines of CSS to make the expand/collapse arrows without another request to get an image and still have it work on IE11. Now need to get the event to fire when clicking on the arrow itself. Not sure it is worth the trouble. --- src/css/default-skin/default-skin.scss | 78 +++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index b023de24e..b7403c8c1 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -392,15 +392,11 @@ a.pswp__share--download { transform: translateX(-50%); text-decoration: none; opacity: 1; - + text-align: center; } -.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand { - background: url('data:image/svg+xml;utf8,'); -} -.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse { - background: url('data:image/svg+xml;utf8,'); -} + + /* This must come after setting the background above */ .pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand, .pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse { @@ -409,10 +405,76 @@ a.pswp__share--download { height: 36px; background-color: #ccc; background-size: cover; + i { + position: relative; + background: transparent; + border: 5px solid transparent; + } + i:after, + i:before { + left: 50%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + } + i:before { + margin-left: -11px; + } + i:after { + margin-left: -8px; + } +} +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand { + i { + top: -2px; + } + i:before, + i:after { + bottom: 0%; + } + i:before { + border-bottom-color: #000; + border-width: 11px 11px 13px 11px; + } + i:after { + border-bottom-color: #CCC; + border-width: 8px 8px 10px 8px; + } +} +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse { + i { + top: 2px; + } + i:before, + i:after { + top: 0%; + } + i:before { + border-top-color: #000; + border-width: 13px 11px 11px 11px; + } + i:after { + border-top-color: #CCC; + border-width: 10px 8px 8px 8px; + } } + .pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand:hover, .pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse:hover { - background-color: #fff; + background-color: #FFF; +} +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand:hover { + i:after { + border-bottom-color: #FFF; + } +} +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse:hover { + i:after { + border-top-color: #FFF; + } } From e47f580e5e52e8ca7f6149a1a5ae5daac9b4038d Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sun, 10 May 2020 13:11:01 +0100 Subject: [PATCH 27/39] Back to SVG background images but now Base64 encoded and background size set explicitly so that it will work with IE11. --- src/css/default-skin/default-skin.scss | 79 +++----------------------- 1 file changed, 8 insertions(+), 71 deletions(-) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index b7403c8c1..2d9da034c 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -392,10 +392,14 @@ a.pswp__share--download { transform: translateX(-50%); text-decoration: none; opacity: 1; - text-align: center; } - +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand { + background-image:url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0xMiAwYzYuNjIzIDAgMTIgNS4zNzcgMTIgMTJzLTUuMzc3IDEyLTEyIDEyLTEyLTUuMzc3LTEyLTEyIDUuMzc3LTEyIDEyLTEyem0wIDFjNi4wNzEgMCAxMSA0LjkyOSAxMSAxMXMtNC45MjkgMTEtMTEgMTEtMTEtNC45MjktMTEtMTEgNC45MjktMTEgMTEtMTF6bTUuMjQ3IDE1bC01LjI0Ny02LjQ0LTUuMjYzIDYuNDQtLjczNy0uNjc4IDYtNy4zMjIgNiA3LjMzNS0uNzUzLjY2NXoiLz48L3N2Zz4='); +} +.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse { + background-image:url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0xMiAwYzYuNjIzIDAgMTIgNS4zNzcgMTIgMTJzLTUuMzc3IDEyLTEyIDEyLTEyLTUuMzc3LTEyLTEyIDUuMzc3LTEyIDEyLTEyem0wIDFjNi4wNzEgMCAxMSA0LjkyOSAxMSAxMXMtNC45MjkgMTEtMTEgMTEtMTEtNC45MjktMTEtMTEgNC45MjktMTEgMTEtMTF6bTUuMjQ3IDhsLTUuMjQ3IDYuNDQtNS4yNjMtNi40NC0uNzM3LjY3OCA2IDcuMzIyIDYtNy4zMzUtLjc1My0uNjY1eiIvPjwvc3ZnPg=='); +} /* This must come after setting the background above */ .pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand, @@ -404,80 +408,13 @@ a.pswp__share--download { width: 36px; height: 36px; background-color: #ccc; - background-size: cover; - i { - position: relative; - background: transparent; - border: 5px solid transparent; - } - i:after, - i:before { - left: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - } - i:before { - margin-left: -11px; - } - i:after { - margin-left: -8px; - } -} -.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand { - i { - top: -2px; - } - i:before, - i:after { - bottom: 0%; + background-size: 36px 36px; } - i:before { - border-bottom-color: #000; - border-width: 11px 11px 13px 11px; - } - i:after { - border-bottom-color: #CCC; - border-width: 8px 8px 10px 8px; - } -} -.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse { - i { - top: 2px; - } - i:before, - i:after { - top: 0%; - } - i:before { - border-top-color: #000; - border-width: 13px 11px 11px 11px; - } - i:after { - border-top-color: #CCC; - border-width: 10px 8px 8px 8px; - } -} - .pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand:hover, .pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse:hover { - background-color: #FFF; -} -.pswp__button--caption--ctrl.pswp__button--caption--ctrl--expand:hover { - i:after { - border-bottom-color: #FFF; - } -} -.pswp__button--caption--ctrl.pswp__button--caption--ctrl--collapse:hover { - i:after { - border-top-color: #FFF; - } + background-color: #fff; } - .pswp__caption--empty { display: none; } From b3d452580b4b3d880baaab6012d7fe8151e170b5 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sat, 9 May 2020 22:48:15 +0100 Subject: [PATCH 28/39] Reset default for allowLongCaptions to false. --- src/js/ui/photoswipe-ui-default.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index b24dc0535..7d9dd80b0 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -91,7 +91,7 @@ showCounter: true, showNextPreviousArrows: true, showCaption: true, - allowLongCaptions: true, + allowLongCaptions: false, preloaderEl: true, From e98d6c0429c82ca756be256adb1ae2f03c502d6e Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sun, 10 May 2020 19:16:22 +0100 Subject: [PATCH 29/39] Ensure HTML exists for caption control and change title on button when toggling the control. --- src/js/ui/photoswipe-ui-default.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 7d9dd80b0..8e8adafb4 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -166,6 +166,7 @@ captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); captionCtrl.classList.add("pswp__button--caption--ctrl--collapse"); + captionCtrl.setAttribute("title", "Collapse caption"); } else { // Collapse caption innerCaptionElement.style.height = 'auto'; @@ -173,6 +174,7 @@ captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); + captionCtrl.setAttribute("title", "Expand caption"); } }; @@ -608,6 +610,18 @@ ]; + var _ensureCaptionCtrlExists = function() { + // Ensure that there is a button to toggle the caption + var captionElement = document.querySelector(".pswp__caption"); + if(!captionElement.querySelector(".pswp__button--caption--ctrl")) { + var btn = document.createElement("button"); + var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); + btn.setAttribute("class", "pswp__button pswp__button--caption--ctrl"); + btn.setAttribute("title", "Expand caption"); + captionElement.insertBefore(btn, innerCaptionElement); + } + }; + var _setupUIElements = function() { var item, classAttr, @@ -651,6 +665,8 @@ if(topBar) { loopThroughChildElements( topBar.children ); } + + _ensureCaptionCtrlExists(); }; From d6f50fe1a2c79367fcb0ea78b32e280394daa416 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Tue, 12 May 2020 13:14:51 +0100 Subject: [PATCH 30/39] Allow left/right buttons to show above expanded caption overlay when viewport is wide enough. --- src/css/default-skin/default-skin.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index 2d9da034c..cbc9b3e61 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -144,6 +144,14 @@ position: absolute; z-index: 1; } +/* Buttons should appear above expanded caption overlay if viewport wider than 540px as the +the maximum width of the caption is 480px plus 30px each side. */ +@media only screen and (min-width: 540px) { + .pswp__button--arrow--left, + .pswp__button--arrow--right { + z-index: 3; + } +} .pswp__button--arrow--left { left: 0; From 510d5aef136510afb60f6ced910aaa39941404f0 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Wed, 13 May 2020 11:12:40 +0100 Subject: [PATCH 31/39] Now with keyboard control. --- src/js/core.js | 22 +++++++++++------- src/js/ui/photoswipe-ui-default.js | 37 ++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 8820d306e..79616879c 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -209,12 +209,6 @@ var _isOpen, _setTranslateX(x, _containerStyle); }, - _resetCaptionCtrl = function() { - var captionCtrl = self.scrollWrap.querySelector(".pswp__button--caption--ctrl"); - captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); - captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); - }, - _calculatePanOffset = function(axis, zoomLevel) { var m = _midZoomPoint[axis] - _offset[axis]; return _startPanOffset[axis] + _currPanDist[axis] + m - m * ( zoomLevel / _startZoomLevel ); @@ -392,6 +386,14 @@ var _isOpen, keydownAction = 'prev'; } else if(e.keyCode === 39) { keydownAction = 'next'; + } else if(e.keyCode === 13 || e.keyCode === 32) { /* Enter or spacebar */ + var btnCaptionCtrl = document.getElementById("pswp__button--caption--ctrl"); + if(btnCaptionCtrl) { + if(btnCaptionCtrl.classList.contains("pswp__button--caption--ctrl--expand") || + btnCaptionCtrl.classList.contains("pswp__button--caption--ctrl--collapse")) { + keydownAction = 'toggleCaption'; + } + } } } @@ -736,7 +738,7 @@ var publicMethods = { _stopDragUpdateLoop(); _stopAllAnimations(); - _resetCaptionCtrl(); + self.ui.resetCaptionCtrl(); _listeners = {}; }, @@ -788,7 +790,7 @@ var publicMethods = { _moveMainScroll(_slideSize.x * _currPositionIndex); - _resetCaptionCtrl(); + self.ui.resetCaptionCtrl(); _stopAllAnimations(); _mainScrollAnimating = false; @@ -833,6 +835,10 @@ var publicMethods = { self.updateSize(true); }, + toggleCaption: function(el) { + self.ui.toggleCaption(el); + }, + // update current zoom/pan objects updateCurrZoomItem: function(emulateSetContent) { if(emulateSetContent) { diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 8e8adafb4..a7d818d1e 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -74,10 +74,11 @@ var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); if(innerCaptionElement.clientHeight - 10 > layoutData.captionInitialHeight) { captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); + captionCtrl.setAttribute("aria-controls", "pswp__caption__center"); + innerCaptionElement.setAttribute("aria-expanded", "false"); } else { - captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); - captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); + _resetCaptionCtrl(captionCtrl); } } @@ -147,13 +148,30 @@ return layoutData; }; - var _toggleCaption = function(el) { - var captionCtrl = el; //e.target || e.srcElement; + var _resetCaptionCtrl = function(captionCtrl) { + if(!captionCtrl) { + captionCtrl = pswp.scrollWrap.querySelector(".pswp__button--caption--ctrl"); + } + + captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); + captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); + captionCtrl.removeAttribute("aria-controls"); + + var innerCaptionElement = captionCtrl.parentNode.querySelector(".pswp__caption__center"); + innerCaptionElement.removeAttribute("aria-expanded"); + }; + + var _toggleCaption = function(captionCtrl) { + if(!captionCtrl) { + captionCtrl = pswp.scrollWrap.querySelector(".pswp__button--caption--ctrl"); + } + var captionElement = captionCtrl.parentNode; var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); var layoutData = _getLayoutData(captionElement); if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")) { // Expand caption + console.log("expand caption"); if(captionElement.clientHeight < layoutData.captionMaxHeight) { // It fits in space below top bar captionElement.style.top = (window.innerHeight - captionElement.clientHeight) + "px"; innerCaptionElement.style.height = 'auto'; @@ -162,14 +180,21 @@ captionElement.style.top = layoutData.gapTop + "px"; innerCaptionElement.style.height = layoutData.captionMaxHeight + "px"; innerCaptionElement.style.overflowY = "auto"; + innerCaptionElement.focus(); + console.log("innerCaptionElement should be focussed"); } captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); captionCtrl.classList.add("pswp__button--caption--ctrl--collapse"); captionCtrl.setAttribute("title", "Collapse caption"); + + innerCaptionElement.setAttribute("aria-expanded", "true"); } else { // Collapse caption + console.log("collapse caption"); innerCaptionElement.style.height = 'auto'; + innerCaptionElement.setAttribute("aria-expanded", "false"); + captionElement.style.top = layoutData.captionInitialPositionTop + "px"; captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); @@ -993,6 +1018,10 @@ ui.toggleCaption = function(el) { _toggleCaption(el); }; + + ui.resetCaptionCtrl = function(el) { + _resetCaptionCtrl(el); + }; }; return PhotoSwipeUI_Default; From e945a8a7966df80add7aaa4e0472d6664af5bd46 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Wed, 13 May 2020 12:45:13 +0100 Subject: [PATCH 32/39] Moving the setting of tabindex and focus on the innerCaptionElement to where the keydown events are handled. Also removing some console output. --- src/js/core.js | 4 ++++ src/js/ui/photoswipe-ui-default.js | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 79616879c..57a3dbcdc 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -391,6 +391,10 @@ var _isOpen, if(btnCaptionCtrl) { if(btnCaptionCtrl.classList.contains("pswp__button--caption--ctrl--expand") || btnCaptionCtrl.classList.contains("pswp__button--caption--ctrl--collapse")) { + // Add tabindex to the caption div so that it can take focus and be controlled by up/down arrows + var innerCaptionElement = btnCaptionCtrl.parentNode.querySelector(".pswp__caption__center"); + innerCaptionElement.setAttribute("tabindex", "-1"); + innerCaptionElement.focus(); keydownAction = 'toggleCaption'; } } diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index a7d818d1e..b3a17aead 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -171,7 +171,6 @@ var layoutData = _getLayoutData(captionElement); if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")) { // Expand caption - console.log("expand caption"); if(captionElement.clientHeight < layoutData.captionMaxHeight) { // It fits in space below top bar captionElement.style.top = (window.innerHeight - captionElement.clientHeight) + "px"; innerCaptionElement.style.height = 'auto'; @@ -180,8 +179,6 @@ captionElement.style.top = layoutData.gapTop + "px"; innerCaptionElement.style.height = layoutData.captionMaxHeight + "px"; innerCaptionElement.style.overflowY = "auto"; - innerCaptionElement.focus(); - console.log("innerCaptionElement should be focussed"); } captionCtrl.classList.remove("pswp__button--caption--ctrl--expand"); @@ -191,7 +188,6 @@ innerCaptionElement.setAttribute("aria-expanded", "true"); } else { // Collapse caption - console.log("collapse caption"); innerCaptionElement.style.height = 'auto'; innerCaptionElement.setAttribute("aria-expanded", "false"); @@ -642,6 +638,7 @@ var btn = document.createElement("button"); var innerCaptionElement = captionElement.querySelector(".pswp__caption__center"); btn.setAttribute("class", "pswp__button pswp__button--caption--ctrl"); + btn.setAttribute("id", "pswp__button--caption--ctrl"); btn.setAttribute("title", "Expand caption"); captionElement.insertBefore(btn, innerCaptionElement); } From a27537683c8af01bbb4952ff3e958f397a2cba00 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Wed, 13 May 2020 21:06:58 +0100 Subject: [PATCH 33/39] Animate expansion and collapse of caption. Note that Google says that doing a CSS animation on height (and width) is bad for performance so I may revisit this later but it seems to work just fine. https://developers.google.com/web/updates/2017/03/performant-expand-and-collapse --- src/css/default-skin/default-skin.scss | 1 + src/js/core.js | 4 +- src/js/ui/photoswipe-ui-default.js | 80 +++++++++++++++++--------- 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/src/css/default-skin/default-skin.scss b/src/css/default-skin/default-skin.scss index cbc9b3e61..0fc84f80c 100644 --- a/src/css/default-skin/default-skin.scss +++ b/src/css/default-skin/default-skin.scss @@ -363,6 +363,7 @@ a.pswp__share--download { line-height: 20px; color: #FFF; background-color: #000; + transition: height 250ms ease-out; a { color: #CCF; diff --git a/src/js/core.js b/src/js/core.js index 57a3dbcdc..a0ee82593 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -742,7 +742,7 @@ var publicMethods = { _stopDragUpdateLoop(); _stopAllAnimations(); - self.ui.resetCaptionCtrl(); + self.ui.resetCaption(); _listeners = {}; }, @@ -794,7 +794,7 @@ var publicMethods = { _moveMainScroll(_slideSize.x * _currPositionIndex); - self.ui.resetCaptionCtrl(); + self.ui.resetCaption(); _stopAllAnimations(); _mainScrollAnimating = false; diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index b3a17aead..f48dc696d 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -41,6 +41,10 @@ _galleryHasOneSlide, + _stylesheet, + _ruleExpanded, + _ruleCollapsed, + _options, _defaultUIOptions = { barsSize: {top:44, bottom:'auto'}, @@ -57,29 +61,31 @@ } innerCaptionElement.innerHTML = item.title; - // If allowLongCaptions is true, position caption from top rather than bottom. + // If allowLongCaptions is true, position caption just under picture and show "Expand" button if necessary if(_options.allowLongCaptions) { var imagePositionTop = item.initialPosition.y; var apparentImageHeight = Math.round(item.h * item.initialZoomLevel); var gapTop = item.vGap.top; + var naturalCaptionHeight = innerCaptionElement.clientHeight; - _setLayoutData(captionElement, imagePositionTop, apparentImageHeight, gapTop); - var layoutData = _getLayoutData(captionElement); + var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); - captionElement.style.bottom = 'auto'; - captionElement.style.top = layoutData.captionInitialPositionTop + "px"; + _setLayoutData(captionElement, imagePositionTop, apparentImageHeight, gapTop, naturalCaptionHeight); + var layoutData = _getLayoutData(captionElement); // Show the 'expand' control only if caption extends out of view. Reset height first. - innerCaptionElement.style.height = 'auto'; - var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); - if(innerCaptionElement.clientHeight - 10 > layoutData.captionInitialHeight) { + if(naturalCaptionHeight - 10 > layoutData.maxCollapsedCaptionHeight) { captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.setAttribute("aria-controls", "pswp__caption__center"); + + innerCaptionElement.classList.add("collapsed"); innerCaptionElement.setAttribute("aria-expanded", "false"); } else { - _resetCaptionCtrl(captionCtrl); + _resetCaption(captionCtrl); } + + _ruleCollapsed.style.height = layoutData.maxCollapsedCaptionHeight + "px"; } return true; @@ -128,27 +134,31 @@ _blockControlsTap, _blockControlsTapTimeout; - var _setLayoutData = function(captionElement, imagePositionTop, apparentImageHeight, gapTop){ + // Write key layout dimensions as data attributes on the caption element + var _setLayoutData = function(captionElement, imagePositionTop, apparentImageHeight, gapTop, naturalCaptionHeight){ captionElement.dataset.imagePositionTop = imagePositionTop; captionElement.dataset.apparentImageHeight = apparentImageHeight; captionElement.dataset.gapTop = gapTop; + captionElement.dataset.naturalCaptionHeight = naturalCaptionHeight; }; var _getLayoutData = function(captionElement) { var layoutData = {}; + // Read data attributes on the caption element layoutData.gapTop = parseInt(captionElement.dataset.gapTop, 10); layoutData.imagePositionTop = parseInt(captionElement.dataset.imagePositionTop, 10); layoutData.apparentImageHeight = parseInt(captionElement.dataset.apparentImageHeight, 10); + layoutData.naturalCaptionHeight = parseInt(captionElement.dataset.naturalCaptionHeight, 10); - layoutData.captionInitialPositionTop = layoutData.imagePositionTop + layoutData.apparentImageHeight; - layoutData.captionInitialHeight = window.innerHeight - layoutData.captionInitialPositionTop; - layoutData.captionMaxHeight = window.innerHeight - layoutData.gapTop; + var imageBottomEdgeFromTop = layoutData.imagePositionTop + layoutData.apparentImageHeight; + layoutData.maxCollapsedCaptionHeight = window.innerHeight - imageBottomEdgeFromTop; + layoutData.maxExpandedCaptionHeight = window.innerHeight - layoutData.gapTop; return layoutData; }; - var _resetCaptionCtrl = function(captionCtrl) { + var _resetCaption = function(captionCtrl) { if(!captionCtrl) { captionCtrl = pswp.scrollWrap.querySelector(".pswp__button--caption--ctrl"); } @@ -159,6 +169,11 @@ var innerCaptionElement = captionCtrl.parentNode.querySelector(".pswp__caption__center"); innerCaptionElement.removeAttribute("aria-expanded"); + innerCaptionElement.classList.remove("expanded"); + innerCaptionElement.classList.remove("collapsed"); + + _ruleExpanded.style.height = "auto"; + _ruleCollapsed.style.height = "auto"; }; var _toggleCaption = function(captionCtrl) { @@ -171,13 +186,11 @@ var layoutData = _getLayoutData(captionElement); if(captionCtrl.classList.contains("pswp__button--caption--ctrl--expand")) { // Expand caption - if(captionElement.clientHeight < layoutData.captionMaxHeight) { // It fits in space below top bar - captionElement.style.top = (window.innerHeight - captionElement.clientHeight) + "px"; - innerCaptionElement.style.height = 'auto'; + if(layoutData.naturalCaptionHeight < layoutData.maxExpandedCaptionHeight) { // It fits in space below top bar + _ruleExpanded.style.height = layoutData.naturalCaptionHeight + "px"; } - else { - captionElement.style.top = layoutData.gapTop + "px"; - innerCaptionElement.style.height = layoutData.captionMaxHeight + "px"; + else { // Caption is taller than the space available + _ruleExpanded.style.height = layoutData.maxExpandedCaptionHeight + "px"; innerCaptionElement.style.overflowY = "auto"; } @@ -185,17 +198,21 @@ captionCtrl.classList.add("pswp__button--caption--ctrl--collapse"); captionCtrl.setAttribute("title", "Collapse caption"); + innerCaptionElement.classList.remove("collapsed"); + innerCaptionElement.classList.add("expanded"); innerCaptionElement.setAttribute("aria-expanded", "true"); } else { // Collapse caption - innerCaptionElement.style.height = 'auto'; - innerCaptionElement.setAttribute("aria-expanded", "false"); - - captionElement.style.top = layoutData.captionInitialPositionTop + "px"; + _ruleCollapsed.style.height = layoutData.maxCollapsedCaptionHeight + "px"; captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.classList.remove("pswp__button--caption--ctrl--collapse"); captionCtrl.setAttribute("title", "Expand caption"); + + innerCaptionElement.style.overflowY = "hidden"; + innerCaptionElement.classList.remove("expanded"); + innerCaptionElement.classList.add("collapsed"); + innerCaptionElement.setAttribute("aria-expanded", "false"); } }; @@ -817,6 +834,17 @@ _setupFullscreenAPI(); _setupLoadingIndicator(); + + // Get handle on stylesheet - doesn't really matter which but I'll take default-skin.css + _stylesheet = document.styleSheets[1]; + + // From https://davidwalsh.name/add-rules-stylesheets + // We insert an empty rule just to create a new CSSStyleRule object. The second param is the index to + // insert at using the length property we effectively "append" the rule to the end of the sheet + var ruleExpandedIndex = _stylesheet.insertRule(".pswp__caption__center.expanded {}", _stylesheet.cssRules.length); + var ruleCollapsedIndex = _stylesheet.insertRule(".pswp__caption__center.collapsed {}", _stylesheet.cssRules.length); + _ruleExpanded = _stylesheet.cssRules.item(ruleExpandedIndex); + _ruleCollapsed = _stylesheet.cssRules.item(ruleCollapsedIndex); }; ui.setIdle = function(isIdle) { @@ -1016,8 +1044,8 @@ _toggleCaption(el); }; - ui.resetCaptionCtrl = function(el) { - _resetCaptionCtrl(el); + ui.resetCaption = function(el) { + _resetCaption(el); }; }; From 5b52d5d035d3a19e2d1c6783ef10d4de6c050ec7 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Wed, 13 May 2020 22:00:53 +0100 Subject: [PATCH 34/39] Get around cross-site security issue by creating a new stylesheet rather than attempting to manipulate an existing one. --- src/js/ui/photoswipe-ui-default.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index f48dc696d..c54db9a67 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -561,7 +561,13 @@ }; - + // From https://davidwalsh.name/add-rules-stylesheets + var _createStylesheet = function() { + var style = document.createElement("style"); + style.appendChild(document.createTextNode("")); + document.head.appendChild(style); + return style.sheet; + }; var _uiElements = [ { @@ -835,12 +841,12 @@ _setupLoadingIndicator(); - // Get handle on stylesheet - doesn't really matter which but I'll take default-skin.css - _stylesheet = document.styleSheets[1]; + // Make a new stylesheet since there will be cross-site security issues if referencing a stylesheet on CDN + _stylesheet = _createStylesheet(); // From https://davidwalsh.name/add-rules-stylesheets // We insert an empty rule just to create a new CSSStyleRule object. The second param is the index to - // insert at using the length property we effectively "append" the rule to the end of the sheet + // insert at using the length property we effectively "append" the rule to the end of the sheet. var ruleExpandedIndex = _stylesheet.insertRule(".pswp__caption__center.expanded {}", _stylesheet.cssRules.length); var ruleCollapsedIndex = _stylesheet.insertRule(".pswp__caption__center.collapsed {}", _stylesheet.cssRules.length); _ruleExpanded = _stylesheet.cssRules.item(ruleExpandedIndex); From d4e2d1da40a348c704accdc96c6f3b6003bf02d8 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 14 May 2020 13:54:43 +0100 Subject: [PATCH 35/39] A bit of rearrangement as I discovered that dragging to a new photo on a phone does not call the goTo function so the resetCaption function was not getting called which had some odd results. --- src/js/core.js | 2 -- src/js/ui/photoswipe-ui-default.js | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index a0ee82593..7f09bb8b1 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -794,8 +794,6 @@ var publicMethods = { _moveMainScroll(_slideSize.x * _currPositionIndex); - self.ui.resetCaption(); - _stopAllAnimations(); _mainScrollAnimating = false; diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index c54db9a67..17d62af42 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -66,6 +66,8 @@ var imagePositionTop = item.initialPosition.y; var apparentImageHeight = Math.round(item.h * item.initialZoomLevel); var gapTop = item.vGap.top; + + ui.resetCaption(); var naturalCaptionHeight = innerCaptionElement.clientHeight; var captionCtrl = captionElement.querySelector(".pswp__button--caption--ctrl"); @@ -78,7 +80,6 @@ captionCtrl.classList.add("pswp__button--caption--ctrl--expand"); captionCtrl.setAttribute("aria-controls", "pswp__caption__center"); - innerCaptionElement.classList.add("collapsed"); innerCaptionElement.setAttribute("aria-expanded", "false"); } else { @@ -86,6 +87,7 @@ } _ruleCollapsed.style.height = layoutData.maxCollapsedCaptionHeight + "px"; + innerCaptionElement.classList.add("collapsed"); } return true; From c67b066992be6e31ac6b25c087a17e7319937798 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Thu, 14 May 2020 16:56:18 +0100 Subject: [PATCH 36/39] Increase the width of the caption if long captions are selected. --- src/js/ui/photoswipe-ui-default.js | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 17d62af42..045b12f8a 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -571,6 +571,23 @@ return style.sheet; }; + var _createStylesForLongCaptions = function() { + // Make a new stylesheet since there will be cross-site security issues if referencing a stylesheet on CDN + _stylesheet = _createStylesheet(); + + // From https://davidwalsh.name/add-rules-stylesheets + // We insert an empty rule just to create a new CSSStyleRule object. The second param is the index to + // insert at using the length property we effectively "append" the rule to the end of the sheet. + var ruleExpandedIndex = _stylesheet.insertRule(".pswp__caption__center.expanded {}", _stylesheet.cssRules.length); + var ruleCollapsedIndex = _stylesheet.insertRule(".pswp__caption__center.collapsed {}", _stylesheet.cssRules.length); + _ruleExpanded = _stylesheet.cssRules.item(ruleExpandedIndex); + _ruleCollapsed = _stylesheet.cssRules.item(ruleCollapsedIndex); + + // While we are here, increase the width of the caption. It is very narrow which keeps it roughly centered + // if there are only a few words but it looks odd when the photo is wide and the caption is long. + _stylesheet.insertRule(".pswp__caption__center { width: 100%; max-width: 720px; }", _stylesheet.cssRules.length); + }; + var _uiElements = [ { name: 'caption', @@ -843,16 +860,9 @@ _setupLoadingIndicator(); - // Make a new stylesheet since there will be cross-site security issues if referencing a stylesheet on CDN - _stylesheet = _createStylesheet(); - - // From https://davidwalsh.name/add-rules-stylesheets - // We insert an empty rule just to create a new CSSStyleRule object. The second param is the index to - // insert at using the length property we effectively "append" the rule to the end of the sheet. - var ruleExpandedIndex = _stylesheet.insertRule(".pswp__caption__center.expanded {}", _stylesheet.cssRules.length); - var ruleCollapsedIndex = _stylesheet.insertRule(".pswp__caption__center.collapsed {}", _stylesheet.cssRules.length); - _ruleExpanded = _stylesheet.cssRules.item(ruleExpandedIndex); - _ruleCollapsed = _stylesheet.cssRules.item(ruleCollapsedIndex); + if(_options.allowLongCaptions) { + _createStylesForLongCaptions(); + } }; ui.setIdle = function(isIdle) { From 78c88f1e7ba63c5b7100a0b7174557cae673cfac Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sun, 17 May 2020 20:41:13 +0100 Subject: [PATCH 37/39] Added section for caption expand/collapse by vertical swipe/drag. Unfortunately it did not work reliably and so it is now commented out in the hope that someone else will understand how to fix it. Added lines 348 and 719 as I thought they might be why I could usually expand the caption with an upward swipe but could not close it. It seems those lines should be there but they did not seem to help so now commented out. --- src/js/gestures.js | 50 +++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/js/gestures.js b/src/js/gestures.js index 0d35ef439..22737c3ef 100644 --- a/src/js/gestures.js +++ b/src/js/gestures.js @@ -54,26 +54,31 @@ var _gestureStartTime, _isEqualPoints = function(p1, p2) { return p1.x === p2.x && p1.y === p2.y; }, + _isNearbyPoints = function(touch0, touch1) { return Math.abs(touch0.x - touch1.x) < DOUBLE_TAP_RADIUS && Math.abs(touch0.y - touch1.y) < DOUBLE_TAP_RADIUS; }, + _calculatePointsDistance = function(p1, p2) { _tempPoint.x = Math.abs( p1.x - p2.x ); _tempPoint.y = Math.abs( p1.y - p2.y ); return Math.sqrt(_tempPoint.x * _tempPoint.x + _tempPoint.y * _tempPoint.y); }, + _stopDragUpdateLoop = function() { if(_dragAnimFrame) { _cancelAF(_dragAnimFrame); _dragAnimFrame = null; } }, + _dragUpdateLoop = function() { if(_isDragging) { _dragAnimFrame = _requestAF(_dragUpdateLoop); _renderMovement(); } }, + _canPan = function() { return !(_options.scaleMode === 'fit' && _currZoomLevel === self.currItem.initialZoomLevel); }, @@ -99,21 +104,23 @@ var _gestureStartTime, _preventObj = {}, _preventDefaultEventBehaviour = function(e, isDown) { _preventObj.prevent = !_closestElement(e.target, _options.isClickableElement); - _shout('preventDragEvent', e, isDown, _preventObj); return _preventObj.prevent; }, + _convertTouchToPoint = function(touch, p) { p.x = touch.pageX; p.y = touch.pageY; p.id = touch.identifier; return p; }, + _findCenterOfPoints = function(p1, p2, pCenter) { pCenter.x = (p1.x + p2.x) * 0.5; pCenter.y = (p1.y + p2.y) * 0.5; }, + _pushPosPoint = function(time, x, y) { if(time - _gestureCheckSpeedTime > 50) { var o = _posPoints.length > 2 ? _posPoints.shift() : {}; @@ -135,6 +142,7 @@ var _gestureStartTime, _ePoint2 = {}, _tempPointsArr = [], _tempCounter, + _getTouchPoints = function(e) { // clean up previous points, without recreating array while(_tempPointsArr.length > 0) { @@ -337,6 +345,7 @@ var _gestureStartTime, _isDragging = _isFirstMove = true; framework.bind(window, _upMoveEvents, self); + // framework.bind(window, _downEvents, self); // I thought this might be needed to collapse caption but it made no difference. _isZoomingIn = _wasOverInitialZoom = @@ -394,13 +403,10 @@ var _gestureStartTime, _midZoomPoint.y = Math.abs(_currCenterPoint.y) - _panOffset.y; _currPointsDistance = _startPointsDistance = _calculatePointsDistance(p, p2); } - - }, // Pointermove/touchmove/mousemove handler _onDragMove = function(e) { - e.preventDefault(); if(_pointerEventEnabled) { @@ -427,7 +433,6 @@ var _gestureStartTime, _currentPoints = touchesList; } } - } else { _currentPoints = touchesList; } @@ -435,7 +440,6 @@ var _gestureStartTime, }, _renderMovement = function() { - if(!_currentPoints) { return; } @@ -537,18 +541,14 @@ var _gestureStartTime, } else { // handle behaviour for one point (dragging or panning) - if(!_direction) { return; } - // if dragging up on collapsed caption then open it. - if(_isFirstMove) { _isFirstMove = false; // subtract drag distance that was used during the detection direction - if( Math.abs(delta.x) >= DIRECTION_CHECK_OFFSET) { delta.x -= _currentPoints[0].x - _startPoint.x; } @@ -566,15 +566,29 @@ var _gestureStartTime, return; } - // if dragging up on a collapsed long caption, expand the caption - var targetCaption = _target.closest(".pswp__caption"); - if(_direction === 'v' && delta.y > -DIRECTION_CHECK_OFFSET && targetCaption) { - var toggleCaptionBtn = targetCaption.querySelector(".pswp__button--caption--ctrl"); - if(toggleCaptionBtn && toggleCaptionBtn.classList.contains("pswp__button--caption--ctrl--expand")) { - self.ui.toggleCaption(toggleCaptionBtn); - return; + /* ************************************************************** + Commenting this section out because it does not work reliably + especially when swiping down in an attempt to close the caption. + I'd be grateful if anyone can figure out why and fix it. + ***************************************************************** + // If dragging up on a collapsed long caption, expand the caption; + // If dragging down on expanded long caption when at the top, collapse the caption. + if(_direction === 'v' && _options.allowLongCaptions) { + var targetCaption = _target.closest(".pswp__caption"); + if(targetCaption) { + var toggleCaptionBtn = targetCaption.querySelector(".pswp__button--caption--ctrl"); + var isExpanded = toggleCaptionBtn.classList.contains("pswp__button--caption--ctrl--collapse"); + var isCollapsed = toggleCaptionBtn.classList.contains("pswp__button--caption--ctrl--expand"); + var innerCaptionElement = targetCaption.querySelector(".pswp__caption__center"); + + if((delta.y < -DIRECTION_CHECK_OFFSET && isCollapsed) || + (delta.y > DIRECTION_CHECK_OFFSET && isExpanded && innerCaptionElement.scrollTop === 0)) { + self.ui.toggleCaption(toggleCaptionBtn); + return; + } } } + */ if(_direction === 'v' && _options.closeOnVerticalDrag) { if(!_canPan()) { @@ -611,7 +625,6 @@ var _gestureStartTime, // Pointerup/pointercancel/touchend/touchcancel/mouseup event handler _onDragRelease = function(e) { - if(_features.isOldAndroid ) { if(_oldAndroidTouchEndTimeout && e.type === 'mouseup') { @@ -703,6 +716,7 @@ var _gestureStartTime, if(numPoints === 0) { _isDragging = false; framework.unbind(window, _upMoveEvents, self); + // framework.unbind(window, _downEvents, self); // I thought this might be needed to collapse caption but it made no difference. _stopDragUpdateLoop(); From b02454a300a7c1563c2653e72843371efc344b60 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sun, 17 May 2020 20:43:55 +0100 Subject: [PATCH 38/39] Add "FYI" to console notices explaining that two options are overridden when allowLongCaptions is true. Don't close caption on vertical drag when allowLongCaption is true. Don't close caption when tap is on an element inside the caption --- src/js/ui/photoswipe-ui-default.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/js/ui/photoswipe-ui-default.js b/src/js/ui/photoswipe-ui-default.js index 045b12f8a..0322c57fc 100644 --- a/src/js/ui/photoswipe-ui-default.js +++ b/src/js/ui/photoswipe-ui-default.js @@ -523,11 +523,11 @@ _overrideOptionsIfAllowLongCaptionsTrue = function() { if(_options.closeOnScroll) { - console.info("Resetting _options.closeOnScroll to false because _options.allowLongCaptions is true."); + console.info("FYI: Resetting _options.closeOnScroll to false because _options.allowLongCaptions is true."); _options.closeOnScroll = false; } if(_options.closeOnVerticalDrag) { - console.info("Resetting _options.closeOnVerticalDrag to false because _options.allowLongCaptions is true."); + console.info("FYI: Resetting _options.closeOnVerticalDrag to false because _options.allowLongCaptions is true."); _options.closeOnVerticalDrag = false; } }, @@ -536,6 +536,10 @@ // Hide controls on vertical drag _listen('onVerticalDrag', function(now) { + if(_options.allowLongCaptions) { + return; + } + if(_controlsVisible && now < 0.95) { ui.hideControls(); } else if(!_controlsVisible && now >= 0.95) { @@ -946,9 +950,10 @@ } } } else { - - // tap anywhere (except buttons and caption) to toggle visibility of controls - if(_options.tapToToggleControls) { + // Tap anywhere (except buttons and caption) to toggle visibility of controls + // Since the caption may now contain other elements, have to check if target is in caption + var targetCaption = target.closest(".pswp__caption"); + if(_options.tapToToggleControls && !targetCaption) { if(_controlsVisible) { ui.hideControls(); } else { From d40b745821e9b02e5637be5d66b5cd1025f67105 Mon Sep 17 00:00:00 2001 From: petersweetandsour Date: Sun, 17 May 2020 20:44:34 +0100 Subject: [PATCH 39/39] Remove some console output --- src/js/core.js | 1 - src/js/items-controller.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/js/core.js b/src/js/core.js index 7f09bb8b1..bac0c8d94 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -352,7 +352,6 @@ var _isOpen, s.left = item.initialPosition.x + 'px'; s.top = item.initialPosition.y + 'px'; - console.log("This is _applyZoomPanToItem at line 355"); item.zoom = zoomRatio; item.apparentImageHeight = h; item.imageFromTop = item.initialPosition; diff --git a/src/js/items-controller.js b/src/js/items-controller.js index ba8119166..165ec4744 100644 --- a/src/js/items-controller.js +++ b/src/js/items-controller.js @@ -422,12 +422,10 @@ _registerModule('Controller', { item.loadComplete = item.img = null; _calculateItemSize(item, _viewportSize); _applyZoomPanToItem(item); - console.log("index: " + index + ", item.container.style.transform: " + item.container.style.transform); if(holder.index === _currentItemIndex) { // recalculate dimensions self.updateCurrZoomItem(); - console.log("index: " + index + ", item.container.style.transform: " + item.container.style.transform); } return; }