intranet-pictures 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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