1/** 2* Oliver Strozyk --slider-resize.js â Contao-Integration Header-Slider + News-iframe 3 4* 5/** 6* Oliver Strozyk --slider-resize.js â Contao-Integration Header-Slider + News-iframe 7 8/** 9 * slider-resize.js â Contao-Integration: Header-Slider + News-Artikel-iframe 10 * 11 * 1) Slider: <div id="sliderContainer"></div> im HTML-Element 12 * 2) News: <iframe id="newsFrame" src="...liste.php" ...> im HTML-Element 13 */ 14(function () { 15 'use strict'; 16 17 var SLIDER_URL = 'https://compu-magic.de/news/slider-embed.php'; 18 var NEWS_BASE_URL = 'https://compu-magic.de/news/'; 19 var lastNewsHeight = 0; 20 21 // ââ 1) Header-Slider erstellen (ohne Eltern-Elemente zu verändern) ââ 22 function createSlider() { 23 var container = document.getElementById('sliderContainer'); 24 if (!container) return; 25 if (document.getElementById('headerSlider')) return; 26 27 // Site-Parameter aus data-site-Attribut lesen (z.B. <div id="sliderContainer" data-site="trinkwasser">) 28 var siteParam = container.getAttribute('data-site'); 29 var sliderSrc = SLIDER_URL + (siteParam ? '?site=' + encodeURIComponent(siteParam) : ''); 30 31 container.style.position = 'relative'; 32 container.style.display = 'block'; 33 container.style.lineHeight = '0'; 34 container.style.overflow = 'hidden'; 35 container.style.padding = '0'; 36 37 var frame = document.createElement('iframe'); 38 frame.id = 'headerSlider'; 39 frame.src = sliderSrc; 40 frame.width = '100%'; 41 frame.height = '480'; 42 frame.frameBorder = '0'; 43 frame.scrolling = 'no'; 44 frame.title = 'Aktuelle Meldungen'; 45 frame.style.cssText = 'display:block;border:none;width:100%;overflow:hidden;transition:height .3s ease'; 46 container.appendChild(frame); 47 48 // Pixelgenaue volle Breite â berücksichtigt die Scrollbar korrekt 49 function applyFullBleed() { 50 container.style.left = '0px'; 51 container.style.width = ''; 52 container.style.marginLeft = ''; 53 54 // Eltern-Container dürfen kein overflow:hidden haben â sonst wird 55 // das negative left abgeschnitten und der Rand bleibt sichtbar 56 var el = container.parentElement; 57 while (el && el !== document.body) { 58 var cs = window.getComputedStyle(el); 59 if (cs.overflow === 'hidden' || cs.overflowX === 'hidden') { 60 el.style.overflow = 'visible'; 61 el.style.overflowX = 'visible'; 62 } 63 // Contao-typische Paddings/Margins am Artikel-Container entfernen 64 if (el.classList.contains('ce_html') || el.classList.contains('inside') || el.classList.contains('content-wrapper')) { 65 el.style.paddingLeft = '0'; 66 el.style.paddingRight = '0'; 67 el.style.marginLeft = '0'; 68 el.style.marginRight = '0'; 69 } 70 el = el.parentElement; 71 } 72 73 var rect = container.getBoundingClientRect(); 74 var viewportWidth = document.documentElement.clientWidth; 75 container.style.left = (-rect.left) + 'px'; 76 container.style.width = viewportWidth + 'px'; 77 container.style.maxWidth = viewportWidth + 'px'; 78 } 79 80 applyFullBleed(); 81 window.addEventListener('resize', applyFullBleed); 82 // Nochmal nach kurzer Verzögerung (falls Contao-Layout sich nach dem 83 // ersten Laden noch verschiebt, z.B. durch nachladende Bilder/Fonts) 84 setTimeout(applyFullBleed, 300); 85 setTimeout(applyFullBleed, 1000); 86 } 87 88 // ââ 2) News-Artikel-iframe: Höhe + Deep-Link ââââââââââââââââââââ 89 function applyNewsHeight(h) { 90 var frame = document.getElementById('newsFrame'); 91 if (!frame || !h || h < 100) return; 92 if (Math.abs(h - lastNewsHeight) < 2) return; 93 lastNewsHeight = h; 94 frame.style.height = h + 'px'; 95 } 96 97 function initNewsFrame() { 98 var frame = document.getElementById('newsFrame'); 99 if (!frame) return; 100 var params = new URLSearchParams(window.location.search); 101 var artikel = params.get('artikel'); 102 if (artikel) { 103 frame.src = NEWS_BASE_URL + 'anzeige.php?slug=' + encodeURIComponent(artikel); 104 // Direkt zum News-Bereich springen, damit man den Artikel sofort sieht 105 scrollToNewsSection(); 106 } 107 } 108 109 function scrollToNewsSection() { 110 var target = document.getElementById('news') || document.getElementById('newsFrame'); 111 if (!target) return; 112 function doScroll() { 113 var rect = target.getBoundingClientRect(); 114 var scrollTop = window.pageYOffset || document.documentElement.scrollTop; 115 var headerOffset = 90; // Platz für ggf. fixierten Seitenkopf 116 window.scrollTo({ top: scrollTop + rect.top - headerOffset, behavior: 'auto' }); 117 } 118 // Sofort versuchen, und nach kurzer Verzögerung nochmal 119 // (falls Contao/Layout noch nachträglich Höhe ändert) 120 doScroll(); 121 setTimeout(doScroll, 300); 122 setTimeout(doScroll, 800); 123 } 124 125 window.addEventListener('message', function (e) { 126 if (e.data && typeof e.data.sliderHeight === 'number') { 127 var sf = document.getElementById('headerSlider'); 128 if (sf) sf.style.height = e.data.sliderHeight + 'px'; 129 } 130 if (e.data && e.data.scrollToContent) { 131 var slider = document.getElementById('sliderContainer'); 132 if (slider) { 133 var rect = slider.getBoundingClientRect(); 134 var scrollTop = window.pageYOffset || document.documentElement.scrollTop; 135 window.scrollTo({ top: scrollTop + rect.bottom + 30, behavior: 'smooth' }); 136 } else { 137 window.scrollTo({ top: window.innerHeight, behavior: 'smooth' }); 138 } 139 } 140 if (e.data && typeof e.data.iframeHeight === 'number') { 141 applyNewsHeight(e.data.iframeHeight); 142 } 143 if (e.data && e.data.newsGoToList === true) { 144 var nf = document.getElementById('newsFrame'); 145 if (nf) nf.src = NEWS_BASE_URL + 'liste.php'; 146 if (window.history && window.history.replaceState) { 147 var url = new URL(window.location.href); 148 url.searchParams.delete('artikel'); 149 window.history.replaceState({}, '', url); 150 } 151 } 152 // Artikel-Overlay: Slider fragt an, diese Seite öffnet es (volle Monitorhöhe) 153 if (e.data && e.data.openArticleOverlay) { 154 openArticleOverlayTop(e.data.openArticleOverlay); 155 } 156 if (e.data && typeof e.data.articleContentHeight === 'number') { 157 var of = document.getElementById('swhArticleOverlayFrame'); 158 if (of) { 159 var maxAvail = window.innerHeight - 100; // 50px oben + 50px unten 160 of.style.height = Math.min(Math.max(e.data.articleContentHeight, 150), maxAvail) + 'px'; 161 } 162 } 163 // Bild-Lightbox: Artikel-Galerie fragt an, diese Seite öffnet sie (volle MonitorgröÃe) 164 if (e.data && e.data.openImageLightbox) { 165 openImageLightboxTop(e.data.images, e.data.index, e.data.bg, e.data.opacity); 166 } 167 // PDF-Vorschau: das anfragende iframe selbst wird auf Vollbild gesetzt 168 // (PDF wird INNERHALB des iframes gerendert â vermeidet CORS-Probleme, 169 // da die PDF-Datei same-origin zum iframe-Inhalt ist) 170 if (e.data && typeof e.data.pdfFullscreen === 'boolean') { 171 var srcFrame = findFrameBySource(e.source); 172 if (srcFrame) togglePdfFullscreen(srcFrame, e.data.pdfFullscreen); 173 } 174 }); 175 176 function findFrameBySource(source) { 177 var frames = document.getElementsByTagName('iframe'); 178 for (var i = 0; i < frames.length; i++) { 179 if (frames[i].contentWindow === source) return frames[i]; 180 } 181 return null; 182 } 183 184 function togglePdfFullscreen(frame, makeFullscreen) { 185 if (makeFullscreen) { 186 if (!frame.dataset.prevStyle) frame.dataset.prevStyle = frame.getAttribute('style') || ''; 187 frame.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999999;border:none;background:#525659'; 188 document.body.style.overflow = 'hidden'; 189 } else { 190 frame.style.cssText = frame.dataset.prevStyle || ''; 191 delete frame.dataset.prevStyle; 192 document.body.style.overflow = ''; 193 } 194 } 195 196 // ââ Bild-Lightbox auf Ebene der echten Seite âââââââââââââââââââââ 197 var lbImages = [], lbIdx = 0; 198 function openImageLightboxTop(images, index, bg, opacity) { 199 lbImages = images || []; 200 lbIdx = index || 0; 201 if (!lbImages.length) return; 202 203 var existing = document.getElementById('swhImageLightbox'); 204 if (existing) existing.remove(); 205 206 var bgHex = bg || '#000000'; 207 var op = (typeof opacity === 'number' ? opacity : 92) / 100; 208 var r = parseInt(bgHex.substr(1,2),16), g = parseInt(bgHex.substr(3,2),16), b = parseInt(bgHex.substr(5,2),16); 209
210 var overlay = document.createElement('div'); 211 overlay.id = 'swhImageLightbox'; 212 overlay.style.cssText = 'position:fixed;inset:0;z-index:9999999;display:flex;align-items:center;justify-content:center;padding:70px 90px;box-sizing:border-box;background:rgba(' + r + ',' + g + ',' + b + ',' + op + ')'; 213 214 var closeBtn = document.createElement('button'); 215 closeBtn.innerHTML = '×'; 216 closeBtn.setAttribute('aria-label', 'SchlieÃen'); 217 closeBtn.style.cssText = 'position:absolute;top:1rem;right:1.25rem;width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.12);color:#fff;border:none;font-size:1.7rem;cursor:pointer'; 218 closeBtn.onclick = closeImageLightboxTop; 219 220 var prevBtn = document.createElement('button'); 221 prevBtn.innerHTML = '‹'; 222 prevBtn.setAttribute('aria-label', 'Vorheriges Bild'); 223 prevBtn.style.cssText = 'position:absolute;top:50%;left:1rem;transform:translateY(-50%);width:52px;height:52px;border-radius:50%;background:rgba(255,255,255,.12);color:#fff;border:none;font-size:1.9rem;cursor:pointer'; 224 prevBtn.onclick = function(){ moveImageLightboxTop(-1); }; 225 226 var nextBtn = document.createElement('button'); 227 nextBtn.innerHTML = '›'; 228 nextBtn.setAttribute('aria-label', 'Nächstes Bild'); 229 nextBtn.style.cssText = 'position:absolute;top:50%;right:1rem;transform:translateY(-50%);width:52px;height:52px;border-radius:50%;background:rgba(255,255,255,.12);color:#fff;border:none;font-size:1.9rem;cursor:pointer'; 230 nextBtn.onclick = function(){ moveImageLightboxTop(1); }; 231 232 var figure = document.createElement('figure'); 233 figure.style.cssText = 'margin:0;text-align:center;display:inline-flex;flex-direction:column;align-items:center;max-width:100%;max-height:100%'; 234 235 var img = document.createElement('img'); 236 img.id = 'swhLbImg'; 237 img.style.cssText = 'display:block;object-fit:contain;border-radius:6px;box-shadow:0 20px 60px rgba(0,0,0,.5)'; 238 239 var caption = document.createElement('figcaption'); 240 caption.id = 'swhLbCaption'; 241 caption.style.cssText = 'color:#fff;font-size:.85rem;margin-top:.6rem;opacity:.85;max-width:90vw'; 242 243 var counter = document.createElement('p'); 244 counter.id = 'swhLbCount'; 245 counter.style.cssText = 'position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);color:#fff;font-size:.78rem;opacity:.7;margin:0'; 246 247 figure.appendChild(img); 248 figure.appendChild(caption); 249 overlay.appendChild(closeBtn); 250 if (lbImages.length > 1) { overlay.appendChild(prevBtn); overlay.appendChild(nextBtn); overlay.appendChild(counter); } 251 overlay.appendChild(figure); 252 document.body.appendChild(overlay); 253 document.body.style.overflow = 'hidden'; 254 255 overlay.addEventListener('click', function(e){ if (e.target === overlay) closeImageLightboxTop(); }); 256 closeBtn.focus(); 257 258 updateImageLightboxTop(); 259 } 260 261 function updateImageLightboxTop() { 262 var item = lbImages[lbIdx]; 263 var img = document.getElementById('swhLbImg'); 264 var caption = document.getElementById('swhLbCaption'); 265 var counter = document.getElementById('swhLbCount'); 266 if (!img) return; 267 img.src = item.src; 268 img.alt = item.alt || ''; 269 caption.textContent = item.alt || ''; 270 if (counter) counter.textContent = (lbIdx + 1) + ' / ' + lbImages.length; 271 fitImageLightboxTop(img, caption); 272 } 273 274 function fitImageLightboxTop(img, caption) { 275 function apply() { 276 var captionH = caption.textContent ? caption.offsetHeight + 24 : 0; 277 var reserved = 140 + captionH; 278 var maxH = Math.max(150, window.innerHeight - reserved); 279 var maxW = Math.max(200, window.innerWidth - 180); 280 img.style.maxHeight = maxH + 'px'; 281 img.style.maxWidth = maxW + 'px'; 282 } 283 if (img.complete) { apply(); } else { img.onload = apply; } 284 } 285 286 function moveImageLightboxTop(dir) { 287 lbIdx = (lbIdx + dir + lbImages.length) % lbImages.length; 288 updateImageLightboxTop(); 289 } 290 291 function closeImageLightboxTop() { 292 var overlay = document.getElementById('swhImageLightbox'); 293 if (overlay) overlay.remove(); 294 document.body.style.overflow = ''; 295 } 296 297 document.addEventListener('keydown', function (e) { 298 var lb = document.getElementById('swhImageLightbox'); 299 if (!lb) return; 300 if (e.key === 'Escape') closeImageLightboxTop(); 301 if (e.key === 'ArrowLeft') moveImageLightboxTop(-1); 302 if (e.key === 'ArrowRight') moveImageLightboxTop(1); 303 }); 304 305 // ââ Artikel-Overlay auf Ebene der echten Seite (volle Monitorhöhe) ââ 306 function openArticleOverlayTop(slug) { 307 var existing = document.getElementById('swhArticleOverlay'); 308 if (existing) existing.remove(); 309
310 var overlay = document.createElement('div'); 311 overlay.id = 'swhArticleOverlay'; 312 overlay.style.cssText = 'position:fixed;inset:0;z-index:999999;background:rgba(0,0,0,.75);display:flex;align-items:flex-start;justify-content:center;padding:50px 1rem;box-sizing:border-box;overflow-y:auto'; 313 314 var box = document.createElement('div'); 315 box.style.cssText = 'position:relative;width:95vw;max-width:1400px;max-height:calc(100vh - 100px);background:#fff;border-radius:14px;overflow-y:auto;box-shadow:0 25px 80px rgba(0,0,0,.5);margin:auto 0'; 316 317 var closeBtn = document.createElement('button'); 318 closeBtn.innerHTML = '×'; 319 closeBtn.setAttribute('aria-label', 'SchlieÃen'); 320 closeBtn.style.cssText = 'position:absolute;top:10px;right:10px;z-index:2;width:38px;height:38px;border-radius:50%;background:rgba(0,0,0,.55);color:#fff;border:none;font-size:1.6rem;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center'; 321 closeBtn.onclick = closeArticleOverlayTop; 322 323 var frame = document.createElement('iframe'); 324 frame.id = 'swhArticleOverlayFrame'; 325 frame.src = NEWS_BASE_URL + 'anzeige.php?slug=' + encodeURIComponent(slug) + '&embed=1'; 326 frame.style.cssText = 'width:100%;height:200px;border:none;display:block'; 327 frame.title = 'Artikel'; 328 329 box.appendChild(closeBtn); 330 box.appendChild(frame); 331 overlay.appendChild(box); 332 document.body.appendChild(overlay); 333 document.body.style.overflow = 'hidden'; 334 335 overlay.addEventListener('click', function (e) { 336 if (e.target === overlay) closeArticleOverlayTop(); 337 }); 338 } 339 340 function closeArticleOverlayTop() { 341 var overlay = document.getElementById('swhArticleOverlay'); 342 if (overlay) overlay.remove(); 343 document.body.style.overflow = ''; 344 } 345 346 document.addEventListener('keydown', function (e) { 347 if (e.key === 'Escape') { 348 closeArticleOverlayTop(); 349 } 350 }); 351 352 function init() { 353 createSlider(); 354 initNewsFrame(); 355 } 356 357 if (document.readyState === 'loading') { 358 document.addEventListener('DOMContentLoaded', init); 359 } else { 360 init(); 361 } 362})();
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.