MediaWiki:Common.js: Difference between revisions
imported>Dawning mNo edit summary |
imported>Dawning big changes (by SublimeText.Mediawiker) |
||
| Line 78: | Line 78: | ||
}); | }); | ||
}); | }); | ||
/* dynamic gif displayer ONLY TOUCH IF YOU KNOW WHAT YOU ARE DOING */ | |||
(function() { | |||
'use strict'; | |||
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; | |||
function init() { | |||
const containers = document.querySelectorAll('.' + CONFIG.containerClass); | |||
containers.forEach(container => { | |||
setupContainer(container); | |||
attachTooltipListeners(container); | |||
}); | |||
} | |||
function setupContainer(container) { | |||
const displayArea = container.querySelector('.' + CONFIG.displayClass); | |||
if (!displayArea) return; | |||
// Add hover listeners to prevent auto-collapse when hovering the display | |||
displayArea.addEventListener('mouseenter', () => { | |||
clearTimeout(collapseTimer); | |||
}); | |||
displayArea.addEventListener('mouseleave', () => { | |||
scheduleCollapse(container); | |||
}); | |||
} | |||
function attachTooltipListeners(container) { | |||
// Find all advanced-tooltip elements in the same section | |||
const skillTreeSection = findSkillTreeSection(container); | |||
if (!skillTreeSection) return; | |||
const tooltips = skillTreeSection.querySelectorAll('.advanced-tooltip'); | |||
const gifMap = buildGifMap(container); | |||
tooltips.forEach((tooltip, index) => { | |||
const skillTitle = tooltip.querySelector('.skill-title'); | |||
if (!skillTitle) return; | |||
const skillName = skillTitle.textContent.trim(); | |||
const gifUrl = gifMap[skillName]; | |||
if (gifUrl) { | |||
tooltip.addEventListener('mouseenter', () => { | |||
handleTooltipHover(container, gifUrl, skillName); | |||
}); | |||
tooltip.addEventListener('mouseleave', () => { | |||
scheduleCollapse(container); | |||
}); | |||
} | |||
}); | |||
} | |||
function findSkillTreeSection(container) { | |||
let parent = container.parentElement; | |||
while (parent) { | |||
if (parent.querySelector('.advanced-tooltip')) { | |||
return parent; | |||
} | |||
parent = parent.parentElement; | |||
} | |||
return document; | |||
} | |||
function buildGifMap(container) { | |||
const gifMap = {}; | |||
const listData = container.getAttribute('data-gif-list'); | |||
if (!listData) return gifMap; | |||
const entries = listData.split(';'); | |||
entries.forEach(entry => { | |||
const [skillName, gifFile] = entry.split(':').map(s => s.trim()); | |||
if (skillName && gifFile) { | |||
const gifUrl = '/images/' + gifFile; | |||
gifMap[skillName] = gifUrl; | |||
} | |||
}); | |||
return gifMap; | |||
} | |||
function handleTooltipHover(container, gifUrl, skillName) { | |||
clearTimeout(collapseTimer); | |||
clearTimeout(expandTimer); | |||
expandTimer = setTimeout(() => { | |||
showGif(container, gifUrl, skillName); | |||
}, CONFIG.expandDelay); | |||
} | |||
function showGif(container, gifUrl, skillName) { | |||
const displayArea = container.querySelector('.' + CONFIG.displayClass); | |||
if (!displayArea) return; | |||
if (!container.classList.contains('expanded')) { | |||
container.classList.add('expanded'); | |||
} | |||
if (currentGif !== gifUrl) { | |||
const imgContainer = displayArea.querySelector('.gif-image-container'); | |||
const caption = displayArea.querySelector('.gif-caption'); | |||
if (imgContainer) { | |||
imgContainer.classList.add('loading'); | |||
const img = document.createElement('img'); | |||
img.src = gifUrl; | |||
img.alt = skillName; | |||
img.onload = () => { | |||
imgContainer.innerHTML = ''; | |||
imgContainer.appendChild(img); | |||
imgContainer.classList.remove('loading'); | |||
}; | |||
img.onerror = () => { | |||
imgContainer.innerHTML = '<div class="gif-error">GIF not found</div>'; | |||
imgContainer.classList.remove('loading'); | |||
}; | |||
} | |||
if (caption) { | |||
caption.textContent = skillName; | |||
} | |||
currentGif = gifUrl; | |||
} | |||
} | |||
function scheduleCollapse(container) { | |||
clearTimeout(collapseTimer); | |||
collapseTimer = setTimeout(() => { | |||
container.classList.remove('expanded'); | |||
currentGif = null; | |||
}, CONFIG.collapseDelay); | |||
} | |||
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; | |||
} | |||
}; | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', init); | |||
} else { | |||
init(); | |||
} | |||
document.addEventListener('DOMContentLoaded', function() { | |||
const observer = new MutationObserver(function(mutations) { | |||
mutations.forEach(function(mutation) { | |||
if (mutation.addedNodes.length) { | |||
init(); | |||
} | |||
}); | |||
}); | |||
observer.observe(document.body, { | |||
childList: true, | |||
subtree: true | |||
}); | |||
}); | |||
})(); | |||
Revision as of 01:56, 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 */
(function() {
'use strict';
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;
function init() {
const containers = document.querySelectorAll('.' + CONFIG.containerClass);
containers.forEach(container => {
setupContainer(container);
attachTooltipListeners(container);
});
}
function setupContainer(container) {
const displayArea = container.querySelector('.' + CONFIG.displayClass);
if (!displayArea) return;
// Add hover listeners to prevent auto-collapse when hovering the display
displayArea.addEventListener('mouseenter', () => {
clearTimeout(collapseTimer);
});
displayArea.addEventListener('mouseleave', () => {
scheduleCollapse(container);
});
}
function attachTooltipListeners(container) {
// Find all advanced-tooltip elements in the same section
const skillTreeSection = findSkillTreeSection(container);
if (!skillTreeSection) return;
const tooltips = skillTreeSection.querySelectorAll('.advanced-tooltip');
const gifMap = buildGifMap(container);
tooltips.forEach((tooltip, index) => {
const skillTitle = tooltip.querySelector('.skill-title');
if (!skillTitle) return;
const skillName = skillTitle.textContent.trim();
const gifUrl = gifMap[skillName];
if (gifUrl) {
tooltip.addEventListener('mouseenter', () => {
handleTooltipHover(container, gifUrl, skillName);
});
tooltip.addEventListener('mouseleave', () => {
scheduleCollapse(container);
});
}
});
}
function findSkillTreeSection(container) {
let parent = container.parentElement;
while (parent) {
if (parent.querySelector('.advanced-tooltip')) {
return parent;
}
parent = parent.parentElement;
}
return document;
}
function buildGifMap(container) {
const gifMap = {};
const listData = container.getAttribute('data-gif-list');
if (!listData) return gifMap;
const entries = listData.split(';');
entries.forEach(entry => {
const [skillName, gifFile] = entry.split(':').map(s => s.trim());
if (skillName && gifFile) {
const gifUrl = '/images/' + gifFile;
gifMap[skillName] = gifUrl;
}
});
return gifMap;
}
function handleTooltipHover(container, gifUrl, skillName) {
clearTimeout(collapseTimer);
clearTimeout(expandTimer);
expandTimer = setTimeout(() => {
showGif(container, gifUrl, skillName);
}, CONFIG.expandDelay);
}
function showGif(container, gifUrl, skillName) {
const displayArea = container.querySelector('.' + CONFIG.displayClass);
if (!displayArea) return;
if (!container.classList.contains('expanded')) {
container.classList.add('expanded');
}
if (currentGif !== gifUrl) {
const imgContainer = displayArea.querySelector('.gif-image-container');
const caption = displayArea.querySelector('.gif-caption');
if (imgContainer) {
imgContainer.classList.add('loading');
const img = document.createElement('img');
img.src = gifUrl;
img.alt = skillName;
img.onload = () => {
imgContainer.innerHTML = '';
imgContainer.appendChild(img);
imgContainer.classList.remove('loading');
};
img.onerror = () => {
imgContainer.innerHTML = '<div class="gif-error">GIF not found</div>';
imgContainer.classList.remove('loading');
};
}
if (caption) {
caption.textContent = skillName;
}
currentGif = gifUrl;
}
}
function scheduleCollapse(container) {
clearTimeout(collapseTimer);
collapseTimer = setTimeout(() => {
container.classList.remove('expanded');
currentGif = null;
}, CONFIG.collapseDelay);
}
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;
}
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
document.addEventListener('DOMContentLoaded', function() {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length) {
init();
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
})();