1(() => { 2 'use strict'; 3 4 const SECOND = 1000; 5 const MINUTE = 60 * SECOND; 6 const HOUR = 60 * MINUTE; 7 const DAY = 24 * HOUR; 8 9 const TAN_30 = Math.tan(Math.PI / 6); 10 const slantObserver = 'ResizeObserver' in window 11 ? new ResizeObserver((entries) => { 12 entries.forEach((entry) => { 13 const element = entry.target; 14 const mode = element.dataset.presstigeSlant || 'full'; 15 const factor = mode === 'half' ? 0.5 : 1; 16 const height = entry.borderBoxSize?.[0]?.blockSize 17 ?? element.getBoundingClientRect().height; 18 19 if (height > 0) { 20 element.style.setProperty('--presstige-slant', `${height * TAN_30}px`); 21 element.style.setProperty('--presstige-slant-half', `${height * TAN_30 * factor}px`); 22 } 23 }); 24 }) 25 : null; 26 27 const initialiseGeometry = (root = document) => { 28 root.querySelectorAll('[data-presstige-slant]').forEach((element) => { 29 if (element.dataset.slantInitialised === '1') { 30 return; 31 } 32 33 element.dataset.slantInitialised = '1'; 34 35 const updateOnce = () => { 36 const mode = element.dataset.presstigeSlant || 'full'; 37 const factor = mode === 'half' ? 0.5 : 1; 38 const height = element.getBoundingClientRect().height; 39 40 if (height > 0) { 41 element.style.setProperty('--presstige-slant', `${height * TAN_30}px`); 42 element.style.setProperty('--presstige-slant-half', `${height * TAN_30 * factor}px`); 43 } 44 }; 45 46 updateOnce(); 47 48 if (slantObserver) { 49 slantObserver.observe(element); 50 } else { 51 window.addEventListener('resize', updateOnce, {passive: true}); 52 } 53 }); 54 }; 55 56 const write = (element, unit, value) => { 57 const target = element.querySelector(`[data-countdown-unit="${unit}"]`); 58 59 if (target) { 60 target.textContent = String(value).padStart(2, '0'); 61 } 62 }; 63 64 const expireCountdown = (element) => { 65 const module = element.closest('.presstige-news--slider'); 66 67 element.hidden = true; 68 element.classList.add('is-expired'); 69 70 if (!module) { 71 return; 72 } 73 74 /* 75 * Ein Countdown liegt in jedem Slideshow-Slide. Sobald das Ziel 76 * erreicht ist, schalten wir die komplette Modulinstanz auf das 77 * normale Layout ohne Countdown um. ResizeObserver aktualisiert die 78 * Schrägen danach automatisch anhand der neuen Utility-Höhe. 79 */ 80 module.classList.remove('presstige-news--has-countdown'); 81 module.classList.add('presstige-news--countdown-expired'); 82 83 module.querySelectorAll('[data-presstige-countdown]').forEach((countdown) => { 84 countdown.hidden = true; 85 countdown.classList.add('is-expired'); 86 }); 87 88 module.querySelectorAll('.presstige-news-slider__utility--countdown').forEach((utility) => { 89 utility.classList.remove('presstige-news-slider__utility--countdown'); 90 }); 91 }; 92 93 const update = (element, targetTime) => { 94 const remaining = targetTime - Date.now(); 95 96 if (remaining <= 0) { 97 expireCountdown(element); 98 return 0; 99 } 100 101 const days = Math.floor(remaining / DAY); 102 const hours = Math.floor((remaining % DAY) / HOUR); 103 const minutes = Math.floor((remaining % HOUR) / MINUTE); 104 const seconds = Math.floor((remaining % MINUTE) / SECOND); 105 106 write(element, 'days', days); 107 write(element, 'hours', hours); 108 write(element, 'minutes', minutes); 109 write(element, 'seconds', seconds); 110 111 return remaining; 112 }; 113 114 const initialise = (root = document) => { 115 initialiseGeometry(root); 116 117 root.querySelectorAll('[data-presstige-countdown]').forEach((element) => {
118 if (element.dataset.countdownInitialised === '1') { 119 return; 120 } 121 122 const targetTime = Date.parse(element.dataset.target || ''); 123 124 if (!Number.isFinite(targetTime)) { 125 expireCountdown(element); 126 return; 127 } 128 129 element.dataset.countdownInitialised = '1'; 130 update(element, targetTime); 131 132 const timer = window.setInterval(() => { 133 if (!document.documentElement.contains(element)) { 134 window.clearInterval(timer); 135 return; 136 } 137 138 if (update(element, targetTime) === 0) { 139 window.clearInterval(timer); 140 } 141 }, SECOND); 142 }); 143 }; 144 145 if (document.readyState === 'loading') { 146 document.addEventListener('DOMContentLoaded', () => initialise(), {once: true}); 147 } else { 148 initialise(); 149 } 150 151 document.addEventListener('joomla:updated', (event) => { 152 initialise(event.target instanceof Element ? event.target : document); 153 }); 154})();
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.