PageSourceSearch

https://defence.indragroup.com/static/v1.0.519-160be22/blocks-js/Gallery.js

js indragroup.com collected 2026-09-24 17:39:59 UTC 4,808 bytes, 159 lines download raw bytes

1// Gallery.js
2function initGallery() {
3  const galleries = document.querySelectorAll('[data-js="gallery"]')
4
5  for (const gallery of galleries) {
6    const dialog = gallery.querySelector('#lightbox')
7    const lightboxImage = gallery.querySelector('#lightboxImage')
8    const lightboxClose = gallery.querySelector('#lightboxClose')
9
10    // Solo configura el lightbox si existen todos los elementos necesarios
11    if (dialog && lightboxImage && lightboxClose) {
12      for (const button of gallery.querySelectorAll(
13        '[data-js="gallery__image-button"]',
14      )) {
15        const img = button.querySelector('img')
16
17        const openModal = () => {
18          lightboxImage.src = img.src
19          dialog.showModal()
20        }
21
22        button.addEventListener('click', openModal)
23
24        button.addEventListener('keydown', (e) => {
25          if (e.key === 'Enter' || e.key === ' ') {
26            e.preventDefault()
27            openModal()
28          }
29        })
30      }
31
32      lightboxClose.addEventListener('click', () => {
33        dialog.close()
34        lightboxImage.src = ''
35      })
36
37      dialog.addEventListener('click', (e) => {
38        const lightboxFigure = dialog.querySelector('.lightbox-figure')
39        if (!lightboxFigure.contains(e.target)) {
40          dialog.close()
41          lightboxImage.src = ''
42        }
43      })
44    }
45
46    const carousel = gallery.querySelector('[data-js="gallery__carousel"]')
47
48    if (!carousel) {
49      return
50    }
51
52    const prevButton = gallery.querySelector('#prev')
53    const nextButton = gallery.querySelector('#next')
54    const controls =
55      gallery.querySelector('.section-title__controls') ||
56      gallery.querySelector('.article-gallery__controls')
57    const shouldShowControls = carousel.scrollWidth > carousel.clientWidth
58    if (shouldShowControls && controls) {
59      controls.style.display = 'grid'
60    }
61
62    function updateButtonState() {
63      const slides = carousel.querySelectorAll(
64        '[data-js="gallery__carousel-slide"]',
65      )
66      if (!slides.length) return
67
68      const firstSlide = slides[0]
69      const lastSlide = slides[slides.length - 1]
70
71      const carouselRect = carousel.getBoundingClientRect()
72      const firstRect = firstSlide.getBoundingClientRect()
73      const lastRect = lastSlide.getBoundingClientRect()
74
75      const isAtStart = firstRect.left >= carouselRect.left - 8
76      const isAtEnd = lastRect.right <= carouselRect.right + 8
77
78      prevButton.disabled = isAtStart
79      nextButton.disabled = isAtEnd
80    }
81
82    updateButtonState()
83    window.addEventListener('resize', () => {
84      const shouldShowControls = carousel.scrollWidth > carousel.clientWidth
85      const dynamicControls =
86        gallery.querySelector('.section-title__controls') ||
87        gallery.querySelector('.article-gallery__controls')
88      if (dynamicControls) {
89        dynamicControls.style.display = shouldShowControls ? 'grid' : 'none'
90      }
91      updateButtonState()
92    })
93
94    function scrollToSlide(direction) {
95      const slides = carousel.querySelectorAll(
96        '[data-js="gallery__carousel-slide"]',
97      )
98      if (!slides.length) return
99
100      let currentIndex = 0
101      let minDelta = Number.POSITIVE_INFINITY
102      for (let i = 0; i < slides.length; i++) {
103        const slide = slides[i]
104        const delta = Math.abs(slide.offsetLeft - carousel.scrollLeft)
105        if (delta < minDelta) {
106          minDelta = delta
107          currentIndex = i
108        }
109      }
110
111      let targetIndex = currentIndex + direction
112      if (targetIndex < 0) targetIndex = 0
113      if (targetIndex >= slides.length) targetIndex = slides.length - 1
114      const targetSlide = slides[targetIndex]
115      if (!targetSlide) return
116      let targetScrollLeft = targetSlide.offsetLeft
117
118      const isMobile = window.innerWidth <= 992
119      if (targetIndex === 0 && isMobile) {
120        targetScrollLeft = 0
121      }
122
123      carousel.scrollTo({ left: targetScrollLeft, behavior: 'smooth' })
124
125      function waitForScroll() {
126        if (Math.abs(carousel.scrollLeft - targetSlide.offsetLeft) < 2) {
127          updateButtonState()
128          return
129        }
130        requestAnimationFrame(waitForScroll)
131      }
132      requestAnimationFrame(waitForScroll)
133    }
134
135    prevButton.addEventListener('click', () => {
136      scrollToSlide(-1)
137    })
138    prevButton.addEventListener('keydown', (e) => {
139      if (e.key === 'Enter' || e.key === ' ') {
140        e.preventDefault()
141        scrollToSlide(-1)
142      }
143    })
144
145    nextButton.addEventListener('click', () => {
146      scrollToSlide(1)
147    })
148    nextButton.addEventListener('keydown', (e) => {
149      if (e.key === 'Enter' || e.key === ' ') {
150        e.preventDefault()
151        scrollToSlide(1)
152      }
153    })
154
155    carousel.addEventListener('scroll', updateButtonState)
156  }
157}
158
159initGallery()

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.