MediaWiki:Common.js: Difference between revisions
From AnarchyMU Wiki
No edit summary |
No edit summary |
||
| (4 intermediate revisions by the same user not shown) | |||
| Line 20: | Line 20: | ||
})(); | })(); | ||
/* Update | /* Update 048: nested Stage dropdown v8 - clean row layout + per-stage overview child */ | ||
(function () { | (function () { | ||
function textOf(el) { | function textOf(el) { | ||
| Line 30: | Line 30: | ||
} | } | ||
function | function pageKeyOf(link) { | ||
return / | if (!link) return ''; | ||
var href = link.getAttribute('href') || ''; | |||
var title = link.getAttribute('title') || ''; | |||
var fromTitle = title.replace(/\s+/g, '_').trim(); | |||
if (fromTitle) return fromTitle; | |||
var fromQuery = href.match(/[?&](title|page)=([^&]+)/i); | |||
if (fromQuery && fromQuery[2]) return decodeURIComponent(fromQuery[2]); | |||
var parts = href.split('/'); | |||
return | return decodeURIComponent(parts[parts.length - 1] || ''); | ||
} | } | ||
| Line 43: | Line 50: | ||
for (i = 0; i < li.childNodes.length; i++) { | for (i = 0; i < li.childNodes.length; i++) { | ||
var n = li.childNodes[i]; | var n = li.childNodes[i]; | ||
if (n && n.nodeType === 1 && n.tagName && n.tagName.toLowerCase() === 'a') | if (n && n.nodeType === 1 && n.tagName && n.tagName.toLowerCase() === 'a') return n; | ||
} | } | ||
return null; | return null; | ||
| Line 56: | Line 61: | ||
for (i = 0; i < container.children.length; i++) { | for (i = 0; i < container.children.length; i++) { | ||
var c = container.children[i]; | var c = container.children[i]; | ||
if (c && c.tagName && c.tagName.toLowerCase() === 'li') | if (c && c.tagName && c.tagName.toLowerCase() === 'li') out.push(c); | ||
} | } | ||
return out; | return out; | ||
} | |||
function isStageLabel(labelNorm) { | |||
return /^stage\s+[1-4]$/i.test(labelNorm); | |||
} | |||
function stageNumberFromLabel(labelNorm) { | |||
var m = labelNorm.match(/^stage\s+([1-4])$/i); | |||
return m ? m[1] : null; | |||
} | |||
function isMiniLabel(labelNorm) { | |||
return /^mini\s+stage\s+\d+$/i.test(labelNorm); | |||
} | |||
function isStageOverviewKey(key, stageNum) { | |||
return key === 'Stage_' + stageNum + '_Overview'; | |||
} | |||
function isMiniForStage(key, stageNum) { | |||
if (stageNum === '1') return /^Mini_Stage_\d+$/.test(key); | |||
return new RegExp('^Stage_' + stageNum + '_Mini_Stage_\\d+$').test(key); | |||
} | } | ||
| Line 69: | Line 94: | ||
var stageCount = 0; | var stageCount = 0; | ||
var miniCount = 0; | var miniCount = 0; | ||
var i; | var i; | ||
for (i = 0; i < lis.length; i++) { | for (i = 0; i < lis.length; i++) { | ||
var label = norm(textOf(directLink(lis[i]))); | var label = norm(textOf(directLink(lis[i]))); | ||
if ( | if (/^stage\s+[1-4]$/i.test(label)) stageCount++; | ||
if ( | if (/^mini\s+stage\s+\d+$/i.test(label)) miniCount++; | ||
} | } | ||
if (stageCount >= 4 && miniCount >= 8) | if (stageCount >= 4 && miniCount >= 8) return stageCount * 100 + miniCount; | ||
return 0; | return 0; | ||
} | } | ||
function | function findStagesList() { | ||
var | var lists = document.querySelectorAll('ul, ol'); | ||
var best = null; | var best = null; | ||
var bestScore = 0; | var bestScore = 0; | ||
var i; | var i; | ||
for (i = 0; i < | for (i = 0; i < lists.length; i++) { | ||
var | var s = scoreContainer(lists[i]); | ||
if ( | if (s > bestScore) { | ||
bestScore = | bestScore = s; | ||
best = | best = lists[i]; | ||
} | } | ||
} | } | ||
return best; | return best; | ||
} | } | ||
function | function buildToggleHandler(stageLi, toggleEl) { | ||
return function (ev) { | return function (ev) { | ||
ev.preventDefault(); | ev.preventDefault(); | ||
ev.stopPropagation(); | ev.stopPropagation(); | ||
var open = stageLi.classList.toggle(' | ev.stopImmediatePropagation(); | ||
var open = stageLi.classList.toggle('stages-open'); | |||
toggleEl.textContent = open ? '▾' : '▸'; | |||
return false; | return false; | ||
}; | }; | ||
} | |||
function normalizeStageRow(stageLi, stageNum) { | |||
stageLi.className = (stageLi.className ? stageLi.className + ' ' : '') + 'stages-inner-parent stages-inner-stage-' + stageNum; | |||
stageLi.setAttribute('data-stage-num', stageNum); | |||
var link = directLink(stageLi); | |||
if (!link) return null; | |||
link.href = '#'; | |||
link.className = (link.className ? link.className + ' ' : '') + 'stages-inner-stage-link'; | |||
var toggle = document.createElement('button'); | |||
toggle.type = 'button'; | |||
toggle.className = 'stages-inner-toggle-btn'; | |||
toggle.setAttribute('aria-label', 'Toggle Stage ' + stageNum); | |||
toggle.textContent = '▸'; | |||
var handler = buildToggleHandler(stageLi, toggle); | |||
toggle.addEventListener('click', handler, true); | |||
link.addEventListener('click', handler, true); | |||
stageLi.appendChild(toggle); | |||
return stageLi; | |||
} | } | ||
function applyNestedStages() { | function applyNestedStages() { | ||
var list = | var list = findStagesList(); | ||
if (!list || list.dataset. | if (!list || list.dataset.stagesNestedV8Applied === '1') return; | ||
var items = childLis(list); | var items = childLis(list); | ||
| Line 122: | Line 167: | ||
var rebuilt = []; | var rebuilt = []; | ||
var currentStageLi = null; | var currentStageLi = null; | ||
var | var currentStageNum = null; | ||
var currentSub = null; | |||
var i; | var i; | ||
| Line 128: | Line 174: | ||
var li = items[i]; | var li = items[i]; | ||
var link = directLink(li); | var link = directLink(li); | ||
if (!link) { | |||
rebuilt.push(li.cloneNode(true)); | |||
continue; | |||
} | |||
var labelNorm = norm(textOf(link)); | |||
var key = pageKeyOf(link); | |||
if (isStageLabel(labelNorm)) { | |||
currentStageNum = stageNumberFromLabel(labelNorm); | |||
currentStageLi = normalizeStageRow(li.cloneNode(true), currentStageNum); | |||
currentSub = document.createElement('ul'); | |||
currentSub.className = 'stages-inner-submenu'; | |||
currentStageLi.appendChild(currentSub); | |||
currentStageLi.appendChild( | |||
rebuilt.push(currentStageLi); | rebuilt.push(currentStageLi); | ||
continue; | continue; | ||
} | } | ||
if ( | if (currentSub && currentStageNum) { | ||
if (isStageOverviewKey(key, currentStageNum) || isMiniForStage(key, currentStageNum)) { | |||
var childLi = li.cloneNode(true); | |||
childLi.className = (childLi.className ? childLi.className + ' ' : '') + 'stages-inner-child-item'; | |||
var childLink = directLink(childLi); | |||
if (childLink && isStageOverviewKey(key, currentStageNum)) { | |||
childLink.className = (childLink.className ? childLink.className + ' ' : '') + 'stages-overview-child-link'; | |||
} | |||
currentSub.appendChild(childLi); | |||
continue; | |||
} | |||
} | } | ||
currentStageLi = null; | currentStageLi = null; | ||
currentStageNum = null; | |||
currentSub = null; | |||
rebuilt.push(li.cloneNode(true)); | rebuilt.push(li.cloneNode(true)); | ||
} | } | ||
while (list.firstChild) | while (list.firstChild) list.removeChild(list.firstChild); | ||
for (i = 0; i < rebuilt.length; i++) list.appendChild(rebuilt[i]); | |||
for (i = 0; i < rebuilt.length; i++) | |||
list.dataset. | list.dataset.stagesNestedV8Applied = '1'; | ||
} | } | ||
function boot() { | function boot() { | ||
applyNestedStages(); | applyNestedStages(); | ||
setTimeout(applyNestedStages, 350); | |||
setTimeout(applyNestedStages, 900); | |||
setTimeout(applyNestedStages, 1600); | |||
} | } | ||
Latest revision as of 11:12, 20 March 2026
/* Any JavaScript here will be loaded for all users on every page load. */
// Ensures class card images use the intended foreground image if data-src is present.
(function () {
function applyDataSrc() {
var images = document.querySelectorAll('.mw-card-image img[data-src]');
for (var i = 0; i < images.length; i++) {
var img = images[i];
var dataSrc = img.getAttribute('data-src');
if (dataSrc && img.getAttribute('src') !== dataSrc) {
img.setAttribute('src', dataSrc);
}
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', applyDataSrc);
} else {
applyDataSrc();
}
})();
/* Update 048: nested Stage dropdown v8 - clean row layout + per-stage overview child */
(function () {
function textOf(el) {
return (el && el.textContent ? el.textContent : '').replace(/\s+/g, ' ').trim();
}
function norm(s) {
return (s || '').replace(/\s+/g, ' ').trim().toLowerCase();
}
function pageKeyOf(link) {
if (!link) return '';
var href = link.getAttribute('href') || '';
var title = link.getAttribute('title') || '';
var fromTitle = title.replace(/\s+/g, '_').trim();
if (fromTitle) return fromTitle;
var fromQuery = href.match(/[?&](title|page)=([^&]+)/i);
if (fromQuery && fromQuery[2]) return decodeURIComponent(fromQuery[2]);
var parts = href.split('/');
return decodeURIComponent(parts[parts.length - 1] || '');
}
function directLink(li) {
if (!li || !li.childNodes) return null;
var i;
for (i = 0; i < li.childNodes.length; i++) {
var n = li.childNodes[i];
if (n && n.nodeType === 1 && n.tagName && n.tagName.toLowerCase() === 'a') return n;
}
return null;
}
function childLis(container) {
if (!container || !container.children) return [];
var out = [];
var i;
for (i = 0; i < container.children.length; i++) {
var c = container.children[i];
if (c && c.tagName && c.tagName.toLowerCase() === 'li') out.push(c);
}
return out;
}
function isStageLabel(labelNorm) {
return /^stage\s+[1-4]$/i.test(labelNorm);
}
function stageNumberFromLabel(labelNorm) {
var m = labelNorm.match(/^stage\s+([1-4])$/i);
return m ? m[1] : null;
}
function isMiniLabel(labelNorm) {
return /^mini\s+stage\s+\d+$/i.test(labelNorm);
}
function isStageOverviewKey(key, stageNum) {
return key === 'Stage_' + stageNum + '_Overview';
}
function isMiniForStage(key, stageNum) {
if (stageNum === '1') return /^Mini_Stage_\d+$/.test(key);
return new RegExp('^Stage_' + stageNum + '_Mini_Stage_\\d+$').test(key);
}
function scoreContainer(container) {
var lis = childLis(container);
if (!lis.length) return 0;
var stageCount = 0;
var miniCount = 0;
var i;
for (i = 0; i < lis.length; i++) {
var label = norm(textOf(directLink(lis[i])));
if (/^stage\s+[1-4]$/i.test(label)) stageCount++;
if (/^mini\s+stage\s+\d+$/i.test(label)) miniCount++;
}
if (stageCount >= 4 && miniCount >= 8) return stageCount * 100 + miniCount;
return 0;
}
function findStagesList() {
var lists = document.querySelectorAll('ul, ol');
var best = null;
var bestScore = 0;
var i;
for (i = 0; i < lists.length; i++) {
var s = scoreContainer(lists[i]);
if (s > bestScore) {
bestScore = s;
best = lists[i];
}
}
return best;
}
function buildToggleHandler(stageLi, toggleEl) {
return function (ev) {
ev.preventDefault();
ev.stopPropagation();
ev.stopImmediatePropagation();
var open = stageLi.classList.toggle('stages-open');
toggleEl.textContent = open ? '▾' : '▸';
return false;
};
}
function normalizeStageRow(stageLi, stageNum) {
stageLi.className = (stageLi.className ? stageLi.className + ' ' : '') + 'stages-inner-parent stages-inner-stage-' + stageNum;
stageLi.setAttribute('data-stage-num', stageNum);
var link = directLink(stageLi);
if (!link) return null;
link.href = '#';
link.className = (link.className ? link.className + ' ' : '') + 'stages-inner-stage-link';
var toggle = document.createElement('button');
toggle.type = 'button';
toggle.className = 'stages-inner-toggle-btn';
toggle.setAttribute('aria-label', 'Toggle Stage ' + stageNum);
toggle.textContent = '▸';
var handler = buildToggleHandler(stageLi, toggle);
toggle.addEventListener('click', handler, true);
link.addEventListener('click', handler, true);
stageLi.appendChild(toggle);
return stageLi;
}
function applyNestedStages() {
var list = findStagesList();
if (!list || list.dataset.stagesNestedV8Applied === '1') return;
var items = childLis(list);
if (!items.length) return;
var rebuilt = [];
var currentStageLi = null;
var currentStageNum = null;
var currentSub = null;
var i;
for (i = 0; i < items.length; i++) {
var li = items[i];
var link = directLink(li);
if (!link) {
rebuilt.push(li.cloneNode(true));
continue;
}
var labelNorm = norm(textOf(link));
var key = pageKeyOf(link);
if (isStageLabel(labelNorm)) {
currentStageNum = stageNumberFromLabel(labelNorm);
currentStageLi = normalizeStageRow(li.cloneNode(true), currentStageNum);
currentSub = document.createElement('ul');
currentSub.className = 'stages-inner-submenu';
currentStageLi.appendChild(currentSub);
rebuilt.push(currentStageLi);
continue;
}
if (currentSub && currentStageNum) {
if (isStageOverviewKey(key, currentStageNum) || isMiniForStage(key, currentStageNum)) {
var childLi = li.cloneNode(true);
childLi.className = (childLi.className ? childLi.className + ' ' : '') + 'stages-inner-child-item';
var childLink = directLink(childLi);
if (childLink && isStageOverviewKey(key, currentStageNum)) {
childLink.className = (childLink.className ? childLink.className + ' ' : '') + 'stages-overview-child-link';
}
currentSub.appendChild(childLi);
continue;
}
}
currentStageLi = null;
currentStageNum = null;
currentSub = null;
rebuilt.push(li.cloneNode(true));
}
while (list.firstChild) list.removeChild(list.firstChild);
for (i = 0; i < rebuilt.length; i++) list.appendChild(rebuilt[i]);
list.dataset.stagesNestedV8Applied = '1';
}
function boot() {
applyNestedStages();
setTimeout(applyNestedStages, 350);
setTimeout(applyNestedStages, 900);
setTimeout(applyNestedStages, 1600);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();