MediaWiki:Common.js
MediaWiki interface page
More actions
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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */
/*
SpiritVale Skill Slider
What this does:
- Finds every skill card: <div class="sv-skill-card" data-max-level="10" data-level="10">
- Inserts a slider into: <div class="sv-level-slider"></div>
- Updates any element inside the card that has:
data-series='["Lv1 text","Lv2 text", ...]'
so that it shows the correct value for the chosen level.
*/
(function () {
// Ensure a number stays between a minimum and maximum.
function clampNumber(value, min, max) {
var n = parseInt(value, 10);
// If value is not a valid number, fall back to min.
if (isNaN(n)) {
return min;
}
if (n < min) return min;
if (n > max) return max;
return n;
}
// Initialize skill cards found under `root`.
// `root` is usually the page, but MediaWiki sometimes gives us just a section of HTML.
function initSkillCards(root) {
var container = root || document;
// Only pick cards we haven't initialized yet (data-sv-init is our marker).
var cards = container.querySelectorAll(".sv-skill-card:not([data-sv-init])");
cards.forEach(function (card) {
// Read max level from HTML attribute (default 1 if missing).
var maxLevel = clampNumber(card.getAttribute("data-max-level"), 1, 999);
// If max level is 1, there's no reason to create a slider.
if (maxLevel <= 1) {
card.setAttribute("data-sv-init", "1");
return;
}
// Read the starting level; if missing, default to max level.
var startLevel = card.getAttribute("data-level");
if (startLevel == null || startLevel === "") {
startLevel = maxLevel;
}
startLevel = clampNumber(startLevel, 1, maxLevel);
// Find where we should place the slider.
var sliderHost = card.querySelector(".sv-level-slider");
if (!sliderHost) {
// No placeholder = nothing to do.
card.setAttribute("data-sv-init", "1");
return;
}
// Optional: element that shows the current level number in text.
var levelNumberSpan = card.querySelector(".sv-level-num");
// Find all dynamic elements that contain a data-series list.
var dynamicElements = card.querySelectorAll("[data-series]");
// Parse the JSON data-series once and store it on the element for reuse.
dynamicElements.forEach(function (el) {
var raw = el.getAttribute("data-series");
try {
el._svSeries = JSON.parse(raw);
} catch (e) {
el._svSeries = null;
}
});
// Create the slider element.
var slider = document.createElement("input");
slider.type = "range";
slider.min = "1";
slider.max = String(maxLevel);
slider.value = String(startLevel);
slider.className = "sv-level-range";
// Clear any existing content in the host, then add the slider.
sliderHost.textContent = "";
sliderHost.appendChild(slider);
// Apply a given level to this card:
// - update the level number text
// - update all dynamic elements to show the correct series value
function applyLevel(level) {
var lv = clampNumber(level, 1, maxLevel);
// Store the chosen level on the card (optional, but useful for debugging).
card.setAttribute("data-level", String(lv));
// Update the visible "current level" number if present.
if (levelNumberSpan) {
levelNumberSpan.textContent = String(lv);
}
// Update each dynamic element:
// Level 1 => index 0, Level 2 => index 1, etc.
var index = lv - 1;
dynamicElements.forEach(function (el) {
var series = el._svSeries;
// If series is missing or not a proper list, skip it.
if (!series || !Array.isArray(series) || series.length === 0) {
return;
}
// If the series is shorter than maxLevel, clamp index to last element.
var safeIndex = index;
if (safeIndex >= series.length) {
safeIndex = series.length - 1;
}
var value = series[safeIndex];
// Put the chosen value into the element.
// Use an empty string if it's null/undefined.
if (value == null) {
el.textContent = "";
} else {
el.textContent = String(value);
}
});
}
// When the slider moves, update the card live.
slider.addEventListener("input", function () {
applyLevel(slider.value);
});
// Apply the starting level right away.
applyLevel(startLevel);
// Mark this card as initialized so we don't do it twice.
card.setAttribute("data-sv-init", "1");
});
}
// MediaWiki hook:
// Runs when page content is ready (and also after AJAX updates).
if (window.mw && mw.hook) {
mw.hook("wikipage.content").add(function ($content) {
// $content is usually a jQuery object; $content[0] is the real DOM node.
initSkillCards($content && $content[0]);
});
}
// Also run on normal page load as a fallback.
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", function () {
initSkillCards(document);
});
} else {
initSkillCards(document);
}
})();