MediaWiki:Common.js: Difference between revisions
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) { | ||
console.log('Dynamic GIF Displayer: Attaching tooltip listeners...'); | |||
// 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 | // 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. | // 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) { | 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'); | |||
entries.forEach(entry => { | entries.forEach(entry => { | ||
const | 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); | |||
} | |||
} | } | ||
}); | }); | ||
| 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: | ||
} | } | ||
// Also initialize on window load as fallback | |||
const observer = new MutationObserver(function(mutations) { | 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'); | |||
})(); | })(); | ||
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');
})();