PageSourceSearch

https://www.sompio.fi/wp-content/themes/hilla-theme/assets/js/body/opener.js

js sompio.fi collected 2026-09-25 01:15:31 UTC 6,372 bytes, 222 lines download raw bytes

1/**
2 * How far beyond the currently displayed image to buffer.
3 *
4 * @type {number}
5 */
6const carouselBufferSize = 1;
7
8const properties = {
9  sizesBackup: 'originalSizes',
10  resizeFlag: 'hasEventToUpdateFullscreenOnResize',
11};
12
13const classes = {
14  opener: 'opener',
15  opened: 'opener-opened',
16  image: 'opener-image',
17  container: 'figure-img-container',
18  carousel: 'carousel',
19  item: 'carousel-item',
20  modal: 'modal-open',
21  activeItem: 'active',
22};
23
24const selectors = {
25  body:        'body',
26  opener:      '.' + classes.opener,
27  opened:      '.' + classes.opened,
28  image:       '.' + classes.image + ' img',
29  container:   '.' + classes.container,
30  carousel:    '.' + classes.carousel,
31  item:        '.' + classes.item,
32  buttonOpen:  '.' + classes.opener + ' .opener-button.opener-button-open, .' + classes.opener + ' .' + classes.image + ' img',
33  buttonClose: '.' + classes.opener + ' .opener-button.opener-button-close',
34};
35
36let $buttonOpen = $(selectors.buttonOpen);
37let $buttonClose = $(selectors.buttonClose);
38
39const $carousels = $(selectors.carousel);
40
41/**
42 * @param {jQuery} $container
43 */
44const findImage = function($container) {
45  return $container.find(selectors.image);
46};
47
48/**
49 * If `index` goes outside of the boundaries of 0 and `length`-1, loop it back in.
50 *
51 * @param {number} index
52 * @param {number} length
53 * @returns {number}
54 */
55const advanceInLoop = function (index, length) {
56  index = index % length;
57  return (index < 0) ? index + length : index
58};
59
60/**
61 * If image opener is part of a carousel, choose the carousel.
62 *
63 * @param {jQuery} $opener
64 * @returns {jQuery}
65 */
66const assignOpener = function($opener) {
67  const $carousel = $opener.closest(selectors.carousel);
68
69  return ($carousel.length > 0) ? $carousel : $opener;
70};
71
72/**
73 * Whether this element is the child of an opener that is opened.
74 *
75 * @param {jQuery} $el
76 * @returns {boolean}
77 */
78const isOpened = function($el) {
79  return ($el.closest(selectors.opened).length > 0);
80};
81
82/**
83 * Whether this element is the child of a carousel item that is inactive.
84 *
85 * @param {jQuery} $el
86 * @returns {boolean}
87 */
88const isInInactiveCarouselItem = function($el) {
89  const $item = $el.closest(selectors.item);
90
91  return ($item.length >
91 0) ? ! $item.hasClass(classes.activeItem) : false;
92};
93
94/**
95 * @param {jQuery} $canvas Element which the image is scaled to fit inside.
96 * @param {jQuery} $image The image to be scaled.
97 *
98 * @returns {number} Percentage of viewport width
99 */
100const getFullscreenImageWidth = function($canvas, $image) {
101  const
102    canvasRatio = $canvas.width() / $canvas.height(),
103    imageRatio = ($image.attr('width') > 0 && $image.attr('height') > 0)
104      ? $image.attr('width') / $image.attr('height')
105      : $image[0].naturalWidth / $image[0].naturalHeight,
106    canvasFractionOfViewport = $canvas.width() / $(window).width();
107
108  // Width as fraction of canvas width. If image is more portrait-sized than the canvas, take the height into consideration.
109  const maxWidth = (imageRatio < canvasRatio) ? imageRatio / canvasRatio : 1.0;
110
111  return maxWidth * canvasFractionOfViewport * 100;
112};
113
114/**
115 * @param {jQuery} $container
116 * @param {jQuery|undefined} $image The image to be scaled. If undefined, get image from $container instead.
117 */
118const applyFullscreenResolution = function ($container, $image = undefined) {
119  if ($image === undefined) {
120    $image = findImage($container);
121  }
122
123  // Backup original value before changing.
124  if ($image.data(properties.sizesBackup) === undefined) {
125    $image.data(properties.sizesBackup, $image.attr('sizes'));
126  }
127
128  const $canvas = $container.find(selectors.container);
129
130  $image.attr('sizes', getFullscreenImageWidth($canvas, $image).toFixed(2) + 'vw');
131
132  // Add event to update on resize. Only add once per image!
133  if ($image.data(properties.resizeFlag) === true) {
134    return;
135  }
136  $(window).resize({image: $image}, function(e) {
137    const $image = e.data.image;
138    if (isOpened($image) && !isInInactiveCarouselItem($image)) {
139      applyFullscreenResolution($image.closest(selectors.opener));
140    }
141  });
142  $image.data(properties.resizeFlag, true);
143};
144
145/**
146 * @param {jQuery} $container
147 */
148const removeFullscreenResolution = function ($container) {
149  const $image = findImage($container);
150
151  // Restore backup:ed value.
152  $image.attr('sizes', $image.data(properties.sizesBackup));
153  $image.data(properties.sizesBackup, undefined);
154};
155
156/**
157 * @param {Event} e
158 */
159const applyFullscreenOnCarouselSlide = function (e) {
160  if (!isOpened($(e.target))) {
161    return;
162  }
163
164  const $items = $(e.target).find(selectors.item);
165
166  /**
167   * 1 for sliding forward (right), -1 for sliding backward (left).
168   *
169   * @type {number}
170   */
171  const slideDirection = (e.from + 1 === e.to || (e.to === 0 && e.from !== 1)) ? 1 : -1;
172
173  for (let steps = 1; steps - 1 <= carouselBufferSize; steps++) {
174    const
175      currentIndex = e.from,
176      destinationIndex = advanceInLoop(currentIndex + (steps * slideDirection), $items.length),
177      $container = $items.eq(currentIndex),
178      $image = findImage($items.eq(destinationIndex));
179
180    /**
181     * $image may be an image currently off-screen, but $container needs to belong to the image currently on-screen.
182     * This is because the container of an off-screen image has no physical dimensions yet.
183     */
184    applyFullscreenResolution($container, $image);
185  }
186};
187
188// Image opener
189$(document).on("click", selectors.buttonOpen, function () {
190  $buttonOpen = $(selectors.buttonOpen);
191  $buttonClose = $(selectors.buttonClose);
192
193  const $opener = $(this).closest('.opener');
194
195  if ($opener.length > 0){
196    var disabledValue = $opener.attr("disabled");
197    if (disabledValue == "true" || disabledValue == "disabled") return;
198  }
199
200  $(selectors.body).addClass(classes.modal);
201  assignOpener($opener).addClass(classes.opened);
202  applyFullscreenResolution($opener);
203});
204
205$(document).on("click", selectors.buttonClose, function () {
206  $buttonOpen = $(selectors.buttonOpen);
207  $buttonClose = $(selectors.buttonClose);
208
209  const $opener = $(this).closest('.opener');
210
211  $(selectors.body).removeClass(classes.modal);
212  assignOpener($opener).removeClass(classes.opened);
213  removeFullscreenResolution($opener);
214});
215
216$(document).keydown(function (e) {
217  if (e.keyCode === 27) {
218    $buttonClose.click();
219  }
220});
221
222$carousels.on('slide.bs.carousel', applyFullscreenOnCarouselSlide);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.