1(function () { 2 'use strict'; 3 function init() { 4 var slider = document.getElementById('video-3'); 5 if (slider) { 6 var slides = Array.from(slider.querySelectorAll('.carousel-inner > .carousel-item')); 7 var buttons = Array.from(slider.querySelectorAll('.carousel-indicators > li > button')); 8 // Bootstrap richiede l'indice anche quando il clic è gestito da SZ Slider. 9 buttons.forEach(function (button, index) { 10 button.parentElement.setAttribute('data-bs-slide-to', String(index)); 11 button.parentElement.setAttribute('data-bs-target', '#video-3'); 12 }); 13 var status = document.createElement('span'); 14 status.className = 'ares-visually-hidden'; status.setAttribute('role', 'status'); 15 status.setAttribute('aria-live', 'polite'); status.setAttribute('aria-atomic', 'true'); 16 slider.appendChild(status); 17 function sync(current) { 18 slides.forEach(function (slide) { var selected = slide === current; slide.setAttribute('aria-hidden', String(!selected)); slide.inert = !selected; }); 19 buttons.forEach(function (button, n) { if (slides[n] === current) button.setAttribute('aria-current', 'true'); else button.removeAttribute('aria-current'); }); 20 if (slider.contains(document.activeElement) && current) status.textContent = current.getAttribute('aria-label'); 21 } 22 // Il componente trascina le slide; la classe Bootstrap active può restare indietro. 23 function syncVisible() { 24 if (!slider.getBoundingClientRect().width) return; 25 var box = slider.querySelector('.carousel-inner').getBoundingClientRect(); 26 var current = slides.reduce(function (best, slide) { 27 return !best || Math.abs(slide.getBoundingClientRect().left - box.left) < 28 Math.abs(best.getBoundingClientRect().left - box.left) ? slide : best; 29 }, null); 30 sync(current); 31 } 32 var syncTimer; 33 function scheduleSync() { clearTimeout(syncTimer); syncTimer = setTimeout(syncVisible, 450); } 34 buttons.forEach(function (button) { 35 // Evita che il trascinamento del carosello intercetti il clic del pulsante. 36 ['pointerdown', 'mousedown', 'touchstart'].forEach(function (name) { 37 button.addEventListener(name, function (event) { event.stopPropagation(); }); 38 }); 39 button.addEventListener('keydown', function (event) { 40 if (event.key === ' ' || event.key === 'Spacebar') { 41 event.preventDefault(); event.stopPropagation(); 42 if (!event.repeat) button.click(); 43 } 44 }); 45 button.addEventListener('click', scheduleSync); 46 }); 47 new MutationObserver(scheduleSync).observe(slider.querySelector('.carousel-inner'), { 48 subtree:true, attributes:true, attributeFilter:['style', 'class'] 49 }); 50 slider.addEventListener('transitionend', scheduleSync); 51 window.addEventListener('resize', scheduleSync); 52 window.addEventListener('load', scheduleSync); 53 sync(slider.querySelector('.carousel-item.active')); 54 scheduleSync(); 55 } 56 var descriptions = { 57 'ares-gallery-03.jpg': 'Operatrice con cuffie davanti ai monitor della centrale operativa.', 58 'ares-gallery-04.jpg': 'Foto di gruppo al G20 con personale di soccorso davanti alle bandiere dei Paesi partecipanti.', 59 'ares-gallery-05.jpg': 'Personale sanitario e militare accanto a un aereo per il trasporto sanitario.', 60 'ares-gallery-06.jpg': 'Ambulanza ARES 118 davanti al Colosseo.', 61 'ares-gallery-07.jpg': 'Soccorritori assistono un ciclista davanti alla basilica di San Giovanni in Laterano.', 62 'ares-gallery-08.jpg': 'Mezzo di soccorso con lampeggianti in via della Conciliazione di notte.', 63 'ares-gallery-09.jpg': 'Personale ARES 118 e mezzi di soccorso durante unâattività sul campo.', 64 'ares-gallery-10.jpg': 'Operatrice sanitaria USAR con casco e radio accanto ai Vigili del Fuoco.' 65 }; 66 function describe(image) { var name = (image.getAttribute('src') || '').split('/').pop().split('?')[0]; if (descriptions[name]) image.setAttribute('alt', descriptions[name]); } 67 function scan(node) { if (node.nodeType !== 1) return; if (node.tagName === 'IMG') describe(node); node.querySelectorAll('img').forEach(describe); } 68 scan(document.body); 69 // The existing gallery recycles image nodes during navigation. 70 new MutationObserver(function (records) { records.forEach(function (record) { if (record.type === 'attributes') describe(record.target);
70 else record.addedNodes.forEach(scan); }); }).observe(document.body, {childList:true, subtree:true, attributes:true, attributeFilter:['src']}); 71 } 72 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); 73}()); 74 75/* WCAG 1.1.1: alternative testuali dei comandi a icona della galleria. */ 76(function () { 77 'use strict'; 78 function initGalleryLabels() { 79 var host = document.getElementById('myDiv'); 80 if (!host) return; 81 var observer; 82 function labelButton(button, normalLabel, alternateLabel) { 83 if (!button || !button.screen || button.screen.hasAttribute('data-ares-text-alternative')) return; 84 var element = button.screen; 85 element.setAttribute('data-ares-text-alternative', 'true'); 86 element.setAttribute('role', 'button'); 87 function update() { 88 var label = alternateLabel && button.currentState === 0 ? alternateLabel : normalLabel; 89 element.setAttribute('aria-label', label); 90 element.setAttribute('title', label); 91 element.querySelectorAll('.table-cell-fwdsisc-plugin-button').forEach(function (icon) { 92 icon.setAttribute('aria-hidden', 'true'); 93 }); 94 } 95 if (alternateLabel && typeof button.setButtonState === 'function') { 96 var setButtonState = button.setButtonState; 97 button.setButtonState = function () { 98 var result = setButtonState.apply(this, arguments); 99 update(); 100 return result; 101 }; 102 } 103 update(); 104 } 105 function attach() { 106 var gallery = window.fwdsisc0; 107 var manager = gallery && gallery.imageManager_do; 108 if (!manager || !manager.prevButton_do || !manager.nextButton_do || 109 !manager.zoomButton_do || !manager.fullScreenButton_do) return; 110 labelButton(manager.prevButton_do, 'Immagine precedente'); 111 labelButton(manager.nextButton_do, 'Immagine successiva'); 112 labelButton(manager.zoomButton_do, 'Ingrandisci immagine', 'Riduci immagine'); 113 labelButton(manager.fullScreenButton_do, 'Apri galleria a schermo intero', 'Esci dallo schermo intero'); 114 if (observer) observer.disconnect(); 115 window.removeEventListener('load', attach); 116 } 117 // La galleria crea i comandi dopo il caricamento delle proprie risorse. 118 observer = new MutationObserver(attach); 119 observer.observe(host, {childList: true, subtree: true}); 120 window.addEventListener('load', attach); 121 attach(); 122 } 123 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initGalleryLabels); 124 else initGalleryLabels(); 125}()); 126 127/* Accesso da tastiera e pausa della galleria fotografica. */ 128(function () { 129 'use strict'; 130 function init() { 131 var host = document.getElementById('myDiv'); 132 if (!host) return; 133 var observer; 134 function attach() { 135 var gallery = window.fwdsisc0; 136 var m = gallery && gallery.imageManager_do; 137 if (!m || !m.nextButton_do || !m.prevButton_do || !m.zoomButton_do || !m.fullScreenButton_do) return; 138 observer.disconnect(); 139 var root = gallery.main_do.screen; 140 root.setAttribute('role', 'region'); 141 root.setAttribute('aria-label', 'Galleria fotografica ARES 118'); 142 var controls = [m.prevButton_do, m.nextButton_do, m.zoomButton_do, m.fullScreenButton_do]; 143 function showControls() { m.showButtons(true); m.showInfoHolder(false); } 144 ['hideButtons', 'hideInfoHolder'].forEach(function (name) { 145 var original = m[name]; 146 m[name] = function () { 147 if (root.contains(document.activeElement) || controls.some(function (b) { return b.screen.contains(document.activeElement); })) return; 148 return original.apply(this, arguments); 149 }; 150 }); 151 function sync() { 152 controls.forEach(function (b, i) { 153 var unavailable = !!b.isDisabled_bl || (!!m.isMaximized_bl && i !== 2); 154 b.screen.tabIndex = unavailable ? -1 : 0; 155 b.screen.setAttribute('aria-disabled', String(unavailable)); 156 }); 157 } 158 controls.forEach(function (b) { 159 b.screen.classList.add('ares-gallery-control'); 160 // Attiva soltanto al clic completato: il rilascio fuori dal comando annulla. 161 // Il vecchio ramo touch/pointer del plugin può attivare già alla pressione. 162 ['pointerdown', 'pointerup', 'mouseup', 'touchend'].forEach(function (name) { 163 b.screen.removeEventListener(name, b.onMouseUp); 164 }); 165 b.screen.addEventListener('click', function (event) { 166 if (b.screen.getAttribute('aria-disabled') !== 'true') b.onMouseUp(event); 167 }); 168 b.screen.addEventListener('focus', showControls); 169 b.screen.addEventListener('keydown', function (event) { 170 if (event.key !== 'Enter' && event.key !== ' ') return; 171 event.preventDefault(); event.stopPropagation(); 172 if (!event.repeat && b.screen.getAttribute('aria-disabled') !== 'true') b.onMouseUp(event); 173 }); 174 ['setButtonState', 'disable', 'enable'].forEach(function (name) { 175 if (typeof b[name] !== 'function') return; 176 var original = b[name]; 177 b[name] = function () { var result = original.apply(this, arguments); sync(); return result; }; 178 }); 179 }); 180 function escapeGallery(event) { 181 if (event.key !== 'Escape') return; 182 if (m.isMaximized_bl && !m.isAnimMaximizeOrMinimize_bl) { 183 event.preventDefault(); event.stopPropagation(); m.maximizeOrMinimize(); m.zoomButton_do.screen.focus(); 184 } else if (gallery.isFullScreen_bl) { 185 event.preventDefault(); event.stopPropagation(); gallery.goNormalScreen(); m.fullScreenButton_do.screen.focus(); 186 } 187 } 188 root.addEventListener('keydown', escapeGallery);
189 controls.forEach(function (b) { b.screen.addEventListener('keydown', escapeGallery); }); 190 if (m.tm) { 191 var paused = false; 192 var start = m.tm.start; 193 m.tm.start = function () { if (!paused) return start.apply(this, arguments); }; 194 var pause = document.createElement('button'); 195 pause.type = 'button'; pause.className = 'ares-gallery-pause'; 196 function setPause(value) { 197 paused = value; 198 pause.textContent = paused ? 'Riprendi galleria' : 'Pausa galleria'; 199 pause.setAttribute('aria-label', paused ? 'Riprendi galleria' : 'Pausa galleria'); 200 if (paused) m.tm.stop(); else m.tm.start(); 201 } 202 pause.addEventListener('click', function () { setPause(!paused); }); 203 root.appendChild(pause); 204 setPause(window.matchMedia('(prefers-reduced-motion: reduce)').matches); 205 } 206 sync(); 207 } 208 observer = new MutationObserver(attach); 209 observer.observe(host, {childList:true, subtree:true}); 210 attach(); 211 } 212 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); 213}());
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.