MediaWiki:Common.js: Unterschied zwischen den Versionen

Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
 
(55 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
/* === PREPRINT START === */
/* === PREPRINT START === */
/* ============================================
/* ============================================
   PREPRINT v7.17 - JS v260212r2
   PREPRINT v7.17 - JS v260225r1
 
  ARCHITECTURE:
  - Platform Adaptation Layer (PAL): isolates Minerva workarounds
  - Model Layer: dimensional intent, linkage fabric, projection
  - Feature Layer: BookNav, TOC, Snippets
   ============================================ */
   ============================================ */


Zeile 14: Zeile 9:
     // Prevent repeated initialization
     // Prevent repeated initialization
     if (window.preprintInitialized) {
     if (window.preprintInitialized) {
        console.log('Preprint: Already initialized, skipping');
         return;
         return;
     }
     }
Zeile 35: Zeile 29:
         var imagesStabilized = false;
         var imagesStabilized = false;
          
          
         // Debug logging with source tracking
         // Debug logging with source tracking (silent in production)
         function log(adapter, message) {
         function log(adapter, message) {
            console.log('Preprint PAL.' + adapter + ': ' + message);
         }
         }


Zeile 52: Zeile 45:
                 }
                 }
                  
                  
                New:
                 // Minerva: observe mutations, unwrap sections as they appear
                 // Minerva: observe mutations, unwrap sections as they appear
                 var debounceTimer = null;
                 var debounceTimer = null;
Zeile 330: Zeile 322:
                 var myGeneration = ++transitionGeneration;
                 var myGeneration = ++transitionGeneration;
                  
                  
                New:
                 resizeTimer = setTimeout(function() {
                 resizeTimer = setTimeout(function() {
                     setOrientationClass(targetOrientation);
                     setOrientationClass(targetOrientation);
Zeile 472: Zeile 463:
                     initViewport();
                     initViewport();
                      
                      
                    New:
                     waitForDOMStability()
                     waitForDOMStability()
                         .then(function() {
                         .then(function() {
Zeile 574: Zeile 564:
         function getLinkage() {
         function getLinkage() {
             return linkage;
             return linkage;
        }
        /* --- List Repair --- */
       
        // MW parser ejects template-generated spans (Place) from list items:
        //  Pattern A (start): <li class="mw-empty-elt"/> + <p><span>...</span>text</p>
        //  Pattern B (end):  <li>text</li> + <p><span>...</span></p>
        // Both followed optionally by a continuation list.
        // This repairs the DOM before structure analysis.
        function repairListPlacement() {
            var $output = $('.mw-parser-output');
            if (!$output.length) return;
            var repaired = 0;
           
            function findEmptyItem($list) {
                var $li = $list.find('li.mw-empty-elt').last();
                if ($li.length) return $li;
                var $dd = $list.find('dd').filter(function() {
                    return this.childNodes.length === 0;
                }).last();
                return $dd.length ? $dd : null;
            }
           
            function isNestingWrapper(el) {
                if (el.tagName !== 'LI') return false;
                if (el.children.length !== 1) return false;
                if (!/^(UL|OL|DL)$/.test(el.firstElementChild.tagName)) return false;
                for (var i = 0; i < el.childNodes.length; i++) {
                    if (el.childNodes[i].nodeType === 3 && el.childNodes[i].textContent.trim()) return false;
                }
                return true;
            }
           
            $output.find('p').each(function() {
                var p = this;
                if (!p.parentNode) return;
                var first = p.firstChild;
                if (!first || first.nodeType !== 1) return;
                if (!first.classList.contains('place-lh') && !first.classList.contains('place-oc')) return;
               
                var $p = $(p);
                var $prevList = $p.prev('ul, ol, dl');
                if (!$prevList.length) return;
               
                // Pattern A: empty item (Place at start of list item)
                var $target = findEmptyItem($prevList);
                var isPatternA = $target !== null;
               
                // Pattern B: no empty item (Place at end of list item)
                if (!$target) {
                    $target = $prevList.find('li').last();
                    if (!$target.length) $target = $prevList.find('dd').last();
                    if (!$target.length) return;
                }
               
                if (isPatternA) $target.removeClass('mw-empty-elt');
               
                // Move <p> contents into target item
                while (p.firstChild) {
                    $target[0].appendChild(p.firstChild);
                }
               
                // Merge continuation list if same type follows
                var $next = $p.next();
                if ($next.length && $next[0].tagName === $prevList[0].tagName) {
                    var targetAtRoot = $target[0].parentNode === $prevList[0];
                   
                    var children = $next.children().get();
                    for (var i = 0; i < children.length; i++) {
                        if (isNestingWrapper(children[i])) {
                            var subList = children[i].firstElementChild;
                            if (targetAtRoot) {
                                // Pattern B: sub-list becomes child of target
                                $target[0].appendChild(subList);
                            } else {
                                // Pattern A: sub-list items become siblings
                                var parentList = $target[0].parentNode;
                                while (subList.firstChild) {
                                    parentList.appendChild(subList.firstChild);
                                }
                            }
                        } else {
                            $prevList[0].appendChild(children[i]);
                        }
                    }
                    $next.remove();
                }
               
                $p.remove();
                repaired++;
            });
           
         }
         }


Zeile 579: Zeile 661:
          
          
         function buildStructure() {
         function buildStructure() {
            repairListPlacement();
             var parserOutput = $('.mw-parser-output');
             var parserOutput = $('.mw-parser-output');
             var elements = parserOutput.children().toArray();
             var elements = parserOutput.children().toArray();
Zeile 665: Zeile 748:
                 }
                 }
             });
             });
           
                       
            console.log('Preprint Model: Structure built, ' + linkage.length + ' linkages');
           
             // Helper functions (closure)
             // Helper functions (closure)
             function ensureColumns() {
             function ensureColumns() {
Zeile 708: Zeile 789:
         function applyPortraitProjection() {
         function applyPortraitProjection() {
             if (layout && layout[0]) layout[0].style.paddingBottom = '';
             if (layout && layout[0]) layout[0].style.paddingBottom = '';
             // Clear inline positioning
            $('.preprint-oc-spacer').remove();
             // Clear inline positioning set by landscape projection
             linkage.forEach(function(link) {
             linkage.forEach(function(link) {
                link.element[0].style.top = '';
                 link.element[0].style.position = '';
                 link.element[0].style.position = '';
                link.element[0].style.top = '';
             });
             });
              
              
Zeile 764: Zeile 846:
              
              
             scrollToHash();
             scrollToHash();
            console.log('Preprint Model: Portrait projection applied');
         }
         }
          
          
Zeile 788: Zeile 869:
             }
             }
              
              
             positionOCElements();
             reconcileLayout();
              
              
             // Restore scroll
             // Restore scroll
Zeile 795: Zeile 876:
              
              
             scrollToHash();
             scrollToHash();
            console.log('Preprint Model: Landscape projection applied');
         }
         }
          
          
         function positionOCElements() {
         function reconcileLayout() {
             // Force reflow
            if (!document.body.classList.contains('preprint-landscape')) return;
             if (layout && layout[0]) {
            if (reconcileLayout._running) return;
                void layout[0].offsetHeight;
            reconcileLayout._running = true;
            }
           
            // Disconnect observer to prevent re-entry from our writes
            if (layout._ocObserver) layout._ocObserver.disconnect();
            // Save and reset scroll for accurate offset calculations (Minerva scrolls body)
            var savedBodyScroll = document.body.scrollTop;
            var savedHtmlScroll = document.documentElement.scrollTop;
            document.body.scrollTop = 0;
            document.documentElement.scrollTop = 0;
 
             // === PHASE 1: CLEAN + READ ===
           
            // Remove all previous-cycle artifacts
            $('.preprint-oc-spacer').remove();
             if (layout && layout[0]) layout[0].style.paddingBottom = '';
              
              
            // Position each element relative to its marker
             linkage.forEach(function(link) {
             linkage.forEach(function(link) {
                 var $marker = link.marker;
                 if (link.element[0].style.position !== 'absolute') {
                var $element = link.element;
                    link.element[0].style.position = 'absolute';
                 var $oc = $element.closest('.outer-column');
                    link.element[0].style.top = '0px';
               
                }
                 if (!$oc.length) return;
            });
               
           
                var markerOffset = $marker.offset();
            // Force reflow after cleanup
                var ocOffset = $oc.offset();
            void document.body.offsetHeight;
               
                       
                if (!markerOffset || !ocOffset) return;
            // Read marker positions, OC container offsets, element geometry
            var items = [];
            linkage.forEach(function(link, i) {
                 var $oc = link.element.closest('.outer-column');
                 if (!$oc.length) { items.push(null); return; }
                  
                  
                 var relativeTop = markerOffset.top - ocOffset.top;
                 var markerTop = link.marker.offset().top;
                var ocTop = $oc.offset().top;
                  
                  
                 $element.css({
                 items.push({
                     'position': 'absolute',
                    index: i,
                     'top': relativeTop + 'px'
                    link: link,
                    markerTop: markerTop,
                    ocTop: ocTop,
                    ocEl: $oc[0],
                    height: link.element.outerHeight(true),
                     margin: parseFloat(link.element.css('margin-top')) || 0,
                    landscapeDir: link.element.attr('data-landscape') || null,
                     top: markerTop - ocTop,
                    docTop: markerTop
                 });
                 });
             });
             });
              
              
             // Landscape placement overrides (elevator)
             // Read first visible IC child offset per OC container (for elevator)
             var landscapeOverrides = linkage.filter(function(link) {
             var ocContainers = [];
                 return link.element.attr('data-landscape');
            var ocFirstICTop = [];
            $('.outer-column').each(function() {
                 ocContainers.push(this);
                var $ic = $(this).prev('.inner-column');
                if (!$ic.length) { ocFirstICTop.push(0); return; }
                var ocTop = $(this).offset().top;
                var found = false;
                $ic.children().each(function() {
                    if (this.getBoundingClientRect().height > 0) {
                        ocFirstICTop.push($(this).offset().top - ocTop);
                        found = true;
                        return false;
                    }
                });
                if (!found) ocFirstICTop.push(0);
             });
             });
             if (landscapeOverrides.length > 0) {
              
                landscapeOverrides.forEach(function(link) {
            // Read protruding IC elements
                    var dir = link.element.attr('data-landscape');
            var protrusions = [];
                    var $oc = link.element.closest('.outer-column');
            $('.inner-column').each(function() {
                    if (!$oc.length) return;
                var icWidth = this.getBoundingClientRect().width;
                    var myTop = parseFloat(link.element.css('top')) || 0;
                $(this).children().each(function() {
                   
                    if (this.classList.contains('oc-marker')) return;
                    // Collect siblings in same column (excluding self), document-relative
                    var elWidth = this.scrollWidth || this.getBoundingClientRect().width;
                    var ocOffset = $oc.offset().top;
                    if (elWidth > icWidth + 1) {
                    var siblings = [];
                         var top = $(this).offset().top;
                    $oc.children('.place-oc, .place-lh, .preprint-table-oc-wrapper').each(function() {
                         protrusions.push({
                        var $el = $(this);
                             element: this,
                        if ($el[0] === link.element[0]) return;
                             top: top,
                        var rect = this.getBoundingClientRect();
                             bottom: top + this.getBoundingClientRect().height
                         var scrollY = window.pageYOffset || document.documentElement.scrollTop;
                         siblings.push({
                             el: $el,
                             top: rect.top + scrollY - ocOffset,
                             bottom: rect.bottom + scrollY - ocOffset
                         });
                         });
                    });
                    siblings.sort(function(a, b) { return a.top - b.top; });
                   
                    if (dir === 'top') {
                        // Find nearest sibling above
                        var above = null;
                        for (var i = siblings.length - 1; i >= 0; i--) {
                            if (siblings[i].top < myTop) { above = siblings[i]; break; }
                        }
                        var margin = parseFloat(link.element.css('margin-top')) || 0;
                        if (above) {
                            link.element.css('top', (above.bottom - margin) + 'px');
                        } else {
                            // No sibling above: align with first visible IC content
                            var $ic = $oc.prev('.inner-column');
                            var targetTop = 0;
                            if ($ic.length) {
                                $ic.children().each(function() {
                                    if (this.getBoundingClientRect().height > 0) {
                                        targetTop = this.getBoundingClientRect().top - $oc[0].getBoundingClientRect().top - margin;
                                        return false;
                                    }
                                });
                            }
                            link.element.css('top', targetTop + 'px');
                        }
                    } else if (dir === 'bottom') {
                        // Find nearest sibling below
                        var below = null;
                        for (var i = 0; i < siblings.length; i++) {
                            if (siblings[i].top > myTop) { below = siblings[i]; break; }
                        }
                        if (below) {
                            link.element.css('top', (below.top - link.element.outerHeight(true)) + 'px');
                        }
                        // If none below, stays at marker position (already at bottom)
                     }
                     }
                 });
                 });
             }
             });
           
            // === PHASE 2: COMPUTE (no DOM access) ===
              
              
             // Fix overlaps
             // Elevator adjustments
             fixOverlaps();
             items.forEach(function(item) {
            // Correct OC position to align with adjacent IC content
                if (!item || !item.landscapeDir) return;
            linkage.forEach(function(link) {
               
                var nextIC = link.marker[0].nextElementSibling;
                var siblings = items.filter(function(other) {
                 if (!nextIC) return;
                    return other && other.ocEl === item.ocEl && other.index !== item.index;
                 // Only correct for block-level siblings (tables, divs), not inline elements within a paragraph
                 }).sort(function(a, b) { return a.top - b.top; });
                 if (nextIC.parentNode && nextIC.parentNode.tagName === 'P') return;
                  
                var ocEl = link.element[0];
                 if (item.landscapeDir === 'top') {
                var icInner = nextIC.querySelector('table') || nextIC;
                    var above = null;
                var ocInner = ocEl.querySelector('table') || ocEl;
                    for (var i = siblings.length - 1; i >= 0; i--) {
                var delta = icInner.getBoundingClientRect().top - ocInner.getBoundingClientRect().top;
                        if (siblings[i].top < item.top) { above = siblings[i]; break; }
                 if (Math.abs(delta) > 1) {
                    }
                     var current = parseFloat(link.element.css('top')) || 0;
                    if (above) {
                     link.element.css('top', (current + delta) + 'px');
                        item.top = above.top + above.height - item.margin;
                    } else {
                        var ocIdx = ocContainers.indexOf(item.ocEl);
                        if (ocIdx >= 0) {
                            item.top = ocFirstICTop[ocIdx] - item.margin;
                        }
                    }
                 } else if (item.landscapeDir === 'bottom') {
                     var below = null;
                    for (var i = 0; i < siblings.length; i++) {
                        if (siblings[i].top > item.top) { below = siblings[i]; break; }
                    }
                     if (below) {
                        item.top = below.top - item.height;
                    }
                 }
                 }
                item.docTop = item.ocTop + item.top;
             });
             });
            adjustLayoutPadding();
              
              
             // Watch for collapsible table expand/collapse
             // Fix overlaps (type-pair minimum gaps)
             if (!layout._ocObserver) {
             var valid = items.filter(function(item) { return item !== null; });
                 layout._ocObserver = new MutationObserver(adjustLayoutPadding);
            valid.sort(function(a, b) { return a.docTop - b.docTop; });
                 layout._ocObserver.observe(layout[0], { subtree: true, attributes: true, attributeFilter: ['class'] });
           
            function elementGap(item) {
                 if (item.link.type === 'place-lh') return 2;
                 if (item.height >= 50) return 16;
                return 4;
             }
             }
        }
       
        function fixOverlaps() {
            // Force reflow first
            void document.body.offsetHeight;
              
              
             // Collect elements with document-relative positions
             var lastItem = null;
             var scrollY = window.pageYOffset || document.documentElement.scrollTop;
             valid.forEach(function(item) {
             var allOC = [];
                if (lastItem) {
             $('.outer-column').each(function() {
                    var minGap = Math.max(elementGap(item), elementGap(lastItem));
                 var $oc = $(this);
                    var requiredTop = lastItem.docTop + lastItem.height + minGap;
                $oc.children('.place-oc, .place-lh, .preprint-table-oc-wrapper').each(function() {
                    var overlap = requiredTop - item.docTop;
                     var $el = $(this);
                    if (overlap > 0) {
                     var rect = this.getBoundingClientRect();
                        item.top += overlap;
                    allOC.push({
                        item.docTop += overlap;
                        el: $el,
                    }
                        oc: $oc,
                }
                        top: rect.top + scrollY,
                lastItem = item;
                        bottom: rect.bottom + scrollY
            });
                    });
           
            // Conflict detection: protruding IC vs computed OC positions
             var spacers = [];
             protrusions.forEach(function(prot) {
                 var maxConflictBottom = 0;
                valid.forEach(function(item) {
                    var ocBottom = item.docTop + item.height;
                    if (prot.top < ocBottom && prot.bottom > item.docTop) {
                        if (ocBottom > maxConflictBottom) maxConflictBottom = ocBottom;
                    }
                });
                if (maxConflictBottom > 0) {
                     var pushdown = maxConflictBottom - prot.top;
                    if (pushdown > 0) {
                        spacers.push({ element: prot.element, height: pushdown });
                     }
                }
            });
           
            // === PHASE 3: WRITE (single pass) ===
           
            // Set OC positions
            valid.forEach(function(item) {
                item.link.element.css({
                    'position': 'absolute',
                    'top': item.top + 'px'
                 });
                 });
             });
             });
            // Sort by document-relative top
            allOC.sort(function(a, b) { return a.top - b.top; });
              
              
             // Fix overlaps using document-relative positions
             // Insert spacers
             var lastBottom = 0;
             spacers.forEach(function(s) {
            allOC.forEach(function(item, index) {
                 var spacer = document.createElement('div');
                 var overlap = lastBottom - item.top;
                 spacer.className = 'preprint-oc-spacer';
                 if (overlap > 0) {
                spacer.style.height = s.height + 'px';
                    // Push down by overlap amount
                s.element.parentNode.insertBefore(spacer, s.element);
                    var currentTop = parseFloat(item.el.css('top')) || 0;
            });
                    item.el.css('top', (currentTop + overlap) + 'px');
           
                    item.top += overlap;
            // Final measure: layout padding
                    item.bottom += overlap;
            void document.body.offsetHeight;
                }
            var scrollY = window.pageYOffset || 0;
               
            var layoutBottom = layout[0].getBoundingClientRect().bottom + scrollY;
                // Gap 4px
            var maxOCBottom = 0;
                var nextIsTable = (index + 1 < allOC.length) &&
            valid.forEach(function(item) {
                    allOC[index + 1].el.hasClass('preprint-table-oc-wrapper');
                 var rect = item.link.element[0].getBoundingClientRect();
                var gap = 4;
                 if (rect.bottom + scrollY > maxOCBottom) maxOCBottom = rect.bottom + scrollY;
                  
                 lastBottom = item.bottom + gap;
             });
             });
        }
            if (maxOCBottom > layoutBottom) {
 
                layout[0].style.paddingBottom = (maxOCBottom - layoutBottom) + 'px';
        function adjustLayoutPadding() {
             }
            var el = document.querySelector('.preprint-layout');
           
             if (!el) return;
            // Restore scroll
             var layoutRect = el.getBoundingClientRect();
             document.body.scrollTop = savedBodyScroll;
             var currentPad = parseFloat(el.style.paddingBottom || 0);
             document.documentElement.scrollTop = savedHtmlScroll;
             var maxBottom = 0;
             reconcileLayout._running = false;
             $('.outer-column .place-oc, .outer-column .place-lh, .outer-column .preprint-table-oc-wrapper').each(function() {
              
                var rect = this.getBoundingClientRect();
            // Reconnect or create observer
                 if (rect.bottom > maxBottom) maxBottom = rect.bottom;
            if (!layout._ocObserver) {
                layout._ocObserver = new MutationObserver(function() {
                    clearTimeout(layout._ocDebounce);
                    layout._ocDebounce = setTimeout(reconcileLayout, 300);
                 });
            }
            layout._ocObserver.observe(layout[0], {
                subtree: true, attributes: true, attributeFilter: ['class']
             });
             });
             var overflow = maxBottom - layoutRect.bottom + currentPad;
              
             if (overflow > 0) {
            // ResizeObserver: catches container width changes not visible to
                 el.style.paddingBottom = overflow + 'px';
            // window resize (TOC pin/unpin, tool menu toggle, DevTools panel).
            // Created once, never disconnected — only fires on actual size change.
             if (!layout._resizeObserver && typeof ResizeObserver !== 'undefined') {
                 layout._resizeObserver = new ResizeObserver(function() {
                    clearTimeout(layout._resizeDebounce);
                    layout._resizeDebounce = setTimeout(function() {
                        if (PAL.isOrientationLocked()) return;
                        if (document.body.classList.contains('preprint-landscape')) {
                            reconcileLayout();
                        }
                    }, 200);
                });
                layout._resizeObserver.observe(layout[0]);
             }
             }
         }
         }
Zeile 979: Zeile 1.111:
         $('.preprint-layout img').on('load', function() {
         $('.preprint-layout img').on('load', function() {
             if (document.body.classList.contains('preprint-landscape')) {
             if (document.body.classList.contains('preprint-landscape')) {
                 positionOCElements();
                 reconcileLayout();
             }
             }
         });
         });
Zeile 990: Zeile 1.122:
                     if (PAL.isOrientationLocked()) return;
                     if (PAL.isOrientationLocked()) return;
                     if (document.body.classList.contains('preprint-landscape')) {
                     if (document.body.classList.contains('preprint-landscape')) {
                         positionOCElements();
                         reconcileLayout();
                     }
                     }
                 }, 200);
                 }, 200);
Zeile 1.003: Zeile 1.135:
                     el.scrollIntoView({ block: 'start' });
                     el.scrollIntoView({ block: 'start' });
                     window.scrollBy(0, -60);
                     window.scrollBy(0, -60);
                    console.log('Preprint Model: Scrolled to return target ' + returnTarget);
                 }
                 }
                 returnTarget = null;
                 returnTarget = null;
Zeile 1.015: Zeile 1.146:
                 target.scrollIntoView({ block: 'start' });
                 target.scrollIntoView({ block: 'start' });
                 window.scrollBy(0, -60);
                 window.scrollBy(0, -60);
                console.log('Preprint Model: Scrolled to hash ' + window.location.hash);
             }
             }
         }
         }
Zeile 1.128: Zeile 1.258:
             getLinkage: getLinkage,
             getLinkage: getLinkage,
             applyProjection: applyProjection,
             applyProjection: applyProjection,
             positionOCElements: positionOCElements,
             positionOCElements: reconcileLayout,
             captureAnchor: captureAnchor,
             captureAnchor: captureAnchor,
             restoreAnchor: restoreAnchor,
             restoreAnchor: restoreAnchor,
             getPositionAnchor: getPositionAnchor,
             getPositionAnchor: getPositionAnchor,
             getLayout: function() { return layout; },
             getLayout: function() { return layout; },
             set returnTarget(id) { returnTarget = id; }
             set returnTarget(id) { returnTarget = id; },
            pauseObserver: function() {
                if (layout && layout._ocObserver) layout._ocObserver.disconnect();
            },
            resumeObserver: function() {
                if (layout && layout[0] && layout._ocObserver) {
                    layout._ocObserver.observe(layout[0], {
                        subtree: true, attributes: true, attributeFilter: ['class']
                    });
                }
            }
         };
         };
     })();
     })();
Zeile 1.198: Zeile 1.338:
                 var $icon = $('<a class="book-nav-icon"></a>');
                 var $icon = $('<a class="book-nav-icon"></a>');
                 if (isBookRoot) {
                 if (isBookRoot) {
                     $icon.attr('href', '/');
                     var saved = sessionStorage.getItem('preprint-position');
                    if (saved) {
                        var pos = JSON.parse(saved);
                        $icon.attr('href', '/wiki/' + pos.article);
                    } else {
                        $icon.attr('href', '#');
                        $icon.addClass('book-nav-icon-disabled');
                    }
                 } else {
                 } else {
                     $icon.attr('href', '/wiki/' + book + (rootAnchor ? '#' + rootAnchor : ''));
                     $icon.attr('href', '/wiki/' + book + (rootAnchor ? '#' + rootAnchor : ''));
Zeile 1.213: Zeile 1.360:
                             var pos = JSON.parse(saved);
                             var pos = JSON.parse(saved);
                             window.location.href = '/wiki/' + pos.article;
                             window.location.href = '/wiki/' + pos.article;
                        } else {
                            window.location.href = '/';
                         }
                         }
                        // No action when disabled — no homepage fallback
                     });
                     });
                 } else {
                 } else {
Zeile 1.244: Zeile 1.390:
                 }
                 }
             }
             }
           
            console.log('Preprint Features: BookNav icon (root=' + isBookRoot + ')');
         }
         }


Zeile 1.311: Zeile 1.455:
              
              
             $landmark.before($link);
             $landmark.before($link);
             console.log('Preprint Features: Sidebar nav (root=' + isBookRoot + ')');
             if (mw.config.get('wgUserName')) {
                var style = document.createElement('style');
                style.textContent = '@media(max-width:790px){.book-nav-sidebar{display:none!important}}';
                document.head.appendChild(style);
            }
         }
         }


Zeile 1.453: Zeile 1.601:
                 // Mobile: root page IS the TOC, hide MW-generated one
                 // Mobile: root page IS the TOC, hide MW-generated one
                 $('.toc, #toc').hide();
                 $('.toc, #toc').hide();
                console.log('Preprint Features: TOC suppressed (bookRoot+Minerva)');
             } else if (isPreprintLayout && bookNavData.length && PAL.isMinerva()) {
             } else if (isPreprintLayout && bookNavData.length && PAL.isMinerva()) {
                 // Mobile book chapters: linear reading, no TOC
                 // Mobile book chapters: linear reading, no TOC
                 $('.toc, #toc').hide();
                 $('.toc, #toc').hide();
                console.log('Preprint Features: TOC suppressed (chapter+BookNav+Minerva)');
             }
             }
             // Desktop: TOC always visible (sticky sidebar navigation)
             // Desktop: TOC always visible (sticky sidebar navigation)
Zeile 1.502: Zeile 1.648:
             return;
             return;
         }
         }
       
               
        console.log('Preprint: PAL ready, building structure');
       
         // Build structure (Model)
         // Build structure (Model)
         Model.buildStructure();
         Model.buildStructure();
Zeile 1.512: Zeile 1.656:
         setTimeout(function() {
         setTimeout(function() {
             Model.applyProjection(initialMode);
             Model.applyProjection(initialMode);
            Model.pauseObserver();
             $('.preprint-layout').addClass('preprint-ready');
             $('.preprint-layout').addClass('preprint-ready');
            Model.resumeObserver();
             window.preprintReadyAt = performance.now();
             window.preprintReadyAt = performance.now();
         }, 50);
         }, 50);
Zeile 1.556: Zeile 1.702:
          
          
         PAL.onProjectionChange(function(event) {
         PAL.onProjectionChange(function(event) {
            console.log('Preprint: Projection change ' + event.from + ' -> ' + event.to);
              
              
             // Icon already hidden by onPreProjectionChange
             // Icon already hidden by onPreProjectionChange
Zeile 1.569: Zeile 1.714:
                     Features.calculateIconMetrics();
                     Features.calculateIconMetrics();
                     if (icon) icon.style.visibility = '';
                     if (icon) icon.style.visibility = '';
                    Model.positionOCElements();
                 }, 100);
                 }, 100);
             } else {
             } else {
Zeile 1.602: Zeile 1.748:
         });
         });
          
          
         mw.loader.load('/wiki/MediaWiki:Common.js/debug.js?action=raw&ctype=text/javascript');         
         // mw.loader.load('/wiki/MediaWiki:Common.js/debug.js?action=raw&ctype=text/javascript');         
        console.log('Preprint: Initialization complete (v7.17)');
     });
     });


})();
})();


/* === PREPRINT END === */


/* === PREPRINT END === */




/* Unified Consent System JavaScript v250911r1
/* === CONSENT START === */
/* Unified Consent System JavaScript v260224r1
  * Single file for both EN and DE versions
  * Single file for both EN and DE versions
  * Automatically detects language based on domain
  * Automatically detects language based on domain
Zeile 1.651: Zeile 1.797:
}
}


// Handle consent acquisition box - 90-day reminder for everyone
// Handle consent acquisition box - 90-day reminder for visitors (spec §8.9)
$(document).ready(function() {
$(document).ready(function() {
     var consentBox = document.getElementById('consent-acquisition-box');
     var consentBox = document.getElementById('consent-acquisition-box');
Zeile 1.673: Zeile 1.819:
         // ADD THIS LINE:
         // ADD THIS LINE:
         localStorage.setItem('consent-acquisition-dismissed-until', Date.now() + (90 * 24 * 60 * 60 * 1000));
         localStorage.setItem('consent-acquisition-dismissed-until', Date.now() + (90 * 24 * 60 * 60 * 1000));
         var targetPage = getCurrentLanguage() === 'de' ?  
         if (mw.config.get('wgUserName')) {
            '/wiki/Transformal_GmbH:Einstellungen' :  
            window.location.href = '/wiki/Special:Preferences#mw-prefsection-legal';
            '/wiki/Transformal_GmbH:Settings';
        } else {
        window.location.href = targetPage;
            var targetPage = getCurrentLanguage() === 'de' ?  
                '/wiki/Transformal_GmbH:Einstellungen' :  
                '/wiki/Transformal_GmbH:Settings';
            window.location.href = targetPage;
        }
     });
     });
});
});
Zeile 1.774: Zeile 1.924:
     }
     }
}
}
/* === CONSENT END === */
/* === CONDITIONAL START === */


/* Template 'ConditionalContent' - v250925r8 */
/* Template 'ConditionalContent' - v250925r8 */
Zeile 1.834: Zeile 1.988:
     }
     }
});
});
/* === CONDITIONAL END === */