Slideshow

Von $1

    Inhaltsverzeichnis
    keine Gliederung

    Version seit 14:21, 6 Nov 2026

    zu dieser Version.

    Zurück zu Versionshistorie.

    Zeige aktuelle Version

       

     

    (function() {
    
        /* Letzten uninitialisierten Wrapper finden */
        var allWraps = document.getElementsByClassName('galleryWrap');
        var wrap = null;
        var i;
        for (i = 0; i < allWraps.length; i++) {
            if (!allWraps[i].getAttribute('data-ginit')) { wrap = allWraps[i]; }
        }
        if (!wrap) { console.log('[Gallery] ABORT: kein freier Wrap'); return; }
        wrap.setAttribute('data-ginit', '1');
    
        function q(cls) {
            var els = wrap.getElementsByClassName(cls);
            return (els && els.length) ? els[0] : null;
        }
    
        var loadBtn  = q('galleryLoadBtn');
        var prevBtn  = q('galleryPrevBtn');
        var nextBtn  = q('galleryNextBtn');
        var playBtn  = q('galleryPlayBtn');
        var stopBtn  = q('galleryStopBtn');
        var counter  = q('galleryCounter');
        var statusEl = q('galleryStatus');
        var stage    = q('galleryStage');
        var mainImg  = q('galleryMainImg');
        var imgName  = q('galleryImgName');
        var thumbRow = q('galleryThumbRow');
        var imgDesc  = q('galleryImgDesc');
    
        if (!loadBtn || !stage || !mainImg) { console.log('[Gallery] ABORT: DOM fehlt'); return; }
    
        var images     = new Array();
        var currentIdx = 0;
        var slideTimer = null;
        var DELAY      = 3000;
        var MAX_DEPTH  = 5;
        var IMG_EXTS   = 'jpg jpeg png gif bmp webp svg';
    
        var bfsQueue   = new Array();
        var bfsIdx     = 0;
        var allPageIds = new Array();
    
        function setText(el, txt) { if (el) { el.textContent = txt; } }
        function setStatus(msg, color) { setText(statusEl, msg); if (statusEl) { statusEl.style.color = color || '#888'; } }
    
        function getPageId() {
            var pid = 0;
            if (typeof Deki !== 'undefined') {
                if (Deki.PageId) { pid = Deki.PageId; }
                else if (Deki.Page && Deki.Page.Id) { pid = Deki.Page.Id; }
            }
            return pid;
        }
    
        function forceHttps(url) {
            if (url && url.indexOf('http://') === 0) {
                return 'https://' + url.substring(7);
            }
            return url;
        }
    
        /* -------------------------------------------------------
           PHASE 1: BFS – Unterseiten sammeln
        ------------------------------------------------------- */
        function loadImages() {
            var pageId = getPageId();
            console.log('[Gallery] START rootPageId=' + pageId);
            if (!pageId) { setStatus('Page-ID nicht gefunden!', '#ff4444'); return; }
            loadBtn.disabled = true;
            images     = new Array();
            allPageIds = new Array();
            bfsQueue   = new Array();
            bfsIdx     = 0;
    
            allPageIds.push(pageId);
            var root = new Object();
            root.id    = pageId;
            root.depth = 0;
            bfsQueue.push(root);
    
            setStatus('Sammle Unterseiten...', '#7ecfff');
            processBFS();
        }
    
        function processBFS() {
            if (bfsIdx >= bfsQueue.length) {
                console.log('[Gallery] BFS fertig. Seiten=' + allPageIds.length + ' IDs=' + allPageIds.join(','));
                setStatus('Lade Bilder von ' + allPageIds.length + ' Seite(n)...', '#7ecfff');
                fetchAllFiles();
                return;
            }
    
            var item = bfsQueue[bfsIdx];
            bfsIdx++;
    
            if (item.depth >= MAX_DEPTH) {
                processBFS();
                return;
            }
    
            var apiUrl = '/@api/deki/pages/' + item.id + '/subpages?dream.out.format=xml';
            console.log('[Gallery] BFS fetch id=' + item.id + ' depth=' + item.depth);
    
            var xhr = new XMLHttpRequest();
            xhr.open('GET', apiUrl, true);
            xhr.onload = function() {
                console.log('[Gallery] BFS resp id=' + item.id + ' status=' + xhr.status + ' bytes=' + xhr.responseText.length);
                /* Ersten 500 Zeichen als Diagnose */
                console.log('[Gallery] BFS xml-preview: ' + xhr.responseText.substring(0, 500));
    
                if (xhr.status === 200) {
                    var parser = new DOMParser();
                    var xml    = parser.parseFromString(xhr.responseText, 'text/xml');
    
                    /* Alle vorkommenden Tag-Namen sammeln */
                    var allNodes = xml.getElementsByTagName('*');
                    var tagNames = new Array();
                    var ti;
                    for (ti = 0; ti < allNodes.length && ti < 40; ti++) {
                        var tn = allNodes[ti].tagName;
                        var found = false;
                        var tk;
                        for (tk = 0; tk < tagNames.length; tk++) {
                            if (tagNames[tk] === tn) { found = true; break; }
                        }
                        if (!found) { tagNames.push(tn); }
                    }
                    console.log('[Gallery] BFS tags-in-xml: ' + tagNames.join(', '));
    
                    /* Kinder auslesen */
                    var nodes = xml.getElementsByTagName('page');
                    console.log('[Gallery] BFS page-nodes=' + nodes.length);
                    var j;
                    for (j = 0; j < nodes.length; j++) {
                        var childId = nodes[j].getAttribute('id');
                        console.log('[Gallery] BFS child #' + j + ' id=' + childId);
                        if (childId) {
                            allPageIds.push(childId);
                            var child = new Object();
                            child.id    = childId;
                            child.depth = item.depth + 1;
                            bfsQueue.push(child);
                        }
                    }
                }
                processBFS();
            };
            xhr.onerror = function() {
                console.log('[Gallery] BFS XHR-error id=' + item.id);
                processBFS();
            };
            xhr.send();
        }
    
        /* -------------------------------------------------------
           PHASE 2: Dateien parallel laden
        ------------------------------------------------------- */
        function fetchAllFiles() {
            var total     = allPageIds.length;
            var remaining = total;
            if (total === 0) { finalize(); return; }
    
            var j;
            for (j = 0; j < total; j++) {
                (function(pid) {
                    var xhr = new XMLHttpRequest();
                    xhr.open('GET', '/@api/deki/pages/' + pid + '/files?dream.out.format=xml', true);
                    xhr.onload = function() {
                        if (xhr.status === 200) {
                            var before = images.length;
                            parseAndAddFiles(xhr.responseText);
                            console.log('[Gallery] Files pid=' + pid + ' neu=' + (images.length - before) + ' gesamt=' + images.length);
                        } else {
                            console.log('[Gallery] Files pid=' + pid + ' status=' + xhr.status);
                        }
                        remaining--;
                        if (remaining === 0) { finalize(); }
                    };
                    xhr.onerror = function() {
                        console.log('[Gallery] Files XHR-error pid=' + pid);
                        remaining--;
                        if (remaining === 0) { finalize(); }
                    };
                    xhr.send();
                })(allPageIds[j]);
            }
        }
    
        function parseAndAddFiles(responseText) {
            var parser = new DOMParser();
            var xml    = parser.parseFromString(responseText, 'text/xml');
            var nodes  = xml.getElementsByTagName('file');
            var j;
            for (j = 0; j < nodes.length; j++) {
                var cNodes = nodes[j].getElementsByTagName('contents');
                var nNodes = nodes[j].getElementsByTagName('filename');
                var dNodes = nodes[j].getElementsByTagName('description');
                if (!cNodes.length) { continue; }
                var url  = forceHttps(cNodes[0].getAttribute('href') || '');
                var name = nNodes.length ? nNodes[0].textContent : url;
                var ext  = name.split('.').pop().toLowerCase();
                if (IMG_EXTS.indexOf(ext) === -1) { continue; }
                var k;
                var dup = false;
                for (k = 0; k < images.length; k++) {
                    if (images[k].url === url) { dup = true; break; }
                }
                if (dup) { continue; }
                var desc = (dNodes.length && dNodes[0].textContent) ? dNodes[0].textContent : '';
                var item = new Object();
                item.url  = url;
                item.name = name;
                item.desc = desc;
                images.push(item);
            }
        }
    
        /* -------------------------------------------------------
           PHASE 3: Gallery anzeigen
        ------------------------------------------------------- */
        function finalize() {
            console.log('[Gallery] FINALIZE images=' + images.length);
            loadBtn.disabled = false;
            if (images.length === 0) { setStatus('Keine Bilder gefunden.', '#ff8c69'); return; }
            setStatus('');
            loadBtn.style.display = 'none';
            stage.style.display   = 'block';
            if (thumbRow) { thumbRow.style.display = 'flex'; }
            if (prevBtn)  { prevBtn.style.display  = 'inline-block'; }
            if (nextBtn)  { nextBtn.style.display  = 'inline-block'; }
            if (playBtn)  { playBtn.style.display  = 'inline-block'; }
            buildThumbs();
            showImage(0);
        }
    
        function showImage(idx) {
            currentIdx = idx;
            if (mainImg) {
                mainImg.src = ''; mainImg.src = images[idx].url;
                mainImg.style.cursor = 'pointer';
                mainImg.onclick = function() { window.open(images[idx].url, '_blank'); };
            }
            setText(imgName, images[idx].name);
            setText(imgDesc, images[idx].desc ? images[idx].desc : 'Keine Beschreibung');
            setText(counter, (idx + 1) + ' / ' + images.length);
            if (thumbRow) {
                var thumbs = thumbRow.getElementsByTagName('img');
                var j;
                for (j = 0; j < thumbs.length; j++) {
                    thumbs[j].className = j === idx ? 'gThumb gThumbActive' : 'gThumb';
                }
            }
        }
    
        function buildThumbs() {
            if (!thumbRow) { return; }
            thumbRow.innerHTML = '';
            var j;
            for (j = 0; j < images.length; j++) {
                var t = document.createElement('img');
                t.className = 'gThumb';
                t.src   = images[j].url;
                t.alt   = images[j].name;
                t.title = images[j].name;
                (function(idx) { t.onclick = function() { showImage(idx); }; })(j);
                thumbRow.appendChild(t);
            }
        }
    
        function showNext() { showImage((currentIdx + 1) % images.length); }
        function showPrev() { showImage((currentIdx - 1 + images.length) % images.length); }
    
        function startSlideshow() {
            if (playBtn) { playBtn.style.display = 'none'; }
            if (stopBtn) { stopBtn.style.display = 'inline-block'; }
            slideTimer = setInterval(function() { showNext(); }, DELAY);
        }
    
        function stopSlideshow() {
            if (slideTimer) { clearInterval(slideTimer); slideTimer = null; }
            if (stopBtn) { stopBtn.style.display = 'none'; }
            if (playBtn) { playBtn.style.display = 'inline-block'; }
        }
    
        if (loadBtn) { loadBtn.onclick = function() { loadImages(); }; }
        if (prevBtn) { prevBtn.onclick = function() { showPrev(); }; }
        if (nextBtn) { nextBtn.onclick = function() { showNext(); }; }
        if (playBtn) { playBtn.onclick = function() { startSlideshow(); }; }
        if (stopBtn) { stopBtn.onclick = function() { stopSlideshow(); }; }
    
        document.onkeydown = function(e) {
            if (!stage || stage.style.display === 'none') { return; }
            var k = e.keyCode;
            if (k === 37)      { showPrev(); }
            else if (k === 39) { showNext(); }
            else if (k === 32) { if (slideTimer) { stopSlideshow(); } else { startSlideshow(); } }
        };
    
    })();
    
    NoElements {}

     
    Use the language selection below for English Utilise le sélecteur de langue ci-dessous pour français Per l'italiano, utilizzare la selezione della lingua qui sotto Schön sprichst du deutsch :-)