MediaWiki:Common.js: Difference between revisions

From Ultimate Dragon Ball Online Wiki

Ravenalien (talk | contribs)
No edit summary
Ravenalien (talk | contribs)
No edit summary
 
(17 intermediate revisions by the same user not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */
/* Tab Navigation System*/
 
(function() {
$(document).ready(function() {
     'use strict';
     'use strict';
      
      
     // Initialize when document is ready
     // Main race tab click handler (works for both regular and image buttons)
     $(document).ready(function() {
     $('.tab-navigation .tab-button, .tab-navigation .tab-button-image').click(function(e) {
         initializeTabs();
        e.preventDefault();
         initializeSubTabs();
       
        var targetId = $(this).data('target');
       
        // Update main race tabs (for both button types)
        $('.tab-navigation .tab-button, .tab-navigation .tab-button-image').removeClass('active');
        $(this).addClass('active');
       
        // Update main content panes
        $('.tab-content > .tab-pane').removeClass('active');
        $('#' + targetId).addClass('active');
       
        // Always activate the overview tab for the selected race
        var $subNav = $('#' + targetId + ' .sub-tab-navigation');
        var $overviewTab;
       
        // Check if using image tabs or regular tabs
        if ($subNav.find('.tab-button-image').length) {
            $overviewTab = $subNav.find('.tab-button-image').first();
         } else {
            $overviewTab = $subNav.find('.tab-button').first();
         }
       
        var overviewTargetId = $overviewTab.data('target');
       
        // Set overview tab and content as active
        $subNav.find('.tab-button, .tab-button-image').removeClass('active');
        $overviewTab.addClass('active');
       
        $subNav.find('.tab-content .tab-pane').removeClass('active');
        $('#' + overviewTargetId).addClass('active');
     });
     });
      
      
    // Create collapsible sections
    $('.collapsible-header').click(function() {
        $(this).toggleClass('collapsed');
        $(this).next('.collapsible-content').slideToggle(300);
       
        // Toggle the icon
        var $icon = $(this).find('.collapse-icon');
        if ($icon.text() === '▼') {
            $icon.text('►');
        } else {
            $icon.text('▼');
        }
    });
   
    // Initialize all sections as expanded
    $('.collapsible-header').each(function() {
        $(this).find('.collapse-icon').text('▼');
    });
   
    // Sub-class tab click handler (works for both regular and image buttons)
    $('.sub-tab-navigation .tab-button, .sub-tab-navigation .tab-button-image').click(function(e) {
        e.preventDefault();
        e.stopPropagation();
       
        var $this = $(this);
        var $subNav = $this.closest('.sub-tab-navigation');
        var targetId = $this.data('target');
       
        // Only update the buttons in this sub-tab navigation
        $subNav.find('.tab-button, .tab-button-image').removeClass('active');
        $this.addClass('active');
       
        // Find and update only the content panes within this sub-tab section
        $subNav.find('.tab-content .tab-pane').removeClass('active');
        $('#' + targetId).addClass('active');
       
        // Keep the parent tab-pane active
        $this.closest('.tab-pane').addClass('active');
    });
   
    // Initial setup
     function initializeTabs() {
     function initializeTabs() {
         // Find all tab containers on the page
         // Set first race tab active if none are
         $('.tab-navigation').each(function(index) {
         var $mainNav = $('.tab-navigation');
             var tabContainerId = 'tab-container-' + index;
        if (!$mainNav.find('.tab-button.active, .tab-button-image.active').length) {
             $(this).attr('id', tabContainerId);
            if ($mainNav.find('.tab-button-image').length) {
                var $firstMainTab = $mainNav.find('.tab-button-image').first();
                $firstMainTab.addClass('active');
             } else {
                var $firstMainTab = $mainNav.find('.tab-button').first();
                $firstMainTab.addClass('active');
            }
           
            var mainTargetId = $firstMainTab.data('target');
             $('#' + mainTargetId).addClass('active');
              
              
             var $container = $('#' + tabContainerId);
            // Set its overview tab active
            var $tabButtons = $container.find('> .tab-nav > .tab-button');
             var $subNav = $('#' + mainTargetId + ' .sub-tab-navigation');
             var $tabPanes = $container.find('> .tab-content > .tab-pane');
             var $overviewTab;
              
              
             // Add click handlers to tab buttons
             // Check if using image tabs or regular tabs
             $tabButtons.on('click', function() {
             if ($subNav.find('.tab-button-image').length) {
                var $this = $(this);
                 $overviewTab = $subNav.find('.tab-button-image').first();
                var targetId = $this.data('target');
            } else {
               
                 $overviewTab = $subNav.find('.tab-button').first();
                // Remove active class from all buttons and panes in this container
             }
                $container.find('> .tab-nav > .tab-button').removeClass('active');
                 $container.find('> .tab-content > .tab-pane').removeClass('active');
               
                // Add active class to clicked button and corresponding pane
                $this.addClass('active');
                 $container.find('#' + targetId).addClass('active');
               
                // If this tab has a sub-tab that's active, ensure it's visible
                var $activeSubTab = $container.find('#' + targetId + ' .sub-tab-navigation .tab-button.active');
                if ($activeSubTab.length) {
                    $activeSubTab.trigger('click');
                }
             });
        });
    }
   
    // Initialize nested sub-tabs
    function initializeSubTabs() {
        $('.sub-tab-navigation').each(function(index) {
            var subTabContainerId = 'sub-tab-container-' + index;
            $(this).attr('id', subTabContainerId);
              
              
             var $container = $('#' + subTabContainerId);
             $overviewTab.addClass('active');
            var $tabButtons = $container.find('> .tab-nav > .tab-button');
            $('#' + $overviewTab.data('target')).addClass('active');
             var $tabPanes = $container.find('> .tab-content > .tab-pane');
        }
       
        // For each race tab that's active
        $('.tab-navigation .tab-button.active, .tab-navigation .tab-button-image.active').each(function() {
            var mainTargetId = $(this).data('target');
             var $mainContent = $('#' + mainTargetId);
              
              
             // Add click handlers to tab buttons
             // Ensure overview tab is active if no sub-tab is active
             $tabButtons.on('click', function() {
             var $subNav = $mainContent.find('.sub-tab-navigation');
                var $this = $(this);
            if ($subNav.length && !$subNav.find('.tab-button.active, .tab-button-image.active').length) {
                 var targetId = $this.data('target');
                 var $overviewTab;
                  
                  
                 // Remove active class from all buttons and panes in this container
                 // Check if using image tabs or regular tabs
                 $container.find('> .tab-nav > .tab-button').removeClass('active');
                 if ($subNav.find('.tab-button-image').length) {
                 $container.find('> .tab-content > .tab-pane').removeClass('active');
                    $overviewTab = $subNav.find('.tab-button-image').first();
                 } else {
                    $overviewTab = $subNav.find('.tab-button').first();
                }
                  
                  
                // Add active class to clicked button and corresponding pane
                 $overviewTab.addClass('active');
                 $this.addClass('active');
                 $('#' + $overviewTab.data('target')).addClass('active');
                 $container.find('#' + targetId).addClass('active');
               
                // Store the active tab state in session storage for persistence
                try {
                    sessionStorage.setItem('activeSubTab-' + subTabContainerId, targetId);
                } catch (e) {
                    console.log('Unable to save tab state to session storage');
                }
            });
           
            // Check if there's a stored active tab
            try {
                var activeTabId = sessionStorage.getItem('activeSubTab-' + subTabContainerId);
                if (activeTabId) {
                    $container.find('.tab-button[data-target="' + activeTabId + '"]').trigger('click');
                }
            } catch (e) {
                console.log('Unable to retrieve tab state from session storage');
             }
             }
         });
         });
     }
     }
})();
/* Add Tooltip functionality for map links */
(function() {
    'use strict';
      
      
     $(document).ready(function() {
     // Run initial setup
        $('span.material-button a').each(function() {
    initializeTabs();
            var href = $(this).attr('href');
   
            if (href && href.indexOf('world-map') !== -1) {
    // Add animation effect when switching tabs
                $(this).parent().attr('title', 'Click to view location on map');
    $('.tab-button, .tab-button-image').click(function() {
               
        $('.tab-pane.active').css('animation', 'tabFadeIn 0.3s');
                // Optional: Add map icon
        setTimeout(function() {
                $(this).prepend('<span class="map-icon">🗺️ </span>');
            $('.tab-pane.active').css('animation', '');
            }
         }, 300);
         });
     });
     });
})();
/* Enhanced Image Previews */
(function() {
    'use strict';
      
      
     $(document).ready(function() {
     // Add image button hover effect
        $('.thumbimage').on('mouseenter', function() {
    $('.tab-button-image').hover(function() {
            $(this).css('transform', 'scale(1.05)');
        if (!$(this).hasClass('active')) {
             $(this).css('transition', 'transform 0.3s ease');
             $(this).find('img').css('opacity', '0.8');
            $(this).css('box-shadow', '0 8px 16px rgba(0,0,0,0.2)');
         }
         }).on('mouseleave', function() {
    }, function() {
            $(this).css('transform', '');
        $(this).find('img').css('opacity', '1');
            $(this).css('box-shadow', '');
        });
     });
     });
})();
/* Fix TOC positioning with tabs */
(function() {
    'use strict';
      
      
     $(document).ready(function() {
    // Add map tooltips
         // If both TOC and tab navigation exist on the page
     $('span.material-button a').each(function() {
        if ($('#toc').length && $('.tab-navigation').length) {
         var href = $(this).attr('href');
            // Add clearfix to TOC
        if (href && href.indexOf('world-map') !== -1) {
             $('#toc').addClass('clearfix');
             $(this).parent().attr('title', 'Click to view location on map');
           
             $(this).prepend('<span class="map-icon">🗺️ </span>');
            // Ensure TOC is above tab content in z-index
            $('#toc').css('position', 'relative');
             $('#toc').css('z-index', '2');
         }
         }
     });
     });
})();
/* Improve Mobile Experience */
(function() {
    'use strict';
      
      
     $(document).ready(function() {
    // Enhanced Image Previews
         // Check if we're on a mobile device
     $('.thumbimage').hover(function() {
        var isMobile = window.matchMedia("only screen and (max-width: 768px)").matches;
         $(this).css({
            'transform': 'scale(1.05)',
            'transition': 'transform 0.3s ease',
            'box-shadow': '0 8px 16px rgba(0,0,0,0.2)'
        });
    }, function() {
        $(this).css({
            'transform': '',
            'box-shadow': ''
        });
    });
   
    // Mobile Experience Optimization
    if (window.matchMedia("only screen and (max-width: 768px)").matches) {
        // Make tab navigation scrollable
        $('.tab-nav').css({
            'overflow-x': 'auto',
            'white-space': 'nowrap',
            '-webkit-overflow-scrolling': 'touch'
        });
       
        // Ensure tab buttons don't wrap
        $('.tab-button, .tab-button-image').css({
            'display': 'inline-block',
            'float': 'none'
        });
          
          
         if (isMobile) {
         // Adjust image button sizes for mobile
             // Make tab navigation scrollable on mobile
        $('.tab-button-image').css({
            $('.tab-nav').css({
             'width': '100px',
                 'overflow-x': 'auto',
            'height': '70px'
                 'white-space': 'nowrap',
        });
                 '-webkit-overflow-scrolling': 'touch'
       
        // Touch-friendly image previews
        $('.thumbimage, .tab-button-image').on('touchstart', function() {
            var $this = $(this);
            $this.css({
                 'transform': 'scale(1.05)',
                 'transition': 'transform 0.3s ease',
                 'box-shadow': '0 8px 16px rgba(0,0,0,0.2)'
             });
             });
              
              
             // Ensure tab buttons don't wrap
             setTimeout(function() {
            $('.tab-button').css({
                 $this.css({
                'display': 'inline-block',
                     'transform': '',
                'float': 'none'
                     'box-shadow': ''
            });
           
            // Add slight delay to image hover effects for better mobile experience
            $('.thumbimage').each(function() {
                var $this = $(this);
                 $this.on('touchstart', function() {
                     $this.css('transform', 'scale(1.05)');
                    $this.css('transition', 'transform 0.3s ease');
                     $this.css('box-shadow', '0 8px 16px rgba(0,0,0,0.2)');
                   
                    setTimeout(function() {
                        $this.css('transform', '');
                        $this.css('box-shadow', '');
                    }, 1000);
                 });
                 });
             });
             }, 1000);
         }
         });
    });
    }
})();
 
/* Save tab state across page loads */
(function() {
    'use strict';
      
      
     $(document).ready(function() {
     // Add preload for tab images to prevent flickering on first load
        // Check if we should restore tab states
    function preloadTabImages() {
        try {
        $('.tab-button-image img').each(function() {
            var pageTabState = sessionStorage.getItem('pageTabState-' + window.location.pathname);
            var img = new Image();
            if (pageTabState) {
             img.src = $(this).attr('src');
                var tabStates = JSON.parse(pageTabState);
               
                // Restore main tab states
                if (tabStates.mainTabs) {
                    $.each(tabStates.mainTabs, function(containerId, activeTabId) {
                        $('#' + containerId + ' > .tab-nav > .tab-button[data-target="' + activeTabId + '"]').trigger('click');
                    });
                }
               
                // Restore sub tab states
                if (tabStates.subTabs) {
                    $.each(tabStates.subTabs, function(containerId, activeTabId) {
                        $('#' + containerId + ' > .tab-nav > .tab-button[data-target="' + activeTabId + '"]').trigger('click');
                    });
                }
            }
        } catch (e) {
             console.log('Error restoring tab state:', e);
        }
       
        // Setup save on tab change
        $('.tab-button').on('click', function() {
            saveTabStates();
         });
         });
       
    }
        function saveTabStates() {
   
            try {
    // Run preload
                var tabStates = {
    preloadTabImages();
                    mainTabs: {},
});
                    subTabs: {}
                };
               
                // Save main tab states
                $('.tab-navigation').each(function() {
                    var id = $(this).attr('id');
                    var activeTabId = $(this).find('> .tab-nav > .tab-button.active').data('target');
                    tabStates.mainTabs[id] = activeTabId;
                });
               
                // Save sub tab states
                $('.sub-tab-navigation').each(function() {
                    var id = $(this).attr('id');
                    var activeTabId = $(this).find('> .tab-nav > .tab-button.active').data('target');
                    tabStates.subTabs[id] = activeTabId;
                });
               
                sessionStorage.setItem('pageTabState-' + window.location.pathname, JSON.stringify(tabStates));
            } catch (e) {
                console.log('Error saving tab state:', e);
            }
        }
    });
})();

Latest revision as of 20:37, 1 March 2025

/* Any JavaScript here will be loaded for all users on every page load. */

$(document).ready(function() {
    'use strict';
    
    // Main race tab click handler (works for both regular and image buttons)
    $('.tab-navigation .tab-button, .tab-navigation .tab-button-image').click(function(e) {
        e.preventDefault();
        
        var targetId = $(this).data('target');
        
        // Update main race tabs (for both button types)
        $('.tab-navigation .tab-button, .tab-navigation .tab-button-image').removeClass('active');
        $(this).addClass('active');
        
        // Update main content panes
        $('.tab-content > .tab-pane').removeClass('active');
        $('#' + targetId).addClass('active');
        
        // Always activate the overview tab for the selected race
        var $subNav = $('#' + targetId + ' .sub-tab-navigation');
        var $overviewTab;
        
        // Check if using image tabs or regular tabs
        if ($subNav.find('.tab-button-image').length) {
            $overviewTab = $subNav.find('.tab-button-image').first();
        } else {
            $overviewTab = $subNav.find('.tab-button').first();
        }
        
        var overviewTargetId = $overviewTab.data('target');
        
        // Set overview tab and content as active
        $subNav.find('.tab-button, .tab-button-image').removeClass('active');
        $overviewTab.addClass('active');
        
        $subNav.find('.tab-content .tab-pane').removeClass('active');
        $('#' + overviewTargetId).addClass('active');
    });
    
    // Create collapsible sections
    $('.collapsible-header').click(function() {
        $(this).toggleClass('collapsed');
        $(this).next('.collapsible-content').slideToggle(300);
        
        // Toggle the icon
        var $icon = $(this).find('.collapse-icon');
        if ($icon.text() === '▼') {
            $icon.text('►');
        } else {
            $icon.text('▼');
        }
    });
    
    // Initialize all sections as expanded
    $('.collapsible-header').each(function() {
        $(this).find('.collapse-icon').text('▼');
    });
    
    // Sub-class tab click handler (works for both regular and image buttons)
    $('.sub-tab-navigation .tab-button, .sub-tab-navigation .tab-button-image').click(function(e) {
        e.preventDefault();
        e.stopPropagation();
        
        var $this = $(this);
        var $subNav = $this.closest('.sub-tab-navigation');
        var targetId = $this.data('target');
        
        // Only update the buttons in this sub-tab navigation
        $subNav.find('.tab-button, .tab-button-image').removeClass('active');
        $this.addClass('active');
        
        // Find and update only the content panes within this sub-tab section
        $subNav.find('.tab-content .tab-pane').removeClass('active');
        $('#' + targetId).addClass('active');
        
        // Keep the parent tab-pane active
        $this.closest('.tab-pane').addClass('active');
    });
    
    // Initial setup
    function initializeTabs() {
        // Set first race tab active if none are
        var $mainNav = $('.tab-navigation');
        if (!$mainNav.find('.tab-button.active, .tab-button-image.active').length) {
            if ($mainNav.find('.tab-button-image').length) {
                var $firstMainTab = $mainNav.find('.tab-button-image').first();
                $firstMainTab.addClass('active');
            } else {
                var $firstMainTab = $mainNav.find('.tab-button').first();
                $firstMainTab.addClass('active');
            }
            
            var mainTargetId = $firstMainTab.data('target');
            $('#' + mainTargetId).addClass('active');
            
            // Set its overview tab active
            var $subNav = $('#' + mainTargetId + ' .sub-tab-navigation');
            var $overviewTab;
            
            // Check if using image tabs or regular tabs
            if ($subNav.find('.tab-button-image').length) {
                $overviewTab = $subNav.find('.tab-button-image').first();
            } else {
                $overviewTab = $subNav.find('.tab-button').first();
            }
            
            $overviewTab.addClass('active');
            $('#' + $overviewTab.data('target')).addClass('active');
        }
        
        // For each race tab that's active
        $('.tab-navigation .tab-button.active, .tab-navigation .tab-button-image.active').each(function() {
            var mainTargetId = $(this).data('target');
            var $mainContent = $('#' + mainTargetId);
            
            // Ensure overview tab is active if no sub-tab is active
            var $subNav = $mainContent.find('.sub-tab-navigation');
            if ($subNav.length && !$subNav.find('.tab-button.active, .tab-button-image.active').length) {
                var $overviewTab;
                
                // Check if using image tabs or regular tabs
                if ($subNav.find('.tab-button-image').length) {
                    $overviewTab = $subNav.find('.tab-button-image').first();
                } else {
                    $overviewTab = $subNav.find('.tab-button').first();
                }
                
                $overviewTab.addClass('active');
                $('#' + $overviewTab.data('target')).addClass('active');
            }
        });
    }
    
    // Run initial setup
    initializeTabs();
    
    // Add animation effect when switching tabs
    $('.tab-button, .tab-button-image').click(function() {
        $('.tab-pane.active').css('animation', 'tabFadeIn 0.3s');
        setTimeout(function() {
            $('.tab-pane.active').css('animation', '');
        }, 300);
    });
    
    // Add image button hover effect
    $('.tab-button-image').hover(function() {
        if (!$(this).hasClass('active')) {
            $(this).find('img').css('opacity', '0.8');
        }
    }, function() {
        $(this).find('img').css('opacity', '1');
    });
    
    // Add map tooltips
    $('span.material-button a').each(function() {
        var href = $(this).attr('href');
        if (href && href.indexOf('world-map') !== -1) {
            $(this).parent().attr('title', 'Click to view location on map');
            $(this).prepend('<span class="map-icon">🗺️ </span>');
        }
    });
    
    // Enhanced Image Previews
    $('.thumbimage').hover(function() {
        $(this).css({
            'transform': 'scale(1.05)',
            'transition': 'transform 0.3s ease',
            'box-shadow': '0 8px 16px rgba(0,0,0,0.2)'
        });
    }, function() {
        $(this).css({
            'transform': '',
            'box-shadow': ''
        });
    });
    
    // Mobile Experience Optimization
    if (window.matchMedia("only screen and (max-width: 768px)").matches) {
        // Make tab navigation scrollable
        $('.tab-nav').css({
            'overflow-x': 'auto',
            'white-space': 'nowrap',
            '-webkit-overflow-scrolling': 'touch'
        });
        
        // Ensure tab buttons don't wrap
        $('.tab-button, .tab-button-image').css({
            'display': 'inline-block',
            'float': 'none'
        });
        
        // Adjust image button sizes for mobile
        $('.tab-button-image').css({
            'width': '100px',
            'height': '70px'
        });
        
        // Touch-friendly image previews
        $('.thumbimage, .tab-button-image').on('touchstart', function() {
            var $this = $(this);
            $this.css({
                'transform': 'scale(1.05)',
                'transition': 'transform 0.3s ease',
                'box-shadow': '0 8px 16px rgba(0,0,0,0.2)'
            });
            
            setTimeout(function() {
                $this.css({
                    'transform': '',
                    'box-shadow': ''
                });
            }, 1000);
        });
    }
    
    // Add preload for tab images to prevent flickering on first load
    function preloadTabImages() {
        $('.tab-button-image img').each(function() {
            var img = new Image();
            img.src = $(this).attr('src');
        });
    }
    
    // Run preload
    preloadTabImages();
});