1/* melody-front.js â carrousel diaporama + lightbox pour les articles Melody. 2 S'auto-initialise ; ne fait rien s'il n'y a pas de .melody-diaporama sur la page. */ 3(function () { 4 function init() { 5 var dps = document.querySelectorAll('.melody-diaporama'); 6 if (!dps.length) return; 7 8 // Lightbox (créée une seule fois) 9 var lb = document.getElementById('mdp-lightbox'); 10 if (!lb) { 11 lb = document.createElement('div'); 12 lb.id = 'mdp-lightbox'; 13 lb.setAttribute('role', 'dialog'); 14 lb.setAttribute('aria-modal', 'true'); 15 lb.innerHTML = '<span class="mdp-close" aria-label="Fermer">×</span>' 16 + '<button type="button" class="lb-arrow lb-prev" aria-label="Photo precedente">❮</button>' 17 + '<img src="" alt="">' 18 + '<button type="button" class="lb-arrow lb-next" aria-label="Photo suivante">❯</button>' 19 + '<div class="mdp-caption"></div>'; 20 document.body.appendChild(lb); 21 } 22 var lbImg = lb.querySelector('img'), lbCap = lb.querySelector('.mdp-caption'); 23 var lbPrev = lb.querySelector('.lb-prev'), lbNext = lb.querySelector('.lb-next'); 24 var group = [], idx = 0; // photos du diaporama courant + index affiché 25 26 function render() { 27 if (!group.length) return; 28 var it = group[idx]; 29 lbImg.src = it.src; 30 lbCap.textContent = it.legend || ''; 31 if (it.credit) { 32 if (it.legend) lbCap.appendChild(document.createTextNode(' ')); 33 var s = document.createElement('span'); s.className = 'cred'; s.textContent = it.credit; 34 lbCap.appendChild(s); 35 } 36 var multi = group.length > 1; 37 lbPrev.style.display = multi ? '' : 'none'; 38 lbNext.style.display = multi ? '' : 'none'; 39 } 40 function openAt(g, i) { group = g; idx = i; render(); lb.classList.add('open'); } 41 function close() { lb.classList.remove('open'); lbImg.src = ''; group = []; } 42 function go(d) { if (group.length) { idx = (idx + d + group.length) % group.length; render(); } } 43 44 lb.addEventListener('click', function (e) { if (e.target === lb || e.target.classList.contains('mdp-close')) close(); }); 45 lbPrev.addEventListener('click', function (e) { e.stopPropagation(); go(-1); }); 46 lbNext.addEventListener('click', function (e) { e.stopPropagation(); go(1); }); 47 document.addEventListener('keydown', function (e) { 48 if (!lb.classList.contains('open')) return; 49 if (e.key === 'Escape') close(); 50 else if (e.key === 'ArrowLeft') go(-1); 51 else if (e.key === 'ArrowRight') go(1); 52 }); 53 54 dps.forEach(function (dp) { 55 var track = dp.querySelector('.mdp-track'); 56 var imgs = Array.prototype.slice.call(dp.querySelectorAll('.mdp-item img')); 57 var g = imgs.map(function (img) { 58 return { src: img.src, legend: img.getAttribute('data-legend') || '', credit: img.getAttribute('data-credit') || '' }; 59 }); 60 imgs.forEach(function (img, i) { 61 img.addEventListener('click', function () { openAt(g, i); }); 62 }); 63 function step() { var it = dp.querySelector('.mdp-item'); return it ? it.getBoundingClientRect().width + 12 : 200; } 64 var prev = dp.querySelector('.mdp-prev'), next = dp.querySelector('.mdp-next'); 65 if (prev && track) prev.addEventListener('click', function () { track.scrollBy({ left: -step(), behavior: 'smooth' }); }); 66 if (next && track) next.addEventListener('click', function () { track.scrollBy({ left: step(), behavior: 'smooth' }); }); 67 }); 68 } 69 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); 70 else init(); 71})();
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.