Aktionen

MediaWiki

MediaWiki:Common.js

Aus exmediawiki

Version vom 24. Juli 2025, 13:57 Uhr von Christopher.theophanous (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
// Material Archive Overview

// Materials collapsible functionality with cursor tooltip and search
$(document).ready(function() {
    // Only run on pages that have materials containers
    if ($('.materials-container').length === 0) {
        return; // Exit if no materials containers found
    }
    
    // Create navigation dynamically using custom tag with line breaks
    var navigationHtml ='<br><nav-item><a href="#search-section" class="nav-link">Search</a></nav-item><br>' +
                        '<nav-item><a href="#materials-section" class="nav-link">Materials</a></nav-item><br>' +
                        '<nav-item><a href="#resources-section" class="nav-link">Resources</a></nav-item><br>' +
                        '<nav-item><a href="#about-section" class="nav-link">About</a></nav-item>' +
                        '<br><br>';
    
    // Insert navigation at the very top of the page content
    $('#mw-content-text').prepend(navigationHtml);
    
    // Create anchor points
    var anchorsHtml = '<div id="search-section"></div><div id="materials-section"></div>' +
                     '<div id="resources-section"></div><div id="about-section"></div>';
    
    // Insert anchor points before first materials container
    $('.materials-container').first().before(anchorsHtml);
    
    // Create search bar dynamically
    var searchHtml = '<div class="search-container">' +
                     '<input type="text" id="material-search" placeholder="Search materials..." autocomplete="off">' +
                     '<div class="search-suggestions"></div>' +
                     '</div>';
    
    // Insert search bar before the first materials container (after anchors)
    $('#search-section').after(searchHtml);
    
    // Navigation scroll functionality
    $(document).on('click', '.nav-link', function(e) {
        e.preventDefault();
        var targetId = $(this).attr('href');
        var $target = $(targetId);
        
        if ($target.length) {
            $('html, body').animate({
                scrollTop: $target.offset().top - 20 // 20px offset from top
            }, 800); // 800ms smooth animation
        }
    });
    
    // Initialize - hide all children AND sub-parents, ensure parents are collapsed
    $('.material-child').hide();
    $('.material-parent[data-parent]').hide(); // Hide sub-parents (like Veneer)
    $('.material-parent').removeClass('expanded');
    
    // Create tooltip element
    var $tooltip = $('<div class="cursor-image-tooltip"></div>');
    $('body').append($tooltip);
    
    // Build search data from all material children
    var searchData = [];
    $('.material-child').each(function() {
        var $child = $(this);
        var title = $child.find('h3').text().replace(/\[\[|\]\]/g, ''); // Remove wiki brackets
        var parent = $child.data('parent');
        var parentText = $('.material-parent[data-category="' + parent + '"] h3').text();
        
        searchData.push({
            title: title,
            element: $child,
            parent: parent,
            parentText: parentText,
            parentElement: $('.material-parent[data-category="' + parent + '"]')
        });
    });
    
    // Search functionality
    var $searchInput = $('#material-search');
    var $searchSuggestions = $('.search-suggestions');
    
    $searchInput.on('input', function() {
        var query = $(this).val().toLowerCase().trim();
        
        if (query.length === 0) {
            $searchSuggestions.hide().empty();
            return;
        }
        
        // Filter search data
        var matches = searchData.filter(function(item) {
            return item.title.toLowerCase().includes(query) || 
                   item.parentText.toLowerCase().includes(query);
        });
        
        if (matches.length > 0) {
            $searchSuggestions.empty().show();
            
            // Limit to first 8 results
            matches.slice(0, 8).forEach(function(match) {
                var $suggestion = $('<div class="search-suggestion"></div>');
                $suggestion.html('<span class="suggestion-title">' + match.title + '</span>' +
                               '<span class="suggestion-category">' + match.parentText + '</span>');
                
                $suggestion.on('click', function() {
                    // Expand parent if not expanded
                    if (!match.parentElement.hasClass('expanded')) {
                        match.parentElement.addClass('expanded');
                        $('.material-child[data-parent="' + match.parent + '"]').show();
                    }
                    
                    // Scroll to element
                    $('html, body').animate({
                        scrollTop: match.element.offset().top - 100
                    }, 500);
                    
                    // Highlight element briefly
                    match.element.addClass('highlighted');
                    setTimeout(function() {
                        match.element.removeClass('highlighted');
                    }, 2000);
                    
                    // Clear search
                    $searchInput.val('');
                    $searchSuggestions.hide().empty();
                });
                
                $searchSuggestions.append($suggestion);
            });
        } else {
            $searchSuggestions.hide().empty();
        }
    });
    
    // Hide suggestions when clicking outside
    $(document).on('click', function(e) {
        if (!$(e.target).closest('.search-container').length) {
            $searchSuggestions.hide();
        }
    });
    
// Handle material parent clicks
$('.material-parent').on('click', function() {
    var $parent = $(this);
    var category = $parent.data('category');
    
    // Toggle expanded state
    $parent.toggleClass('expanded');
    
    // Show/hide direct children AND sub-parents
    var $directChildren = $('.material-child[data-parent="' + category + '"], .material-parent[data-parent="' + category + '"]');
    
    if ($parent.hasClass('expanded')) {
        $directChildren.show();
    } else {
        $directChildren.hide();
        
        // When collapsing, also collapse and hide any sub-parents and their children
        $('.material-parent[data-parent="' + category + '"]').each(function() {
            var $subParent = $(this);
            var subCategory = $subParent.data('category');
            
            // Remove expanded class from sub-parent
            $subParent.removeClass('expanded');
            
            // Hide sub-parent's children
            $('.material-child[data-parent="' + subCategory + '"]').hide();
        });
    }
});
    
    // Handle cursor tooltip for material children
    $('.material-child').on('mouseenter', function(e) {
        var $child = $(this);
        var $imagePreview = $child.find('.image-preview');
        
        if ($imagePreview.length > 0) {
            // Copy the image content to tooltip
            $tooltip.html($imagePreview.html());
            $tooltip.show();
            
            // Position tooltip with offset - image appears lower than cursor
            // Offset by half the image height (100px) plus some extra space
            $tooltip.css({
                left: (e.clientX + 10) + 'px',  // 10px right of cursor
                top: (e.clientY + 60) + 'px'   // 60px below cursor (half height + spacing)
            });
        }
    });
    
    $('.material-child').on('mousemove', function(e) {
        if ($tooltip.is(':visible')) {
            // Follow cursor with consistent offset
            $tooltip.css({
                left: (e.clientX + 10) + 'px',  // 10px right of cursor
                top: (e.clientY + 60) + 'px'   // 60px below cursor (half height + spacing)
            });
        }
    });
    
    $('.material-child').on('mouseleave', function() {
        $tooltip.hide();
    });
});


// Individual material page

// MediaWiki Slideshow Gallery - PAGE SPECIFIC ONLY
// Add this to MediaWiki:Common.js

(function() {
    'use strict';
    
    // Check if current page should have slideshow functionality
    function shouldLoadSlideshow() {
        return document.body && (
            document.body.classList.contains('slideshow-gallery-page') || 
            document.querySelector('.slideshow-gallery-page') !== null ||
            document.querySelector('.slideshow-container') !== null
        );
    }

    // Only load slideshow code if needed
    if (!shouldLoadSlideshow()) {
        return;
    }

    console.log('Loading slideshow gallery for this page');

    // Wait for MediaWiki and jQuery to be ready
    function initWhenReady() {
        if (typeof mw === 'undefined' || typeof $ === 'undefined') {
            setTimeout(initWhenReady, 100);
            return;
        }
        
        // MediaWiki hook
        mw.hook('wikipage.content').add(function($content) {
            initSlideshows($content);
        });

        // jQuery ready
        $(document).ready(function() {
            initSlideshows($(document));
        });
    }

    function initSlideshows($context) {
        $context = $context || $(document);
        
        // Only initialize slideshow containers on pages with the specific class
        var $galleryPages = $context.find('.slideshow-gallery-page, body.slideshow-gallery-page');
        if ($galleryPages.length === 0 && !$context.hasClass('slideshow-gallery-page')) {
            // Also check for direct slideshow containers as fallback
            if ($context.find('.slideshow-container').length === 0) {
                return;
            }
        }
        
        // Initialize each slideshow container
        $context.find('.slideshow-container').each(function() {
            if (!$(this).data('slideshow-initialized')) {
                $(this).data('slideshow-initialized', true);
                initSingleSlideshow(this);
            }
        });
    }

    function initSingleSlideshow(container) {
        var slides = container.querySelectorAll('.mySlides');
        var thumbnails = container.querySelectorAll('.demo');
        var captionText = container.querySelector('#caption, .caption');
        var slideIndex = 1;
        
        console.log('Initializing slideshow with', slides.length, 'slides');
        
        if (slides.length === 0) {
            console.log('No slides found in slideshow container');
            return;
        }
        
        // Show first slide initially
        showSlides(slideIndex);
        
        // Add click handlers to navigation buttons
        var prevBtn = container.querySelector('.prev');
        var nextBtn = container.querySelector('.next');
        
        if (prevBtn) {
            prevBtn.addEventListener('click', function(e) {
                e.preventDefault();
                plusSlides(-1);
            });
        }
        
        if (nextBtn) {
            nextBtn.addEventListener('click', function(e) {
                e.preventDefault();
                plusSlides(1);
            });
        }
        
        // Add click handlers to thumbnails
        for (var i = 0; i < thumbnails.length; i++) {
            (function(index) {
                thumbnails[index].addEventListener('click', function() {
                    currentSlide(index + 1);
                });
            })(i);
        }
        
        // Keyboard navigation
        container.addEventListener('keydown', function(e) {
            if (e.keyCode === 37) { // Left arrow
                plusSlides(-1);
                e.preventDefault();
            } else if (e.keyCode === 39) { // Right arrow
                plusSlides(1);
                e.preventDefault();
            }
        });
        
        // Make container focusable for keyboard navigation
        container.setAttribute('tabindex', '0');
        
        // Touch/swipe support
        var startX = 0;
        var endX = 0;
        
        container.addEventListener('touchstart', function(e) {
            startX = e.touches[0].clientX;
        });
        
        container.addEventListener('touchmove', function(e) {
            e.preventDefault();
        });
        
        container.addEventListener('touchend', function(e) {
            endX = e.changedTouches[0].clientX;
            var diffX = startX - endX;
            
            if (Math.abs(diffX) > 50) {
                if (diffX > 0) {
                    plusSlides(1); // Swipe left = next
                } else {
                    plusSlides(-1); // Swipe right = previous
                }
            }
        });
        
        // Auto-play functionality (if data-autoplay attribute is set)
        var autoPlayInterval;
        var autoPlayDelay = container.getAttribute('data-autoplay');
        
        if (autoPlayDelay) {
            function startAutoPlay() {
                autoPlayInterval = setInterval(function() {
                    plusSlides(1);
                }, parseInt(autoPlayDelay));
            }
            
            function stopAutoPlay() {
                if (autoPlayInterval) {
                    clearInterval(autoPlayInterval);
                    autoPlayInterval = null;
                }
            }
            
            container.addEventListener('mouseenter', stopAutoPlay);
            container.addEventListener('mouseleave', startAutoPlay);
            
            startAutoPlay();
        }
        
        // Next/previous controls
        function plusSlides(n) {
            showSlides(slideIndex += n);
        }
        
        // Thumbnail image controls
        function currentSlide(n) {
            showSlides(slideIndex = n);
        }
        
        function showSlides(n) {
            var i;
            
            if (n > slides.length) { 
                slideIndex = 1; 
            }
            if (n < 1) { 
                slideIndex = slides.length; 
            }
            
            // Hide all slides
            for (i = 0; i < slides.length; i++) {
                slides[i].style.display = "none";
                slides[i].classList.remove('active');
            }
            
            // Remove active class from all thumbnails
            for (i = 0; i < thumbnails.length; i++) {
                thumbnails[i].classList.remove('active-thumb');
            }
            
            // Show current slide
            if (slides[slideIndex - 1]) {
                slides[slideIndex - 1].style.display = "block";
                slides[slideIndex - 1].classList.add('active');
            }
            
            // Highlight current thumbnail
            if (thumbnails[slideIndex - 1]) {
                thumbnails[slideIndex - 1].classList.add('active-thumb');
            }
            
            // Update caption
            if (captionText && thumbnails[slideIndex - 1]) {
                captionText.innerHTML = thumbnails[slideIndex - 1].getAttribute('alt') || '';
            }
            
            console.log('Showing slide', slideIndex, 'of', slides.length);
        }
    }

    // Start initialization
    initWhenReady();

})();