intranet-pictures 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 389f9f8c45887f26425f96b166204dda1c9edcc443b8e6b70fc83dc3ce8e6ab4
4
- data.tar.gz: 8cd7e0f11ae898d2ccee675f87d14facacf84b472c37d456f2a5ba2b8ed68d64
3
+ metadata.gz: 6e5e318561ea69bdaed8eaf38cf8d1349220835196596acc6ba65640c2deac52
4
+ data.tar.gz: ebc612ab80afffc3c9f70a3ea0b2da47467006b91854a0e7f7c05227a2c64a2d
5
5
  SHA512:
6
- metadata.gz: a26dab3d6b2d07d29bde79c2ce8b6fe8c95a3d3f0e7bf5fd90bf9537619b9ef5cae2d947c2ba6b068919c0048bbfc94612d02abb534510626e9d04ab5e97b0d3
7
- data.tar.gz: 71ef4e5113ee75f4067c22dd0623bb17fbf651cbbb5f91aa9440c0ec19391f4f21faab2aa5cac3e8672084cef6448287e6d5fc5cb021eb01863c86287ed31472
6
+ metadata.gz: fc2992a96129bf8b0e8a0e79753a9833541a10b875bddc9893cf5dec74e595dcf5693fd28f5b5c4b771725fb0bb64f14ebc43efb87855959c780efa19e4a822f
7
+ data.tar.gz: 26b461521d1b71a98a37f0e1848a3cae417eb79ccc8ba19faeaafbbc94a38143fa00871e53118417923b3a9bd1326520ae57492f732fa9fcc9f7ee68b0f35a6f
@@ -240,7 +240,8 @@ module Intranet
240
240
  " viewer_close: '#{I18n.t('pictures.viewer.close')}',\n" \
241
241
  " viewer_zoom: '#{I18n.t('pictures.viewer.zoom')}',\n" \
242
242
  " viewer_previous: '#{I18n.t('pictures.viewer.previous')}',\n" \
243
- " viewer_next: '#{I18n.t('pictures.viewer.next')}' };"]
243
+ " viewer_next: '#{I18n.t('pictures.viewer.next')}',\n" \
244
+ " viewer_toggle_caption: '#{I18n.t('pictures.viewer.toggle_caption')}' };"]
244
245
  end
245
246
 
246
247
  ##########################################################################
@@ -8,7 +8,7 @@ module Intranet
8
8
  NAME = 'intranet-pictures'
9
9
 
10
10
  # The version of the gem, according to semantic versionning.
11
- VERSION = '2.1.0'
11
+ VERSION = '2.2.0'
12
12
 
13
13
  # The URL of the gem homepage.
14
14
  HOMEPAGE_URL = 'https://rubygems.org/gems/intranet-pictures'
@@ -10,6 +10,7 @@ en:
10
10
  zoom: 'Zoom'
11
11
  previous: 'Previous image'
12
12
  next: 'Next image'
13
+ toggle_caption: 'Toggle caption/info pannel'
13
14
  nav:
14
15
  event: 'Events'
15
16
  city: 'Cities'
@@ -10,6 +10,7 @@ fr:
10
10
  zoom: 'Agrandir'
11
11
  previous: 'Image précédente'
12
12
  next: 'Image suivante'
13
+ toggle_caption: 'Afficher/Masquer les détails'
13
14
  nav:
14
15
  event: 'Événements'
15
16
  city: 'Villes'
@@ -12,43 +12,141 @@ import PhotoSwipeDynamicCaption from './photoswipe/photoswipe-dynamic-caption-pl
12
12
  // Import internationalization support
13
13
  import i18n from './../i18n.js';
14
14
 
15
- function convertDate(iso8601_date) {
16
- const d = new Date(iso8601_date);
17
- const str = d.toLocaleDateString() + ' ' + d.toLocaleTimeString().replace(/(\d{2}):(\d{2}):(\d{2})/, '$1h$2');
18
- return str;
15
+ class PhotoSwipePictureGallery {
16
+ constructor(items) {
17
+ // Create PhotoSwipe Lightbox
18
+ const lightboxOptions = {
19
+ dataSource: items,
20
+ pswpModule: PhotoSwipe,
21
+ bgOpacity: 0.95,
22
+ closeOnVerticalDrag: false,
23
+ closeTitle: i18n.viewer_close + ' (Esc)',
24
+ zoomTitle: i18n.viewer_zoom + ' (z)',
25
+ arrowPrevTitle: i18n.viewer_previous,
26
+ arrowNextTitle: i18n.viewer_next,
27
+ };
28
+ this.lightbox = new PhotoSwipeLightbox(lightboxOptions);
29
+
30
+ // Initialize caption plugin
31
+ const captionPluginOptions = {
32
+ type: 'below',
33
+ mobileLayoutBreakpoint: 800,
34
+ captionContent: (slide) => {
35
+ return this._captionContent(slide)
36
+ },
37
+ };
38
+ this.captionPlugin = new PhotoSwipeDynamicCaption(this.lightbox, captionPluginOptions);
39
+
40
+ // Add custom 'Info' button, see https://photoswipe.com/v5/docs/adding-custom-buttons/
41
+ // Info menu button
42
+ const infoButton = {
43
+ name: 'info',
44
+ title: i18n.viewer_toggle_caption,
45
+ order: 15, // Insert button between zoom & close buttons
46
+ isButton: true,
47
+ html: {
48
+ isCustomSVG: true,
49
+ inner: '<path d="M7 16a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" id="pswp__icn-info"/>'
50
+ + '<path fill="currentColor" d="M17 15h-2v6h2z"/>'
51
+ + '<path fill="currentColor" d="M17 11h-2v2h2z"/>',
52
+ outlineID: 'pswp__icn-info',
53
+ },
54
+ onClick: (ev, el, pswp) => {
55
+ this._toggleInfoPannel(ev, el, pswp);
56
+ },
57
+ };
58
+ this.lightbox.on('uiRegister', () => {
59
+ this.lightbox.pswp.ui.registerElement(infoButton);
60
+ });
61
+
62
+ this.lightbox.on('calcSlideSize', (e) => {
63
+ /* When using mobile layout for caption, hide the Info button since the caption is fixed
64
+ * at the bottom. */
65
+ if (this.captionPlugin.useMobileLayout()) {
66
+ document.querySelector('.pswp__button--info').style.display = 'none';
67
+ } else {
68
+ document.querySelector('.pswp__button--info').style.display = '';
69
+ }
70
+ });
71
+ }
72
+
73
+ // Open gallery at the given slide index (starting at 0)
74
+ open(index) {
75
+ this.lightbox.init();
76
+ this.lightbox.loadAndOpen(index);
77
+ }
78
+
79
+ // Switch between regular caption (below image) and info pannel (aside)
80
+ _toggleInfoPannel(ev, el, pswp) {
81
+ if (this.captionPlugin.options.type === 'below') {
82
+ this.captionPlugin.options.type = 'aside';
83
+ } else if (this.captionPlugin.options.type === 'aside') {
84
+ this.captionPlugin.options.type = 'below';
85
+ }
86
+ /* Force updating size of all PhotoSwipe elements. This will trigger the 'calcSlideSize' event
87
+ * on each loaded slide, causing update of the caption text (see handler above). */
88
+ this.lightbox.pswp.updateSize(true);
89
+ }
90
+
91
+ _convertDate(iso8601_date) {
92
+ const d = new Date(iso8601_date);
93
+ const str = d.toLocaleDateString() + ' ' + d.toLocaleTimeString().replace(/(\d{2}):(\d{2}):(\d{2})/, '$1h$2');
94
+ return str;
95
+ }
96
+
97
+ // Get caption content, according to current image & caption layout
98
+ _captionContent(slide) {
99
+ const slideTitle = slide.data.title;
100
+ const slideDateTime = this._convertDate(slide.data.datetime, true);
101
+
102
+ if (this.captionPlugin.options.type === 'aside' && !this.captionPlugin.useMobileLayout()) {
103
+ var caption = '<strong>' + slideTitle + '</strong><hr />' +
104
+ '<p class="pswp__caption__exif pswp__caption__exif_datetime">' + slideDateTime + '</p>';
105
+ if (slide.data.artist) {
106
+ caption += '<p class="pswp__caption__exif pswp__caption__exif_author">' + slide.data.artist + '</p>';
107
+ }
108
+ if (slide.data.event) {
109
+ caption += '<p class="pswp__caption__exif pswp__caption__exif_event">' + slide.data.event + '</p>';
110
+ }
111
+ if (slide.data.city || slide.data.region) {
112
+ caption += '<p class="pswp__caption__exif pswp__caption__exif_location">';
113
+ if (slide.data.city) { caption += slide.data.city; }
114
+ if (slide.data.city && slide.data.region) { caption += ', '; }
115
+ if (slide.data.region) { caption += slide.data.region; }
116
+ caption += '</p>';
117
+ }
118
+ if (slide.data.model) {
119
+ caption += '<p class="pswp__caption__exif pswp__caption__exif_camera">' + slide.data.model + '</p>';
120
+ }
121
+ if (slide.data.focallength) {
122
+ caption += '<p class="pswp__caption__exif pswp__caption__exif_focal">' + slide.data.focallength + '</p>';
123
+ }
124
+ if (slide.data.fnumber) {
125
+ caption += '<p class="pswp__caption__exif pswp__caption__exif_fstop">' + slide.data.fnumber + '</p>';
126
+ }
127
+ if (slide.data.exposure) {
128
+ caption += '<p class="pswp__caption__exif pswp__caption__exif_shutter">' + slide.data.exposure + '</p>';
129
+ }
130
+ if (slide.data.isospeed) {
131
+ caption += '<p class="pswp__caption__exif pswp__caption__exif_iso">' + 'ISO ' + slide.data.isospeed + '</p>';
132
+ }
133
+ return caption;
134
+ } else {
135
+ return '<strong>' + slideDateTime + '</strong> &mdash; ' + slideTitle;
136
+ }
137
+ }
19
138
  }
20
139
 
21
140
  function createImageGallery(json) {
22
141
  var items = [];
23
142
  for (let i = 0; i < json.length; i++) {
24
- const imageUrl = 'api/picture?id=' + json[i].id;
25
- const imageTitle = '<strong>' + convertDate(json[i].datetime, true) + '</strong> &mdash; ' + json[i].title;
26
- items.push({ src: imageUrl, width: json[i].width, height: json[i].height, title: imageTitle});
143
+ var imageData = json[i];
144
+ imageData.src = 'api/picture?id=' + json[i].id; // Add 'src' field required by PhotoSwipe
145
+ items.push(imageData);
27
146
  }
28
147
 
29
- // Create PhotoSwipe Lightbox
30
- const lightboxOptions = {
31
- dataSource: items,
32
- pswpModule: PhotoSwipe,
33
- bgOpacity: 0.95,
34
- closeOnVerticalDrag: false,
35
- closeTitle: i18n.viewer_close + ' (Esc)',
36
- zoomTitle: i18n.viewer_zoom + ' (z)',
37
- arrowPrevTitle: i18n.viewer_previous,
38
- arrowNextTitle: i18n.viewer_next,
39
- };
40
- const lightbox = new PhotoSwipeLightbox(lightboxOptions);
41
-
42
- // Initialize caption plugin
43
- const captionPluginOptions = {
44
- type: 'below',
45
- captionContent: (slide) => { return slide.data.title || ''; }
46
- };
47
- const captionPlugin = new PhotoSwipeDynamicCaption(lightbox, captionPluginOptions);
48
-
49
- // Open gallery
50
- lightbox.init();
51
- lightbox.loadAndOpen(0); // start at first slide
148
+ const gallery = new PhotoSwipePictureGallery(items);
149
+ gallery.open(0); // start at first slide
52
150
  }
53
151
 
54
152
  // Export this function so that it may be called from HTML
@@ -39,9 +39,14 @@
39
39
 
40
40
  .pswp__dynamic-caption--mobile {
41
41
  width: 100%;
42
- top: auto;
43
- right: 0;
44
- bottom: 0;
45
42
  background: rgba(0,0,0,0.5);
46
43
  padding: 10px 15px;
44
+
45
+ right: 0;
46
+ bottom: 0;
47
+
48
+ /* override styles that were set via JS.
49
+ as they interfere with size measurement */
50
+ top: auto !important;
51
+ left: 0 !important;
47
52
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * PhotoSwipe Dynamic Caption plugin v1.1.0
2
+ * PhotoSwipe Dynamic Caption plugin v1.2.7
3
3
  * https://github.com/dimsemenov/photoswipe-dynamic-caption-plugin
4
4
  *
5
5
  * By https://dimsemenov.com
@@ -11,6 +11,7 @@ const defaultOptions = {
11
11
  horizontalEdgeThreshold: 20,
12
12
  mobileCaptionOverlapRatio: 0.3,
13
13
  mobileLayoutBreakpoint: 600,
14
+ verticallyCenterImage: false
14
15
  };
15
16
 
16
17
  class PhotoSwipeDynamicCaption {
@@ -23,28 +24,8 @@ class PhotoSwipeDynamicCaption {
23
24
  this.lightbox = lightbox;
24
25
 
25
26
  this.lightbox.on('init', () => {
26
- this.initPlugin();
27
- });
28
- }
29
-
30
- initPlugin() {
31
- this.pswp = this.lightbox.pswp;
32
- this.isCaptionHidden = false;
33
- this.tempCaption = false;
34
- this.captionElement = false;
35
-
36
- this.pswp.on('uiRegister', () => {
37
- this.pswp.ui.registerElement({
38
- name: 'dynamic-caption',
39
- order: 9,
40
- isButton: false,
41
- appendTo: 'root',
42
- html: '',
43
- onInit: (el) => {
44
- this.captionElement = el;
45
- this.initCaption();
46
- }
47
- });
27
+ this.pswp = this.lightbox.pswp;
28
+ this.initCaption();
48
29
  });
49
30
  }
50
31
 
@@ -52,51 +33,72 @@ class PhotoSwipeDynamicCaption {
52
33
  const { pswp } = this;
53
34
 
54
35
  pswp.on('change', () => {
55
- this.updateCaptionHTML();
56
- this.updateCurrentCaptionPosition();
57
-
58
36
  // make sure caption is displayed after slides are switched
59
- this.showCaption();
37
+ this.showCaption(this.pswp.currSlide);
60
38
  });
61
39
 
62
40
  pswp.on('calcSlideSize', (e) => this.onCalcSlideSize(e));
63
41
 
64
- // hide caption if mainscroll is shifted (dragging)
65
- pswp.on('moveMainScroll', () => {
66
- if (!this.useMobileLayout()) {
67
- if (this.pswp.mainScroll.isShifted()) {
68
- this.hideCaption();
69
- } else {
70
- this.showCaption();
42
+ pswp.on('slideDestroy', (e) => {
43
+ if (e.slide.dynamicCaption) {
44
+ if (e.slide.dynamicCaption.element) {
45
+ e.slide.dynamicCaption.element.remove();
71
46
  }
47
+ delete e.slide.dynamicCaption;
72
48
  }
73
49
  });
74
50
 
75
51
  // hide caption if zoomed
76
- pswp.on('zoomPanUpdate', () => {
77
- if (pswp.currSlide.currZoomLevel > pswp.currSlide.zoomLevels.initial) {
78
- this.hideCaption();
79
- } else {
80
- this.showCaption();
52
+ pswp.on('zoomPanUpdate', ({ slide }) => {
53
+ if (pswp.opener.isOpen && slide.dynamicCaption) {
54
+ if (slide.currZoomLevel > slide.zoomLevels.initial) {
55
+ this.hideCaption(slide);
56
+ } else {
57
+ this.showCaption(slide);
58
+ }
59
+
60
+ // move caption on vertical drag
61
+ if (slide.dynamicCaption.element) {
62
+ let captionYOffset = 0;
63
+ if (slide.currZoomLevel <= slide.zoomLevels.initial) {
64
+ const shiftedAmount = slide.pan.y - slide.bounds.center.y;
65
+ if (Math.abs(shiftedAmount) > 1) {
66
+ captionYOffset = shiftedAmount;
67
+ }
68
+ }
69
+
70
+ this.setCaptionYOffset(slide.dynamicCaption.element, captionYOffset);
71
+ }
72
+
73
+ this.adjustPanArea(slide, slide.currZoomLevel);
81
74
  }
82
75
  });
83
76
 
84
77
  pswp.on('beforeZoomTo', (e) => {
85
- const { currSlide } = pswp;
78
+ this.adjustPanArea(pswp.currSlide, e.destZoomLevel);
79
+ });
86
80
 
87
- if (currSlide.__dcAdjustedPanAreaSize) {
88
- if (e.destZoomLevel > currSlide.zoomLevels.initial) {
89
- currSlide.panAreaSize.x = currSlide.__dcOriginalPanAreaSize.x;
90
- currSlide.panAreaSize.y = currSlide.__dcOriginalPanAreaSize.y;
91
- } else {
92
- // Restore panAreaSize after we zoom back to initial position
93
- currSlide.panAreaSize.x = currSlide.__dcAdjustedPanAreaSize.x;
94
- currSlide.panAreaSize.y = currSlide.__dcAdjustedPanAreaSize.y;
95
- }
81
+ // Stop default action of tap when tapping on the caption
82
+ pswp.on('tapAction', (e) => {
83
+ if (e.originalEvent.target.closest('.pswp__dynamic-caption')) {
84
+ e.preventDefault();
96
85
  }
97
86
  });
98
87
  }
99
88
 
89
+ adjustPanArea(slide, zoomLevel) {
90
+ if (slide.dynamicCaption && slide.dynamicCaption.adjustedPanAreaSize) {
91
+ if (zoomLevel > slide.zoomLevels.initial) {
92
+ slide.panAreaSize.x = slide.dynamicCaption.originalPanAreaSize.x;
93
+ slide.panAreaSize.y = slide.dynamicCaption.originalPanAreaSize.y;
94
+ } else {
95
+ // Restore panAreaSize after we zoom back to initial position
96
+ slide.panAreaSize.x = slide.dynamicCaption.adjustedPanAreaSize.x;
97
+ slide.panAreaSize.y = slide.dynamicCaption.adjustedPanAreaSize.y;
98
+ }
99
+ }
100
+ }
101
+
100
102
  useMobileLayout() {
101
103
  const { mobileLayoutBreakpoint } = this.options;
102
104
 
@@ -111,43 +113,59 @@ class PhotoSwipeDynamicCaption {
111
113
  return false;
112
114
  }
113
115
 
114
- hideCaption() {
115
- if (!this.isCaptionHidden) {
116
- this.isCaptionHidden = true;
117
- this.captionElement.classList.add('pswp__dynamic-caption--faded');
116
+ hideCaption(slide) {
117
+ if (slide.dynamicCaption && !slide.dynamicCaption.hidden) {
118
+ const captionElement = slide.dynamicCaption.element;
119
+
120
+ if (!captionElement) {
121
+ return;
122
+ }
123
+
124
+ slide.dynamicCaption.hidden = true;
125
+ captionElement.classList.add('pswp__dynamic-caption--faded');
118
126
 
119
127
  // Disable caption visibility with the delay, so it's not interactable
120
- if (this.captionFadeTimeout) {
121
- clearTimeout(this.captionFadeTimeout);
128
+ if (slide.captionFadeTimeout) {
129
+ clearTimeout(slide.captionFadeTimeout);
122
130
  }
123
- this.captionFadeTimeout = setTimeout(() => {
124
- this.captionElement.style.visibility = 'hidden';
125
- this.captionFadeTimeout = null;
131
+ slide.captionFadeTimeout = setTimeout(() => {
132
+ captionElement.style.visibility = 'hidden';
133
+ delete slide.captionFadeTimeout;
126
134
  }, 400);
127
135
  }
128
136
  }
129
137
 
130
- showCaption() {
131
- if (this.isCaptionHidden) {
132
- this.isCaptionHidden = false;
133
- this.captionElement.style.visibility = 'visible';
138
+ setCaptionYOffset(el, y) {
139
+ el.style.transform = `translateY(${y}px)`;
140
+ }
141
+
142
+ showCaption(slide) {
143
+ if (slide.dynamicCaption && slide.dynamicCaption.hidden) {
144
+ const captionElement = slide.dynamicCaption.element;
145
+
146
+ if (!captionElement) {
147
+ return;
148
+ }
149
+
150
+ slide.dynamicCaption.hidden = false;
151
+ captionElement.style.visibility = 'visible';
134
152
 
135
- clearTimeout(this.captionFadeTimeout);
136
- this.captionFadeTimeout = setTimeout(() => {
137
- this.captionElement.classList.remove('pswp__dynamic-caption--faded');
138
- this.captionFadeTimeout = null;
153
+ clearTimeout(slide.captionFadeTimeout);
154
+ slide.captionFadeTimeout = setTimeout(() => {
155
+ captionElement.classList.remove('pswp__dynamic-caption--faded');
156
+ delete slide.captionFadeTimeout;;
139
157
  }, 50);
140
158
  }
141
159
  }
142
160
 
143
- setCaptionPosition(x, y) {
161
+ setCaptionPosition(captionEl, x, y) {
144
162
  const isOnHorizontalEdge = (x <= this.options.horizontalEdgeThreshold);
145
- this.captionElement.classList[
163
+ captionEl.classList[
146
164
  isOnHorizontalEdge ? 'add' : 'remove'
147
165
  ]('pswp__dynamic-caption--on-hor-edge');
148
166
 
149
- this.captionElement.style.left = x + 'px';
150
- this.captionElement.style.top = y + 'px';
167
+ captionEl.style.left = x + 'px';
168
+ captionEl.style.top = y + 'px';
151
169
  }
152
170
 
153
171
  setCaptionWidth(captionEl, width) {
@@ -167,67 +185,84 @@ class PhotoSwipeDynamicCaption {
167
185
  }
168
186
  }
169
187
 
170
- updateCurrentCaptionPosition() {
171
- const slide = this.pswp.currSlide;
172
-
173
- if (!slide.dynamicCaptionType) {
188
+ updateCaptionPosition(slide) {
189
+ if (!slide.dynamicCaption || !slide.dynamicCaption.type || !slide.dynamicCaption.element) {
174
190
  return;
175
191
  }
176
192
 
177
- if (slide.dynamicCaptionType === 'mobile') {
178
- this.setCaptionType(this.captionElement, slide.dynamicCaptionType);
193
+ if (slide.dynamicCaption.type === 'mobile') {
194
+ this.setCaptionType(
195
+ slide.dynamicCaption.element,
196
+ slide.dynamicCaption.type
197
+ );
179
198
 
180
- this.captionElement.style.removeProperty('left');
181
- this.captionElement.style.removeProperty('top');
182
- this.setCaptionWidth(this.captionElement, false);
199
+ slide.dynamicCaption.element.style.removeProperty('left');
200
+ slide.dynamicCaption.element.style.removeProperty('top');
201
+ this.setCaptionWidth(slide.dynamicCaption.element, false);
183
202
  return;
184
203
  }
185
204
 
186
205
  const zoomLevel = slide.zoomLevels.initial;
187
206
  const imageWidth = Math.ceil(slide.width * zoomLevel);
188
207
  const imageHeight = Math.ceil(slide.height * zoomLevel);
189
-
190
208
 
191
- this.setCaptionType(this.captionElement, slide.dynamicCaptionType);
192
- if (slide.dynamicCaptionType === 'aside') {
209
+ this.setCaptionType(slide.dynamicCaption.element, slide.dynamicCaption.type);
210
+ if (slide.dynamicCaption.type === 'aside') {
193
211
  this.setCaptionPosition(
194
- this.pswp.currSlide.bounds.center.x + imageWidth,
195
- this.pswp.currSlide.bounds.center.y
212
+ slide.dynamicCaption.element,
213
+ slide.bounds.center.x + imageWidth,
214
+ slide.bounds.center.y
196
215
  );
197
- this.setCaptionWidth(this.captionElement, false);
198
- } else if (slide.dynamicCaptionType === 'below') {
216
+ this.setCaptionWidth(slide.dynamicCaption.element, false);
217
+ } else if (slide.dynamicCaption.type === 'below') {
199
218
  this.setCaptionPosition(
200
- this.pswp.currSlide.bounds.center.x,
201
- this.pswp.currSlide.bounds.center.y + imageHeight
219
+ slide.dynamicCaption.element,
220
+ slide.bounds.center.x,
221
+ slide.bounds.center.y + imageHeight
202
222
  );
203
- this.setCaptionWidth(this.captionElement, imageWidth);
223
+ this.setCaptionWidth(slide.dynamicCaption.element, imageWidth);
204
224
  }
205
225
  }
206
226
 
207
- /**
208
- * Temporary caption is used to measure size for the current/next/previous captions,
209
- * (it has visibility:hidden)
210
- */
211
- createTemporaryCaption() {
212
- this.tempCaption = document.createElement('div');
213
- this.tempCaption.className = 'pswp__dynamic-caption pswp__dynamic-caption--temp';
214
- this.tempCaption.style.visibility = 'hidden';
215
- this.tempCaption.setAttribute('aria-hidden', 'true');
216
- // move caption element, so it's after BG,
217
- // so that other controls can freely overlap it
218
- this.pswp.bg.after(this.captionElement);
219
- this.captionElement.after(this.tempCaption);
220
- }
221
-
222
227
  onCalcSlideSize(e) {
223
228
  const { slide } = e;
224
-
225
- const captionHTML = this.getCaptionHTML(e.slide);
226
- let useMobileVersion = false;
227
229
  let captionSize;
230
+ let useMobileVersion;
231
+
232
+ if (!slide.dynamicCaption) {
233
+ slide.dynamicCaption = {
234
+ element: undefined,
235
+ type: false,
236
+ hidden: false
237
+ };
238
+ } // INTRANET-CHANGE: even if the slide already has a caption, reevaluate its content
239
+
240
+ const captionHTML = this.getCaptionHTML(slide);
228
241
 
229
242
  if (!captionHTML) {
230
- slide.dynamicCaptionType = false;
243
+ return;
244
+ }
245
+
246
+ // INTRANET-CHANGE: remove previous element from DOM, if required
247
+ if (e.slide.dynamicCaption.element) {
248
+ if (captionHTML != slide.dynamicCaption.element.innerHTML) {
249
+ e.slide.dynamicCaption.element.remove();
250
+ }
251
+ }
252
+
253
+ slide.dynamicCaption.element = document.createElement('div');
254
+ slide.dynamicCaption.element.className = 'pswp__dynamic-caption pswp__hide-on-close';
255
+ slide.dynamicCaption.element.innerHTML = captionHTML;
256
+
257
+ this.pswp.dispatch('dynamicCaptionUpdateHTML', {
258
+ captionElement: slide.dynamicCaption.element,
259
+ slide
260
+ });
261
+
262
+ slide.holderElement.appendChild(slide.dynamicCaption.element);
263
+ //}
264
+
265
+ if (!slide.dynamicCaption.element) {
231
266
  return;
232
267
  }
233
268
 
@@ -236,33 +271,32 @@ class PhotoSwipeDynamicCaption {
236
271
  slide.bounds.update(slide.zoomLevels.initial);
237
272
 
238
273
  if (this.useMobileLayout()) {
239
- slide.dynamicCaptionType = 'mobile';
274
+ slide.dynamicCaption.type = 'mobile';
240
275
  useMobileVersion = true;
241
276
  } else {
242
277
  if (this.options.type === 'auto') {
243
278
  if (slide.bounds.center.x > slide.bounds.center.y) {
244
- slide.dynamicCaptionType = 'aside';
279
+ slide.dynamicCaption.type = 'aside';
245
280
  } else {
246
- slide.dynamicCaptionType = 'below';
281
+ slide.dynamicCaption.type = 'below';
247
282
  }
248
283
  } else {
249
- slide.dynamicCaptionType = this.options.type;
284
+ slide.dynamicCaption.type = this.options.type;
250
285
  }
251
286
  }
252
287
 
253
288
  const imageWidth = Math.ceil(slide.width * slide.zoomLevels.initial);
254
289
  const imageHeight = Math.ceil(slide.height * slide.zoomLevels.initial);
255
290
 
256
- if (!this.tempCaption) {
257
- this.createTemporaryCaption();
258
- }
291
+ this.setCaptionType(
292
+ slide.dynamicCaption.element,
293
+ slide.dynamicCaption.type
294
+ );
259
295
 
260
- this.setCaptionType(this.tempCaption, slide.dynamicCaptionType);
296
+ if (slide.dynamicCaption.type === 'aside') {
297
+ this.setCaptionWidth(slide.dynamicCaption.element, false);
298
+ captionSize = this.measureCaptionSize(slide.dynamicCaption.element, e.slide);
261
299
 
262
- if (slide.dynamicCaptionType === 'aside') {
263
- this.tempCaption.innerHTML = this.getCaptionHTML(e.slide);
264
- this.setCaptionWidth(this.tempCaption, false);
265
- captionSize = this.measureCaptionSize(this.tempCaption, e.slide);
266
300
  const captionWidth = captionSize.x;
267
301
 
268
302
  const horizontalEnding = imageWidth + slide.bounds.center.x;
@@ -274,60 +308,53 @@ class PhotoSwipeDynamicCaption {
274
308
  } else {
275
309
  // do nothing, caption will fit aside without any adjustments
276
310
  }
277
- } else if (slide.dynamicCaptionType === 'below' || useMobileVersion) {
311
+ } else if (slide.dynamicCaption.type === 'below' || useMobileVersion) {
278
312
  this.setCaptionWidth(
279
- this.tempCaption,
313
+ slide.dynamicCaption.element,
280
314
  useMobileVersion ? this.pswp.viewportSize.x : imageWidth
281
315
  );
282
- this.tempCaption.innerHTML = this.getCaptionHTML(e.slide);
283
- captionSize = this.measureCaptionSize(this.tempCaption, e.slide);
316
+
317
+ captionSize = this.measureCaptionSize(slide.dynamicCaption.element, e.slide);
284
318
  const captionHeight = captionSize.y;
285
319
 
320
+ if (this.options.verticallyCenterImage) {
321
+ slide.panAreaSize.y -= captionHeight;
322
+ this.recalculateZoomLevelAndBounds(slide);
323
+ } else {
324
+ // Lift up the image only by caption height
286
325
 
287
- // vertical ending of the image
288
- const verticalEnding = imageHeight + slide.bounds.center.y;
326
+ // vertical ending of the image
327
+ const verticalEnding = imageHeight + slide.bounds.center.y;
289
328
 
290
- // height between bottom of the screen and ending of the image
291
- // (before any adjustments applied)
292
- const verticalLeftover = slide.panAreaSize.y - verticalEnding;
293
- const initialPanAreaHeight = slide.panAreaSize.y;
329
+ // height between bottom of the screen and ending of the image
330
+ // (before any adjustments applied)
331
+ const verticalLeftover = slide.panAreaSize.y - verticalEnding;
332
+ const initialPanAreaHeight = slide.panAreaSize.y;
294
333
 
295
- if (verticalLeftover <= captionHeight) {
296
- // lift up the image to give more space for caption
297
- slide.panAreaSize.y -= Math.min((captionHeight - verticalLeftover) * 2, captionHeight);
334
+ if (verticalLeftover <= captionHeight) {
335
+ // lift up the image to give more space for caption
336
+ slide.panAreaSize.y -= Math.min((captionHeight - verticalLeftover) * 2, captionHeight);
298
337
 
299
- // we reduce viewport size, thus we need to update zoom level and pan bounds
300
- this.recalculateZoomLevelAndBounds(slide);
338
+ // we reduce viewport size, thus we need to update zoom level and pan bounds
339
+ this.recalculateZoomLevelAndBounds(slide);
301
340
 
302
- const maxPositionX = slide.panAreaSize.x * this.options.mobileCaptionOverlapRatio / 2;
341
+ const maxPositionX = slide.panAreaSize.x * this.options.mobileCaptionOverlapRatio / 2;
303
342
 
304
- // Do not reduce viewport height if too few space available
305
- if (useMobileVersion
306
- && slide.bounds.center.x > maxPositionX) {
307
- // Restore the default position
308
- slide.panAreaSize.y = initialPanAreaHeight;
309
- this.recalculateZoomLevelAndBounds(slide);
343
+ // Do not reduce viewport height if too few space available
344
+ if (useMobileVersion
345
+ && slide.bounds.center.x > maxPositionX) {
346
+ // Restore the default position
347
+ slide.panAreaSize.y = initialPanAreaHeight;
348
+ this.recalculateZoomLevelAndBounds(slide);
349
+ }
310
350
  }
311
351
  }
312
-
313
-
314
-
315
- // if (this.useMobileLayout && slide.bounds.center.x > 100) {
316
- // // do nothing, caption will overlap the bottom part of the image
317
- // } else if (verticalLeftover <= captionHeight) {
318
-
319
- // } else {
320
- // // do nothing, caption will fit below the image without any adjustments
321
- // }
322
352
  } else {
323
353
  // mobile
324
354
  }
325
355
 
326
356
  this.storeAdjustedPanAreaSize(slide);
327
-
328
- if (slide === this.pswp.currSlide) {
329
- this.updateCurrentCaptionPosition();
330
- }
357
+ this.updateCaptionPosition(slide);
331
358
  }
332
359
 
333
360
  measureCaptionSize(captionEl, slide) {
@@ -349,19 +376,23 @@ class PhotoSwipeDynamicCaption {
349
376
  }
350
377
 
351
378
  storeAdjustedPanAreaSize(slide) {
352
- if (!slide.__dcAdjustedPanAreaSize) {
353
- slide.__dcAdjustedPanAreaSize = {};
379
+ if (slide.dynamicCaption) {
380
+ if (!slide.dynamicCaption.adjustedPanAreaSize) {
381
+ slide.dynamicCaption.adjustedPanAreaSize = {};
382
+ }
383
+ slide.dynamicCaption.adjustedPanAreaSize.x = slide.panAreaSize.x;
384
+ slide.dynamicCaption.adjustedPanAreaSize.y = slide.panAreaSize.y;
354
385
  }
355
- slide.__dcAdjustedPanAreaSize.x = slide.panAreaSize.x;
356
- slide.__dcAdjustedPanAreaSize.y = slide.panAreaSize.y;
357
386
  }
358
387
 
359
388
  storeOriginalPanAreaSize(slide) {
360
- if (!slide.__dcOriginalPanAreaSize) {
361
- slide.__dcOriginalPanAreaSize = {};
389
+ if (slide.dynamicCaption) {
390
+ if (!slide.dynamicCaption.originalPanAreaSize) {
391
+ slide.dynamicCaption.originalPanAreaSize = {};
392
+ }
393
+ slide.dynamicCaption.originalPanAreaSize.x = slide.panAreaSize.x;
394
+ slide.dynamicCaption.originalPanAreaSize.y = slide.panAreaSize.y;
362
395
  }
363
- slide.__dcOriginalPanAreaSize.x = slide.panAreaSize.x;
364
- slide.__dcOriginalPanAreaSize.y = slide.panAreaSize.y;
365
396
  }
366
397
 
367
398
  getCaptionHTML(slide) {
@@ -386,15 +417,6 @@ class PhotoSwipeDynamicCaption {
386
417
  }
387
418
  return captionHTML;
388
419
  }
389
-
390
- updateCaptionHTML() {
391
- const captionHTML = this.getCaptionHTML(this.pswp.currSlide);
392
- this.captionElement.style.visibility = captionHTML ? 'visible' : 'hidden';
393
- this.captionElement.innerHTML = captionHTML || '';
394
- this.pswp.dispatch('dynamicCaptionUpdateHTML', {
395
- captionElement: this.captionElement
396
- });
397
- }
398
420
  }
399
421
 
400
422
  export default PhotoSwipeDynamicCaption;
@@ -22,6 +22,13 @@ ul.groups {
22
22
  ul.groups.wide {
23
23
  grid-template-columns: repeat(2, 1fr);
24
24
  }
25
+
26
+ /* Small screens only */
27
+ @media only screen and (max-width: 1023px), only screen and (max-device-width: 1023px) {
28
+ ul.groups { grid-template-columns: repeat(2, 1fr); }
29
+ ul.groups.wide { grid-template-columns: repeat(1, 1fr); }
30
+ }
31
+
25
32
  ul.groups li {
26
33
  display: block;
27
34
  width: 100%;
@@ -34,19 +41,11 @@ ul.groups li {
34
41
  border-radius: 3px;
35
42
  justify-self: center;
36
43
  }
37
- ul.groups a {
38
- color: black;
39
- }
40
-
41
- /* Small screens only */
42
- @media only screen and (max-width: 1023px), only screen and (max-device-width: 1023px) {
43
- ul.groups { grid-template-columns: repeat(2, 1fr); }
44
- ul.groups.wide { grid-template-columns: repeat(1, 1fr); }
45
- }
46
44
 
47
45
  ul.groups li a {
48
46
  display: block;
49
47
  height: 100%;
48
+ color: black;
50
49
  }
51
50
  ul.groups li figure {
52
51
  margin: 0px;
@@ -87,5 +86,62 @@ ul.groups li:hover, ul.groups li:focus {
87
86
 
88
87
  .pswp .pswp__dynamic-caption--below {
89
88
  max-width: 800px;
90
- padding: 10px 20px 10px;
89
+ padding: 10px 20px; /* top/bottom sides */
90
+ }
91
+
92
+ .pswp .pswp__dynamic-caption--aside {
93
+ max-width: 400px;
94
+ width: 400px;
95
+ text-align: justify;
96
+ padding: 10px 20px; /* top/bottom sides */
97
+ }
98
+
99
+ .pswp .pswp__dynamic-caption--aside hr {
100
+ margin: 8px 0px; /* top/bottom sides */
101
+ background: rgba(255, 255, 255, 0.7);
102
+ height: 1px;
103
+ }
104
+
105
+ .pswp .pswp__caption__exif {
106
+ padding: .25em 0 .25em 2.5em; /* top right bottom left */
107
+ margin: .125em 0; /* top/bottom sides */
108
+ background-position: .5em center;
109
+ background-repeat: no-repeat;
110
+ background-size: 20px 20px;
111
+ }
112
+
113
+ .pswp .pswp__caption__exif_datetime {
114
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgaGVpZ2h0PSIxMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNjY2NjY2MiPjxwYXRoIGQ9Ik0xMzIuNSwxNjMuMVY0MC42YzAtMTYuOSwxMy43LTMwLjYsMzAuNi0zMC42czMwLjYsMTMuNywzMC42LDMwLjZ2MTIyLjVjMCwxNi45LTEzLjcsMzAuNi0zMC42LDMwLjZTMTMyLjUsMTgwLjEsMTMyLjUsMTYzLjF6IE02NTMuMSwxOTMuOGMxNi45LDAsMzAuNi0xMy43LDMwLjYtMzAuNlY0MC42YzAtMTYuOS0xMy43LTMwLjYtMzAuNi0zMC42cy0zMC42LDEzLjctMzAuNiwzMC42djEyMi41QzYyMi41LDE4MC4xLDYzNi4yLDE5My44LDY1My4xLDE5My44eiBNOTkwLDc0NWMwLDEzNS4zLTEwOS43LDI0NS0yNDUsMjQ1UzUwMCw4ODAuMyw1MDAsNzQ1czEwOS43LTI0NSwyNDUtMjQ1Uzk5MCw2MDkuNyw5OTAsNzQ1eiBNOTI4LjgsNzQ1YzAtMTAxLjMtODIuNC0xODMuOC0xODMuOC0xODMuOFM1NjEuMyw2NDMuNyw1NjEuMyw3NDVTNjQzLjcsOTI4LjgsNzQ1LDkyOC44UzkyOC44LDg0Ni4zLDkyOC44LDc0NXogTTI1NSwzNzcuNUgxMzIuNVY1MDBIMjU1VjM3Ny41eiBNMTMyLjUsNjgzLjhIMjU1VjU2MS4zSDEzMi41VjY4My44eiBNMzE2LjMsNTAwaDEyMi41VjM3Ny41SDMxNi4zVjUwMHogTTMxNi4zLDY4My44aDEyMi41VjU2MS4zSDMxNi4zVjY4My44eiBNNzEuMyw3MzguOVYzMTYuM0g3NDV2MTIyLjVoNjEuM1YxOTkuOWMwLTM3LjItMjkuNy02Ny40LTY2LjMtNjcuNGgtMjUuNXYzMC42YzAsMzMuNy0yNy41LDYxLjMtNjEuMyw2MS4zcy02MS4zLTI3LjUtNjEuMy02MS4zdi0zMC42SDIyNC40djMwLjZjMCwzMy43LTI3LjUsNjEuMy02MS4zLDYxLjNzLTYxLjMtMjcuNS02MS4zLTYxLjN2LTMwLjZINzYuNGMtMzYuNywwLTY2LjQsMzAuMS02Ni40LDY3LjR2NTM5YzAsMzcuMSwyOS43LDY3LjQsNjYuNCw2Ny40aDM2Mi40Vjc0NUg3Ni40QzczLjYsNzQ1LDcxLjMsNzQyLjEsNzEuMyw3MzguOXogTTYyMi41LDUwMFYzNzcuNUg1MDBWNTAwSDYyMi41eiBNODM2LjksNzQ1SDc0NXYtOTEuOWMwLTE2LjktMTMuNy0zMC42LTMwLjYtMzAuNnMtMzAuNiwxMy43LTMwLjYsMzAuNnYxMjIuNWMwLDE2LjksMTMuNywzMC42LDMwLjYsMzAuNmgxMjIuNWMxNi45LDAsMzAuNi0xMy43LDMwLjYtMzAuNlM4NTMuOCw3NDUsODM2LjksNzQ1eiIvPjwvc3ZnPgo=);
115
+ }
116
+
117
+ .pswp .pswp__caption__exif_author {
118
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0iI2NjY2NjYyI+PHBhdGggZD0iTTEwIDEyLjVjLTUuOTIgMC05IDMuNS05IDUuNXYxaDE4di0xYzAtMi0zLjA4LTUuNS05LTUuNXoiLz48Y2lyY2xlIGN4PSIxMCIgY3k9IjYiIHI9IjUiLz48L3N2Zz4K);
119
+ }
120
+
121
+ .pswp .pswp__caption__exif_event {
122
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgaGVpZ2h0PSIxMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNjY2NjY2MiPjxwYXRoIGQ9Ik0xNTUuMiwxMzdjMCwyNy4yLTEyLjEsNDgtMzYuMyw2Mi40djcxOGMwLDQuOS0xLjgsOS4yLTUuNCwxMi44cy03LjgsNS40LTEyLjgsNS40SDY0LjRjLTQuOSwwLTkuMi0xLjgtMTIuOC01LjRzLTUuNC03LjgtNS40LTEyLjh2LTcxOEMyMi4xLDE4NS4xLDEwLDE2NC4zLDEwLDEzN2MwLTIwLDcuMS0zNy4xLDIxLjMtNTEuM2MxNC4yLTE0LjIsMzEuMy0yMS4zLDUxLjMtMjEuM3MzNy4xLDcuMSw1MS4zLDIxLjNDMTQ4LjEsOTkuOSwxNTUuMiwxMTcsMTU1LjIsMTM3TDE1NS4yLDEzN3ogTTk5MCwxNzMuM3Y0MzIuN2MwLDkuNS0yLjQsMTYuNy03LjEsMjEuOGMtNC43LDUuMS0xMi4yLDEwLjMtMjIuNCwxNS42Yy04MS4zLDQzLjktMTUxLDY1LjgtMjA5LjMsNjUuOGMtMjMuMSwwLTQ2LjQtNC4yLTcwLTEyLjVjLTIzLjYtOC4zLTQ0LjEtMTcuNC02MS41LTI3LjJzLTM5LjItMTguOS02NS41LTI3LjJjLTI2LjMtOC4zLTUzLjItMTIuNS04MC44LTEyLjVjLTcyLjYsMC0xNjAuMywyNy42LTI2My4xLDgyLjhjLTYuNCwzLjQtMTIuNyw1LjEtMTguNyw1LjFjLTkuOCwwLTE4LjMtMy42LTI1LjUtMTAuOGMtNy4yLTcuMi0xMC44LTE1LjctMTAuOC0yNS41VjI2MC43YzAtMTIuMSw1LjktMjIuNSwxNy42LTMxLjJjNy45LTUuMywyMi45LTEzLjQsNDQuOC0yNC40Yzg5LjItNDUuNCwxNjguOC02OC4xLDIzOC44LTY4LjFjNDAuNSwwLDc4LjMsNS41LDExMy40LDE2LjRjMzUuMiwxMSw3Ni42LDI3LjYsMTI0LjIsNDkuOWMxNC40LDcuMiwzMSwxMC44LDQ5LjksMTAuOGMyMC40LDAsNDIuNi00LDY2LjYtMTEuOWMyNC03LjksNDQuOC0xNi44LDYyLjQtMjYuN2MxNy42LTkuOCwzNC4yLTE4LjcsNDkuOS0yNi43czI2LTExLjksMzAuOS0xMS45YzkuOCwwLDE4LjMsMy42LDI1LjUsMTAuOEM5ODYuNCwxNTUsOTkwLDE2My41LDk5MCwxNzMuM0w5OTAsMTczLjN6Ii8+PC9zdmc+Cg==);
123
+ }
124
+
125
+ .pswp .pswp__caption__exif_location {
126
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgaGVpZ2h0PSIxMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNjY2NjY2MiPjxwYXRoIGQ9Ik02MTAsNzU5LjRsLTE4LjksMzkuOWMxMDEuMywxMy4yLDE2Mi42LDQ2LjcsMTYyLjYsNzEuNGMwLDMxLjUtOTguOCw3Ny4zLTI1My43LDc3LjNjLTE1NC44LDAtMjUzLjYtNDUuOC0yNTMuNi03Ny4zYzAtMjkuMyw4NS4zLTcwLjcsMjIxLjYtNzYuNWwzMiw2Ni43bDIyMC00NTguMmgtMC4zYzIxLjctMzguNiwzNC4zLTgzLjIsMzQuMy0xMzAuOUM3NTMuOSwxMjcuMiw2NDAuMiwxMCw1MDAsMTBjLTE0MC4yLDAtMjUzLjksMTE3LjItMjUzLjksMjYxLjhjMCw0Ny43LDEyLjYsOTIuMywzNC4yLDEzMC45aC0wLjJsMTY4LjEsMzUwLjRjLTEyNy41LDguNS0yNDIuNyw0OC41LTI0Mi43LDExNy41QzIwNS41LDk0OSwzNTMuNyw5OTAsNTAwLDk5MGMxNDYuMywwLDI5NC41LTQxLDI5NC41LTExOS4zQzc5NC41LDgxMi40LDcxMi4zLDc3NC44LDYxMCw3NTkuNHogTTM5My40LDIzOS42YzAtNjAuNyw0Ny43LTExMCwxMDYuNi0xMTBjNTksMCwxMDYuNyw0OS4zLDEwNi43LDExMGMwLDYwLjctNDcuNywxMDkuOS0xMDYuNywxMDkuOUM0NDEuMSwzNDkuNSwzOTMuNCwzMDAuMywzOTMuNCwyMzkuNnoiLz48L3N2Zz4K);
127
+ }
128
+
129
+ .pswp .pswp__caption__exif_camera {
130
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjY2NjY2NjIiBkPSJNMTE1LjUsMjYuN0g5NC4zbC05LjEtOS41Yy0yLjEtMy44LTYuMi02LjEtMTAuNi02LjFINTMuOWMtNC40LDAtOC41LDIuNC0xMC42LDYuMWwtOS4yLDkuNUgxMi41ICAgYy02LjcsMC0xMi4yLDUuMy0xMi4yLDExLjlWMTA1YzAsNi42LDUuNCwxMS45LDEyLjIsMTEuOWgxMDIuOWM2LjcsMCwxMi4yLTUuMywxMi4yLTExLjlWMzguN0MxMjcuNiwzMi4xLDEyMi4yLDI2LjcsMTE1LjUsMjYuN3ogICAgTTY0LDEwMS4yYy0xNy42LDAtMzEuOS0xNC4zLTMxLjktMzEuOWMwLTE3LjYsMTQuMy0zMS45LDMxLjktMzEuOWMxNy42LDAsMzEuOSwxNC4zLDMxLjksMzEuOUM5NS44LDg3LDgxLjYsMTAxLjIsNjQsMTAxLjJ6ICAgIE02NCw0OC4xYy0xMS43LDAtMjEuMiw5LjUtMjEuMiwyMS4yYzAsMTEuNyw5LjUsMjEuMiwyMS4yLDIxLjJjMTEuNywwLDIxLjItOS41LDIxLjItMjEuMkM4NS4yLDU3LjYsNzUuNyw0OC4xLDY0LDQ4LjF6Ii8+PC9zdmc+Cg==);
131
+ }
132
+
133
+ .pswp .pswp__caption__exif_focal {
134
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjY2NjY2NjIiBkPSJNMTIgNi41YzMuNzkgMCA3LjE3IDIuMTMgOC44MiA1LjUtMS42NSAzLjM3LTUuMDIgNS41LTguODIgNS41UzQuODMgMTUuMzcgMy4xOCAxMkM0LjgzIDguNjMgOC4yMSA2LjUgMTIgNi41bTAtMkM3IDQuNSAyLjczIDcuNjEgMSAxMmMxLjczIDQuMzkgNiA3LjUgMTEgNy41czkuMjctMy4xMSAxMS03LjVjLTEuNzMtNC4zOS02LTcuNS0xMS03LjV6bTAgNWMxLjM4IDAgMi41IDEuMTIgMi41IDIuNXMtMS4xMiAyLjUtMi41IDIuNS0yLjUtMS4xMi0yLjUtMi41IDEuMTItMi41IDIuNS0yLjVtMC0yYy0yLjQ4IDAtNC41IDIuMDItNC41IDQuNXMyLjAyIDQuNSA0LjUgNC41IDQuNS0yLjAyIDQuNS00LjUtMi4wMi00LjUtNC41LTQuNXoiPjwvcGF0aD48L3N2Zz4K);
135
+ }
136
+
137
+ .pswp .pswp__caption__exif_fstop {
138
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjY2NjY2NjIiBkPSJNOS40IDEwLjVsNC43Ny04LjI2QzEzLjQ3IDIuMDkgMTIuNzUgMiAxMiAyYy0yLjQgMC00LjYuODUtNi4zMiAyLjI1bDMuNjYgNi4zNS4wNi0uMXpNMjEuNTQgOWMtLjkyLTIuOTItMy4xNS01LjI2LTYtNi4zNEwxMS44OCA5aDkuNjZ6bS4yNiAxaC03LjQ5bC4yOS41IDQuNzYgOC4yNUMyMSAxNi45NyAyMiAxNC42MSAyMiAxMmMwLS42OS0uMDctMS4zNS0uMi0yek04LjU0IDEybC0zLjktNi43NUMzLjAxIDcuMDMgMiA5LjM5IDIgMTJjMCAuNjkuMDcgMS4zNS4yIDJoNy40OWwtMS4xNS0yem0tNi4wOCAzYy45MiAyLjkyIDMuMTUgNS4yNiA2IDYuMzRMMTIuMTIgMTVIMi40NnptMTEuMjcgMGwtMy45IDYuNzZjLjcuMTUgMS40Mi4yNCAyLjE3LjI0IDIuNCAwIDQuNi0uODUgNi4zMi0yLjI1bC0zLjY2LTYuMzUtLjkzIDEuNnoiPjwvcGF0aD48L3N2Zz4=);
139
+ }
140
+
141
+ .pswp .pswp__caption__exif_shutter {
142
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjY2NjY2NjIiBkPSJNMTUgMUg5djJoNlYxem00LjAzIDYuMzlsMS40Mi0xLjQyYy0uNDMtLjUxLS45LS45OS0xLjQxLTEuNDFsLTEuNDIgMS40MkMxNi4wNyA0Ljc0IDE0LjEyIDQgMTIgNGMtNC45NyAwLTkgNC4wMy05IDlzNC4wMiA5IDkgOSA5LTQuMDMgOS05YzAtMi4xMi0uNzQtNC4wNy0xLjk3LTUuNjF6TTEyIDIwYy0zLjg3IDAtNy0zLjEzLTctN3MzLjEzLTcgNy03IDcgMy4xMyA3IDctMy4xMyA3LTcgN3ptLS4zMi01SDYuMzVjLjU3IDEuNjIgMS44MiAyLjkyIDMuNDEgMy41NmwtLjExLS4wNiAyLjAzLTMuNXptNS45Ny00Yy0uNTctMS42LTEuNzgtMi44OS0zLjM0LTMuNTRMMTIuMjYgMTFoNS4zOXptLTcuMDQgNy44M2MuNDUuMTEuOTEuMTcgMS4zOS4xNyAxLjM0IDAgMi41Ny0uNDUgMy41Ny0xLjE5bC0yLjExLTMuOS0yLjg1IDQuOTJ6TTcuNTUgOC45OUM2LjU5IDEwLjA1IDYgMTEuNDYgNiAxM2MwIC4zNC4wNC42Ny4wOSAxaDQuNzJMNy41NSA4Ljk5em04Ljc5IDguMTRDMTcuMzcgMTYuMDYgMTggMTQuNiAxOCAxM2MwLS4zNC0uMDQtLjY3LS4wOS0xaC00LjM0bDIuNzcgNS4xM3ptLTMuMDEtOS45OEMxMi45IDcuMDYgMTIuNDYgNyAxMiA3Yy0xLjQgMC0yLjY5LjQ5LTMuNzEgMS4yOWwyLjMyIDMuNTYgMi43Mi00Ljd6Ij48L3BhdGg+PC9zdmc+Cg==);
143
+ }
144
+
145
+ .pswp .pswp__caption__exif_iso {
146
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjY2NjY2NjIiBkPSJNMTkgM0g1Yy0xLjEgMC0yIC45LTIgMnYxNGMwIDEuMS45IDIgMiAyaDE0YzEuMSAwIDItLjkgMi0yVjVjMC0xLjEtLjktMi0yLTJ6TTUuNSA3LjVoMnYtMkg5djJoMlY5SDl2Mkg3LjVWOWgtMlY3LjV6TTE5IDE5SDVMMTkgNXYxNHptLTItMnYtMS41aC01VjE3aDV6Ij48L3BhdGg+PC9zdmc+Cg==);
91
147
  }
@@ -339,7 +339,8 @@ RSpec.describe Intranet::Pictures::Responder do
339
339
  " viewer_close: '#{I18n.t('pictures.viewer.close')}',\n" \
340
340
  " viewer_zoom: '#{I18n.t('pictures.viewer.zoom')}',\n" \
341
341
  " viewer_previous: '#{I18n.t('pictures.viewer.previous')}',\n" \
342
- " viewer_next: '#{I18n.t('pictures.viewer.next')}' };"
342
+ " viewer_next: '#{I18n.t('pictures.viewer.next')}',\n" \
343
+ " viewer_toggle_caption: '#{I18n.t('pictures.viewer.toggle_caption')}' };"
343
344
  )
344
345
  end
345
346
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intranet-pictures
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ebling Mis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-25 00:00:00.000000000 Z
11
+ date: 2023-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: intranet-core