PageSourceSearch

https://www.stadtwerke-hettstedt.de/files/files/slider-resize.js?v=b9d6c19a

js stadtwerke-hettstedt.de collected 2026-10-02 15:07:50 UTC 15,309 bytes, 362 lines download raw bytes

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 = '&times;';
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 = '&#8249;';
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 = '&#8250;';
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 = '&times;';
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.