imported>Dawning
big changes (by SublimeText.Mediawiker)
imported>Dawning
(by SublimeText.Mediawiker)
Line 80: Line 80:


/* dynamic gif displayer ONLY TOUCH IF YOU KNOW WHAT YOU ARE DOING */
/* dynamic gif displayer ONLY TOUCH IF YOU KNOW WHAT YOU ARE DOING */
/**
* Dynamic GIF Displayer for Telos Realms Wiki
* Works with Fandom Tooltips extension
*/


(function() {
(function() {
     'use strict';
     'use strict';
      
      
    console.log('Dynamic GIF Displayer: Script loading...');
   
    // Configuration
     const CONFIG = {
     const CONFIG = {
         containerClass: 'dynamic-gif-container',
         containerClass: 'dynamic-gif-container',
Line 89: Line 97:
         autoExpand: true,
         autoExpand: true,
         expandDelay: 200,
         expandDelay: 200,
         collapseDelay: 1000  
         collapseDelay: 1000
     };
     };
      
      
Line 96: Line 104:
     let currentGif = null;
     let currentGif = null;
      
      
    /**
    * Initialize the dynamic GIF displayer
    */
     function init() {
     function init() {
        console.log('Dynamic GIF Displayer: Initializing...');
       
         const containers = document.querySelectorAll('.' + CONFIG.containerClass);
         const containers = document.querySelectorAll('.' + CONFIG.containerClass);
        console.log('Dynamic GIF Displayer: Found', containers.length, 'containers');
          
          
         containers.forEach(container => {
         containers.forEach(container => {
            console.log('Dynamic GIF Displayer: Setting up container', container.id);
             setupContainer(container);
             setupContainer(container);
             attachTooltipListeners(container);
             attachTooltipListeners(container);
Line 105: Line 120:
     }
     }
      
      
    /**
    * Setup the GIF display container
    */
     function setupContainer(container) {
     function setupContainer(container) {
         const displayArea = container.querySelector('.' + CONFIG.displayClass);
         const displayArea = container.querySelector('.' + CONFIG.displayClass);
         if (!displayArea) return;
         if (!displayArea) {
            console.error('Dynamic GIF Displayer: No display area found');
            return;
        }
          
          
         // Add hover listeners to prevent auto-collapse when hovering the display
         // Add hover listeners to prevent auto-collapse when hovering the display
Line 119: Line 140:
     }
     }
      
      
    /**
    * Attach listeners to all tooltips within the skill tree area
    */
     function attachTooltipListeners(container) {
     function attachTooltipListeners(container) {
         // Find all advanced-tooltip elements in the same section
         console.log('Dynamic GIF Displayer: Attaching tooltip listeners...');
        const skillTreeSection = findSkillTreeSection(container);
        if (!skillTreeSection) return;
          
          
         const tooltips = skillTreeSection.querySelectorAll('.advanced-tooltip');
         // Build GIF map from the data store
         const gifMap = buildGifMap(container);
         const gifMap = buildGifMap(container);
        console.log('Dynamic GIF Displayer: GIF map', gifMap);
          
          
         tooltips.forEach((tooltip, index) => {
        // Find all tooltips on the entire page
        const tooltips = document.querySelectorAll('.advanced-tooltip');
        console.log('Dynamic GIF Displayer: Found', tooltips.length, 'tooltips');
       
         tooltips.forEach((tooltip) => {
             const skillTitle = tooltip.querySelector('.skill-title');
             const skillTitle = tooltip.querySelector('.skill-title');
             if (!skillTitle) return;
             if (!skillTitle) return;
Line 133: Line 160:
             const skillName = skillTitle.textContent.trim();
             const skillName = skillTitle.textContent.trim();
             const gifUrl = gifMap[skillName];
             const gifUrl = gifMap[skillName];
           
            console.log('Dynamic GIF Displayer: Processing tooltip:', skillName, 'GIF:', gifUrl);
              
              
             if (gifUrl) {
             if (gifUrl) {
                 tooltip.addEventListener('mouseenter', () => {
                // Remove existing listeners to prevent duplicates
                    handleTooltipHover(container, gifUrl, skillName);
                 tooltip.removeEventListener('mouseenter', tooltip._gifHoverHandler);
                 });
                tooltip.removeEventListener('mouseleave', tooltip._gifLeaveHandler);
               
                // Create and store handlers
                tooltip._gifHoverHandler = () => handleTooltipHover(container, gifUrl, skillName);
                 tooltip._gifLeaveHandler = () => scheduleCollapse(container);
               
                // Add hover listeners
                tooltip.addEventListener('mouseenter', tooltip._gifHoverHandler);
                tooltip.addEventListener('mouseleave', tooltip._gifLeaveHandler);
                  
                  
                 tooltip.addEventListener('mouseleave', () => {
                 console.log('Dynamic GIF Displayer: Attached listeners to', skillName);
                    scheduleCollapse(container);
                });
             }
             }
         });
         });
     }
     }
      
      
     function findSkillTreeSection(container) {
     /**
        let parent = container.parentElement;
    * Build a map of skill names to GIF URLs from data-gif-list attribute
        while (parent) {
    */
            if (parent.querySelector('.advanced-tooltip')) {
                return parent;
            }
            parent = parent.parentElement;
        }
        return document;
    }
   
     function buildGifMap(container) {
     function buildGifMap(container) {
         const gifMap = {};
         const gifMap = {};
         const listData = container.getAttribute('data-gif-list');
         const listData = container.getAttribute('data-gif-list');
          
          
         if (!listData) return gifMap;
         if (!listData) {
            console.error('Dynamic GIF Displayer: No data-gif-list attribute found');
            return gifMap;
        }
       
        console.log('Dynamic GIF Displayer: Raw list data:', listData);
       
        // Parse the semicolon-separated list
        const entries = listData.split(';').filter(e => e.trim());
        console.log('Dynamic GIF Displayer: Found', entries.length, 'entries');
          
          
        const entries = listData.split(';');
         entries.forEach(entry => {
         entries.forEach(entry => {
             const [skillName, gifFile] = entry.split(':').map(s => s.trim());
             const parts = entry.split(':');
            if (skillName && gifFile) {
            if (parts.length >= 2) {
                const gifUrl = '/images/' + gifFile;
                const skillName = parts[0].trim();
                gifMap[skillName] = gifUrl;
                const gifFile = parts.slice(1).join(':').trim(); // In case filename has colons
               
                if (skillName && gifFile) {
                    // Construct full URL - try multiple possible paths
                    let gifUrl;
                    if (typeof mw !== 'undefined' && mw.config) {
                        // Use MediaWiki's file path
                        gifUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/images/' + gifFile;
                    } else {
                        // Fallback to relative path
                        gifUrl = '/images/' + gifFile;
                    }
                   
                    gifMap[skillName] = gifUrl;
                    console.log('Dynamic GIF Displayer: Mapped "' + skillName + '" to', gifUrl);
                }
             }
             }
         });
         });
Line 175: Line 225:
     }
     }
      
      
    /**
    * Handle tooltip hover event
    */
     function handleTooltipHover(container, gifUrl, skillName) {
     function handleTooltipHover(container, gifUrl, skillName) {
        console.log('Dynamic GIF Displayer: Hovering', skillName);
         clearTimeout(collapseTimer);
         clearTimeout(collapseTimer);
         clearTimeout(expandTimer);
         clearTimeout(expandTimer);
Line 184: Line 238:
     }
     }
      
      
    /**
    * Show the GIF in the display area
    */
     function showGif(container, gifUrl, skillName) {
     function showGif(container, gifUrl, skillName) {
        console.log('Dynamic GIF Displayer: Showing GIF for', skillName, gifUrl);
       
         const displayArea = container.querySelector('.' + CONFIG.displayClass);
         const displayArea = container.querySelector('.' + CONFIG.displayClass);
         if (!displayArea) return;
         if (!displayArea) return;
          
          
        // Expand container if collapsed
         if (!container.classList.contains('expanded')) {
         if (!container.classList.contains('expanded')) {
             container.classList.add('expanded');
             container.classList.add('expanded');
            console.log('Dynamic GIF Displayer: Expanded container');
         }
         }
          
          
        // Update GIF if different from current
         if (currentGif !== gifUrl) {
         if (currentGif !== gifUrl) {
             const imgContainer = displayArea.querySelector('.gif-image-container');
             const imgContainer = displayArea.querySelector('.gif-image-container');
Line 197: Line 259:
              
              
             if (imgContainer) {
             if (imgContainer) {
                // Clear placeholder
                const placeholder = imgContainer.querySelector('.gif-placeholder');
                if (placeholder) {
                    placeholder.remove();
                }
               
                // Add loading state
                 imgContainer.classList.add('loading');
                 imgContainer.classList.add('loading');
                  
                  
                // Create new image
                 const img = document.createElement('img');
                 const img = document.createElement('img');
                 img.src = gifUrl;
                 img.src = gifUrl;
Line 207: Line 277:
                     imgContainer.appendChild(img);
                     imgContainer.appendChild(img);
                     imgContainer.classList.remove('loading');
                     imgContainer.classList.remove('loading');
                    console.log('Dynamic GIF Displayer: GIF loaded successfully');
                 };
                 };
                  
                  
                 img.onerror = () => {
                 img.onerror = () => {
                     imgContainer.innerHTML = '<div class="gif-error">GIF not found</div>';
                     imgContainer.innerHTML = '<div class="gif-error">GIF not found: ' + gifUrl + '</div>';
                     imgContainer.classList.remove('loading');
                     imgContainer.classList.remove('loading');
                    console.error('Dynamic GIF Displayer: Failed to load GIF', gifUrl);
                 };
                 };
             }
             }
Line 223: Line 295:
     }
     }
      
      
    /**
    * Schedule container collapse
    */
     function scheduleCollapse(container) {
     function scheduleCollapse(container) {
         clearTimeout(collapseTimer);
         clearTimeout(collapseTimer);
Line 229: Line 304:
             container.classList.remove('expanded');
             container.classList.remove('expanded');
             currentGif = null;
             currentGif = null;
            console.log('Dynamic GIF Displayer: Collapsed container');
         }, CONFIG.collapseDelay);
         }, CONFIG.collapseDelay);
     }
     }
      
      
    /**
    * Manual toggle function for the collapse button
    */
     window.toggleGifDisplay = function(containerId) {
     window.toggleGifDisplay = function(containerId) {
         const container = document.getElementById(containerId);
         const container = document.getElementById(containerId);
Line 244: Line 323:
     };
     };
      
      
    // Initialize when DOM is ready
     if (document.readyState === 'loading') {
     if (document.readyState === 'loading') {
         document.addEventListener('DOMContentLoaded', init);
         document.addEventListener('DOMContentLoaded', init);
Line 250: Line 330:
     }
     }
      
      
     document.addEventListener('DOMContentLoaded', function() {
     // Also initialize on window load as fallback
         const observer = new MutationObserver(function(mutations) {
    window.addEventListener('load', init);
            mutations.forEach(function(mutation) {
   
                if (mutation.addedNodes.length) {
    // Re-initialize when content changes (for tabber and dynamic content)
                    init();
    if (typeof mw !== 'undefined' && mw.hook) {
                }
         mw.hook('wikipage.content').add(init);
            });
    }
        });
   
       
    // MutationObserver for dynamic content
        observer.observe(document.body, {
    const observer = new MutationObserver(function(mutations) {
            childList: true,
        let shouldReinit = false;
             subtree: true
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes.length) {
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeType === 1 && (
                        node.classList && node.classList.contains('advanced-tooltip') ||
                        node.querySelector && node.querySelector('.advanced-tooltip')
                    )) {
                        shouldReinit = true;
                    }
                });
             }
         });
         });
        if (shouldReinit) {
            console.log('Dynamic GIF Displayer: Content changed, reinitializing...');
            setTimeout(init, 100);
        }
    });
   
    observer.observe(document.body, {
        childList: true,
        subtree: true
     });
     });
   
    console.log('Dynamic GIF Displayer: Script loaded');
})();
})();

Revision as of 02:08, 14 October 2025

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

/* DRUID */
$(function () {
  $(".druid-main-images-label").off("click");
  $(".druid-main-images-label").click(function () {
    var $parent = $(this).closest(".druid-container");
    $parent.find(".druid-toggleable").removeClass("focused");
    var i = $(this).attr("data-druid");
    $parent.find(".druid-toggleable[data-druid=" + i + "]").addClass("focused");
  });

  $(".druid-collapsible").off("click");
  $(".druid-collapsible").click(function () {
    var kind = $(this).attr("data-druid-section");
    $(this).toggleClass("druid-collapsible-collapsed");
    $(this)
      .closest(".druid-container")
      .find("[data-druid-section-row=" + kind + "]")
      .toggleClass("druid-collapsed");
  });
});
/* End DRUID */

/* [[Template:Spoiler]] */
$(function () {
	$('.spoiler-content')
	.off('click') // in case this code is loaded twice
	.on('click', function(e){
		$(this).toggleClass('show');
	}).find('a').on('click', function(e){
		e.stopPropagation();
	});

});
/* End Template:Spoiler */


/* Link to imported modules from Lua code */
$(function() {
    var config = mw.config.get([
        'wgCanonicalNamespace',
        'wgFormattedNamespaces'
    ]);
    if (config.wgCanonicalNamespace !== 'Module') {
        return;
    }
    var localizedNamespace = config.wgFormattedNamespaces[828];
    $('.s1, .s2, .s').each(function() {
        var $this = $(this);
        var html = $this.html();
        var quote = html[0];
        var isLongStringQuote = quote === '[';
        var quoteRE = new RegExp('^\\' + quote + '|\\' + quote + '$', 'g');
        if (isLongStringQuote) {
            quoteRE = /^\[\[|\]\]$/g;
        }
        var name = html.replace(quoteRE, '');
        var isEnglishPrefix = name.startsWith('Module:');
        var isLocalizedPrefix = name.startsWith(localizedNamespace + ':');
        var isDevPrefix = name.startsWith('Dev:');
        if (isEnglishPrefix || isLocalizedPrefix || isDevPrefix) {
            var attrs = {
                href: mw.util.getUrl(name)
            };
            if (isDevPrefix) {
                attrs.href = 'https://commons.wiki.gg/wiki/Module:' + mw.util.wikiUrlencode(name.replace('Dev:', ''));
                attrs.target = '_blank';
                attrs.rel = 'noopener';
            }
            var link = mw.html.element('a', attrs, name);
            var str = quote + link + quote;
            if (isLongStringQuote) {
                str = '[[' + link + ']]';
            }
            $this.html(str);
        }
    });
});

/* dynamic gif displayer ONLY TOUCH IF YOU KNOW WHAT YOU ARE DOING */

/**
 * Dynamic GIF Displayer for Telos Realms Wiki
 * Works with Fandom Tooltips extension
 */

(function() {
    'use strict';
    
    console.log('Dynamic GIF Displayer: Script loading...');
    
    // Configuration
    const CONFIG = {
        containerClass: 'dynamic-gif-container',
        displayClass: 'gif-display-area',
        autoExpand: true,
        expandDelay: 200,
        collapseDelay: 1000
    };
    
    let expandTimer = null;
    let collapseTimer = null;
    let currentGif = null;
    
    /**
     * Initialize the dynamic GIF displayer
     */
    function init() {
        console.log('Dynamic GIF Displayer: Initializing...');
        
        const containers = document.querySelectorAll('.' + CONFIG.containerClass);
        console.log('Dynamic GIF Displayer: Found', containers.length, 'containers');
        
        containers.forEach(container => {
            console.log('Dynamic GIF Displayer: Setting up container', container.id);
            setupContainer(container);
            attachTooltipListeners(container);
        });
    }
    
    /**
     * Setup the GIF display container
     */
    function setupContainer(container) {
        const displayArea = container.querySelector('.' + CONFIG.displayClass);
        if (!displayArea) {
            console.error('Dynamic GIF Displayer: No display area found');
            return;
        }
        
        // Add hover listeners to prevent auto-collapse when hovering the display
        displayArea.addEventListener('mouseenter', () => {
            clearTimeout(collapseTimer);
        });
        
        displayArea.addEventListener('mouseleave', () => {
            scheduleCollapse(container);
        });
    }
    
    /**
     * Attach listeners to all tooltips within the skill tree area
     */
    function attachTooltipListeners(container) {
        console.log('Dynamic GIF Displayer: Attaching tooltip listeners...');
        
        // Build GIF map from the data store
        const gifMap = buildGifMap(container);
        console.log('Dynamic GIF Displayer: GIF map', gifMap);
        
        // Find all tooltips on the entire page
        const tooltips = document.querySelectorAll('.advanced-tooltip');
        console.log('Dynamic GIF Displayer: Found', tooltips.length, 'tooltips');
        
        tooltips.forEach((tooltip) => {
            const skillTitle = tooltip.querySelector('.skill-title');
            if (!skillTitle) return;
            
            const skillName = skillTitle.textContent.trim();
            const gifUrl = gifMap[skillName];
            
            console.log('Dynamic GIF Displayer: Processing tooltip:', skillName, 'GIF:', gifUrl);
            
            if (gifUrl) {
                // Remove existing listeners to prevent duplicates
                tooltip.removeEventListener('mouseenter', tooltip._gifHoverHandler);
                tooltip.removeEventListener('mouseleave', tooltip._gifLeaveHandler);
                
                // Create and store handlers
                tooltip._gifHoverHandler = () => handleTooltipHover(container, gifUrl, skillName);
                tooltip._gifLeaveHandler = () => scheduleCollapse(container);
                
                // Add hover listeners
                tooltip.addEventListener('mouseenter', tooltip._gifHoverHandler);
                tooltip.addEventListener('mouseleave', tooltip._gifLeaveHandler);
                
                console.log('Dynamic GIF Displayer: Attached listeners to', skillName);
            }
        });
    }
    
    /**
     * Build a map of skill names to GIF URLs from data-gif-list attribute
     */
    function buildGifMap(container) {
        const gifMap = {};
        const listData = container.getAttribute('data-gif-list');
        
        if (!listData) {
            console.error('Dynamic GIF Displayer: No data-gif-list attribute found');
            return gifMap;
        }
        
        console.log('Dynamic GIF Displayer: Raw list data:', listData);
        
        // Parse the semicolon-separated list
        const entries = listData.split(';').filter(e => e.trim());
        console.log('Dynamic GIF Displayer: Found', entries.length, 'entries');
        
        entries.forEach(entry => {
            const parts = entry.split(':');
            if (parts.length >= 2) {
                const skillName = parts[0].trim();
                const gifFile = parts.slice(1).join(':').trim(); // In case filename has colons
                
                if (skillName && gifFile) {
                    // Construct full URL - try multiple possible paths
                    let gifUrl;
                    if (typeof mw !== 'undefined' && mw.config) {
                        // Use MediaWiki's file path
                        gifUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/images/' + gifFile;
                    } else {
                        // Fallback to relative path
                        gifUrl = '/images/' + gifFile;
                    }
                    
                    gifMap[skillName] = gifUrl;
                    console.log('Dynamic GIF Displayer: Mapped "' + skillName + '" to', gifUrl);
                }
            }
        });
        
        return gifMap;
    }
    
    /**
     * Handle tooltip hover event
     */
    function handleTooltipHover(container, gifUrl, skillName) {
        console.log('Dynamic GIF Displayer: Hovering', skillName);
        clearTimeout(collapseTimer);
        clearTimeout(expandTimer);
        
        expandTimer = setTimeout(() => {
            showGif(container, gifUrl, skillName);
        }, CONFIG.expandDelay);
    }
    
    /**
     * Show the GIF in the display area
     */
    function showGif(container, gifUrl, skillName) {
        console.log('Dynamic GIF Displayer: Showing GIF for', skillName, gifUrl);
        
        const displayArea = container.querySelector('.' + CONFIG.displayClass);
        if (!displayArea) return;
        
        // Expand container if collapsed
        if (!container.classList.contains('expanded')) {
            container.classList.add('expanded');
            console.log('Dynamic GIF Displayer: Expanded container');
        }
        
        // Update GIF if different from current
        if (currentGif !== gifUrl) {
            const imgContainer = displayArea.querySelector('.gif-image-container');
            const caption = displayArea.querySelector('.gif-caption');
            
            if (imgContainer) {
                // Clear placeholder
                const placeholder = imgContainer.querySelector('.gif-placeholder');
                if (placeholder) {
                    placeholder.remove();
                }
                
                // Add loading state
                imgContainer.classList.add('loading');
                
                // Create new image
                const img = document.createElement('img');
                img.src = gifUrl;
                img.alt = skillName;
                
                img.onload = () => {
                    imgContainer.innerHTML = '';
                    imgContainer.appendChild(img);
                    imgContainer.classList.remove('loading');
                    console.log('Dynamic GIF Displayer: GIF loaded successfully');
                };
                
                img.onerror = () => {
                    imgContainer.innerHTML = '<div class="gif-error">GIF not found: ' + gifUrl + '</div>';
                    imgContainer.classList.remove('loading');
                    console.error('Dynamic GIF Displayer: Failed to load GIF', gifUrl);
                };
            }
            
            if (caption) {
                caption.textContent = skillName;
            }
            
            currentGif = gifUrl;
        }
    }
    
    /**
     * Schedule container collapse
     */
    function scheduleCollapse(container) {
        clearTimeout(collapseTimer);
        
        collapseTimer = setTimeout(() => {
            container.classList.remove('expanded');
            currentGif = null;
            console.log('Dynamic GIF Displayer: Collapsed container');
        }, CONFIG.collapseDelay);
    }
    
    /**
     * Manual toggle function for the collapse button
     */
    window.toggleGifDisplay = function(containerId) {
        const container = document.getElementById(containerId);
        if (!container) return;
        
        clearTimeout(collapseTimer);
        container.classList.toggle('expanded');
        
        if (!container.classList.contains('expanded')) {
            currentGif = null;
        }
    };
    
    // Initialize when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
    
    // Also initialize on window load as fallback
    window.addEventListener('load', init);
    
    // Re-initialize when content changes (for tabber and dynamic content)
    if (typeof mw !== 'undefined' && mw.hook) {
        mw.hook('wikipage.content').add(init);
    }
    
    // MutationObserver for dynamic content
    const observer = new MutationObserver(function(mutations) {
        let shouldReinit = false;
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes.length) {
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeType === 1 && (
                        node.classList && node.classList.contains('advanced-tooltip') ||
                        node.querySelector && node.querySelector('.advanced-tooltip')
                    )) {
                        shouldReinit = true;
                    }
                });
            }
        });
        if (shouldReinit) {
            console.log('Dynamic GIF Displayer: Content changed, reinitializing...');
            setTimeout(init, 100);
        }
    });
    
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
    
    console.log('Dynamic GIF Displayer: Script loaded');
})();