MediaWiki:Common.js

From Toon Wiki
Revision as of 23:17, 22 December 2025 by Admin (talk | contribs) (Interactive features)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/* ============================================
   TOON WIKI - INTERACTIVE FEATURES
   ============================================ */

$(document).ready(function() {
    
    /* ===== Infobox Gallery Tabs ===== */
    function initInfoboxTabs() {
        $('.infobox-image .gallery').each(function() {
            var $gallery = $(this);
            var $items = $gallery.find('.gallerybox');
            
            if ($items.length < 2) return;
            
            // Create tab navigation
            var $tabs = $('<div class="infobox-tabs"></div>');
            
            $items.each(function(index) {
                var $item = $(this);
                var label = $item.find('.gallerytext p').text().trim() || ('Image ' + (index + 1));
                
                var $btn = $('<button class="tab-btn"></button>')
                    .text(label)
                    .attr('data-index', index)
                    .on('click', function() {
                        var idx = $(this).data('index');
                        $items.removeClass('active').hide();
                        $items.eq(idx).addClass('active').show();
                        $tabs.find('.tab-btn').removeClass('active');
                        $(this).addClass('active');
                    });
                
                if (index === 0) {
                    $btn.addClass('active');
                    $item.addClass('active').show();
                } else {
                    $item.hide();
                }
                
                $tabs.append($btn);
            });
            
            $gallery.parent().append($tabs);
        });
    }
    
    /* ===== Smooth Scroll for TOC Links ===== */
    function initSmoothScroll() {
        $('a[href^="#"]').on('click', function(e) {
            var target = $(this.hash);
            if (target.length) {
                e.preventDefault();
                $('html, body').animate({
                    scrollTop: target.offset().top - 60
                }, 400);
            }
        });
    }
    
    /* ===== Back to Top Button ===== */
    function initBackToTop() {
        var $btn = $('<button id="back-to-top" title="Back to top">↑</button>')
            .css({
                position: 'fixed',
                bottom: '20px',
                right: '20px',
                width: '44px',
                height: '44px',
                background: '#611e03',
                color: 'white',
                border: 'none',
                borderRadius: '50%',
                fontSize: '20px',
                cursor: 'pointer',
                display: 'none',
                zIndex: 9999,
                boxShadow: '0 2px 10px rgba(0,0,0,0.2)',
                transition: 'all 0.2s ease'
            })
            .on('click', function() {
                $('html, body').animate({ scrollTop: 0 }, 400);
            })
            .on('mouseenter', function() {
                $(this).css({ transform: 'scale(1.1)', background: '#8b4513' });
            })
            .on('mouseleave', function() {
                $(this).css({ transform: 'scale(1)', background: '#611e03' });
            });
        
        $('body').append($btn);
        
        $(window).on('scroll', function() {
            if ($(this).scrollTop() > 300) {
                $btn.fadeIn(200);
            } else {
                $btn.fadeOut(200);
            }
        });
    }
    
    /* ===== Image Lightbox ===== */
    function initLightbox() {
        var $overlay = $('<div id="lightbox-overlay"></div>').css({
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            background: 'rgba(0,0,0,0.9)',
            zIndex: 99999,
            display: 'none',
            cursor: 'zoom-out',
            justifyContent: 'center',
            alignItems: 'center'
        });
        
        var $img = $('<img id="lightbox-img">').css({
            maxWidth: '90%',
            maxHeight: '90%',
            boxShadow: '0 0 30px rgba(0,0,0,0.5)',
            borderRadius: '4px'
        });
        
        var $close = $('<button>&times;</button>').css({
            position: 'absolute',
            top: '20px',
            right: '30px',
            background: 'none',
            border: 'none',
            color: 'white',
            fontSize: '40px',
            cursor: 'pointer',
            lineHeight: 1
        });
        
        $overlay.append($img, $close);
        $('body').append($overlay);
        
        // Click handler for images
        $('.mw-parser-output img').not('.mw-file-element[width="20"]').on('click', function(e) {
            var fullSrc = $(this).closest('a').attr('href');
            if (fullSrc && fullSrc.match(/\.(png|jpg|jpeg|gif|webp)/i)) {
                e.preventDefault();
                $img.attr('src', fullSrc);
                $overlay.css('display', 'flex');
                $('body').css('overflow', 'hidden');
            }
        });
        
        // Close handlers
        $overlay.on('click', function(e) {
            if (e.target === this || e.target === $close[0]) {
                $overlay.hide();
                $('body').css('overflow', '');
            }
        });
        
        $(document).on('keydown', function(e) {
            if (e.key === 'Escape') {
                $overlay.hide();
                $('body').css('overflow', '');
            }
        });
    }
    
    /* ===== Reading Progress Bar ===== */
    function initProgressBar() {
        var $bar = $('<div id="reading-progress"></div>').css({
            position: 'fixed',
            top: 0,
            left: 0,
            height: '3px',
            background: 'linear-gradient(90deg, #ff9900, #611e03)',
            width: '0%',
            zIndex: 99998,
            transition: 'width 0.1s ease'
        });
        
        $('body').append($bar);
        
        $(window).on('scroll', function() {
            var winHeight = $(window).height();
            var docHeight = $(document).height();
            var scrollTop = $(window).scrollTop();
            var progress = (scrollTop / (docHeight - winHeight)) * 100;
            $bar.css('width', Math.min(progress, 100) + '%');
        });
    }
    
    /* ===== Current Section Highlight ===== */
    function initSectionHighlight() {
        var $sections = $('h2, h3').filter(function() {
            return $(this).attr('id');
        });
        
        var $tocLinks = $('.toc a, .mw-toc a');
        
        $(window).on('scroll', function() {
            var scrollPos = $(window).scrollTop() + 100;
            
            $sections.each(function() {
                var $section = $(this);
                var sectionTop = $section.offset().top;
                var sectionId = $section.attr('id');
                
                if (scrollPos >= sectionTop) {
                    $tocLinks.removeClass('toc-active');
                    $tocLinks.filter('[href="#' + sectionId + '"]').addClass('toc-active');
                }
            });
        });
        
        // Add CSS for active TOC link
        $('<style>.toc-active { font-weight: bold; color: #611e03 !important; }</style>').appendTo('head');
    }
    
    /* ===== Initialize All Features ===== */
    initInfoboxTabs();
    initSmoothScroll();
    initBackToTop();
    initLightbox();
    initProgressBar();
    initSectionHighlight();
    
    console.log('Toon Wiki enhancements loaded');
});