PageSourceSearch

https://www.bigibyte.com/assets/gallery.js

js bigibyte.com collected 2026-10-02 01:24:18 UTC 3,717 bytes, 88 lines download raw bytes

1// Lightbox for the About page "Our work in action" gallery.
2// Clicking a card opens the full photo; arrows, swipe and Esc work too.
3(function () {
4  var box, img, cap, list = [], idx = 0, lastFocus = null, startX = 0;
5
6  function cards() {
7    var seen = {}, out = [];
8    document.querySelectorAll('[data-ab-card][data-full]').forEach(function (c) {
9      var u = c.getAttribute('data-full');
10      if (seen[u]) return;
11      seen[u] = 1;
12      out.push({ src: u, title: c.getAttribute('data-title') || '', tag: c.getAttribute('data-tag') || '' });
13    });
14    return out;
15  }
16
17  function build() {
18    box = document.createElement('div');
19    box.className = 'ab-lb';
20    box.setAttribute('role', 'dialog');
21    box.setAttribute('aria-modal', 'true');
22    box.setAttribute('aria-label', 'Photo viewer');
23    box.innerHTML =
24      '<button type="button" class="ab-lb-x" aria-label="Close">&times;</button>' +
25      '<button type="button" class="ab-lb-nav ab-lb-prev" aria-label="Previous photo">&#8249;</button>' +
26      '<figure class="ab-lb-fig"><img alt=""><figcaption><span class="ab-lb-tag"></span><span class="ab-lb-title"></span><span class="ab-lb-count"></span></figcaption></figure>' +
27      '<button type="button" class="ab-lb-nav ab-lb-next" aria-label="Next photo">&#8250;</button>';
28    document.body.appendChild(box);
29    img = box.querySelector('img');
30    cap = box.querySelector('figcaption');
31    box.addEventListener('click', function (e) {
32      if (e.target === box || e.target.closest('.ab-lb-x')) close();
33      else if (e.target.closest('.ab-lb-prev')) show(idx - 1);
34      else if (e.target.closest('.ab-lb-next')) show(idx + 1);
35    });
36    box.addEventListener('touchstart', function (e) { startX = e.touches[0].clientX; }, { passive: true });
37    box.addEventListener('touchend', function (e) {
38      var dx = e.changedTouches[0].clientX - startX;
39      if (Math.abs(dx) > 50) show(idx + (dx < 0 ? 1 : -1));
40    });
41  }
42
43  function show(i) {
44    idx = (i + list.length) % list.length;
45    var it = list[idx];
46    box.classList.add('ab-lb-loading');
47    img.onload = function () { box.classList.remove('ab-lb-loading'); };
48    img.src = it.src;
49    img.alt = it.title + ' at BigiByte';
50    cap.querySelector('.ab-lb-tag').textContent = it.tag;
51    cap.querySelector('.ab-lb-title').textContent = it.title;
52    cap.querySelector('.ab-lb-count').textContent = (idx + 1) + ' / ' + list.length;
53  }
54
55  function open(src) {
56    list = cards();
57    if (!box) build();
58    var i = list.findIndex(function (x) { return x.src === src; });
59    lastFocus = document.activeElement;
60    show(i < 0 ? 0 : i);
61    box.classList.add('ab-lb-open');
62    document.documentElement.style.overflow = 'hidden';
63    if (window.__lenis) window.__lenis.stop();
64    box.querySelector('.ab-lb-x').focus();
65  }
66
67  function close() {
68    box.classList.remove('ab-lb-open');
69    document.documentElement.style.overflow = '';
70    if (window.__lenis) window.__lenis.start();
71    if (lastFocus && lastFocus.focus) lastFocus.focus();
72  }
73
74  document.addEventListener('click', function (e) {
75    var c = e.target.closest && e.target.closest('[data-ab-card][data-full]');
76    if (c) { e.preventDefault(); open(c.getAttribute('data-full')); }
77  });
78  document.addEventListener('keydown', function (e) {
79    if (box && box.classList.contains('ab-lb-open')) {
80      if (e.key === 'Escape') close();
81      else if (e.key === 'ArrowRight') show(idx + 1);
82      else if (e.key === 'ArrowLeft') show(idx - 1);
83      return;
84    }
85    var c = e.target.closest && e.target.closest('[data-ab-card][data-full]');
86    if (c && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); open(c.getAttribute('data-full')); }
87  });
88})();

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.