MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
/* | /* | ||
* ========================================================== | * ========================================================== | ||
* GladiusRO Wiki | * GladiusRO Wiki - Permanent Sidebar Configuration | ||
* | * | ||
* 1. | * Functions: | ||
* 1. Keep Contents permanently in the left sidebar. | |||
* 2. Hide technical links from logged-out players. | * 2. Hide technical links from logged-out players. | ||
* 3. | * 3. Show technical links to logged-in administrators/editors. | ||
* ========================================================== | * ========================================================== | ||
*/ | */ | ||
| Line 12: | Line 13: | ||
'use strict'; | 'use strict'; | ||
var | var observerRunning = false; | ||
var | var refreshTimer = null; | ||
/* | /* | ||
* | * Find the left sidebar used by the current wiki skin. | ||
*/ | */ | ||
function | function getGladiusSidebar() { | ||
return document.getElementById('mw-panel') || | |||
document.getElementById('mw-navigation') || | |||
document.querySelector('.sidebar'); | |||
document. | } | ||
/* | |||
* Check whether the current visitor is logged in. | |||
* | |||
* Logged-out player: | |||
* wgUserName is null. | |||
* | |||
* Logged-in administrator/editor: | |||
* wgUserName contains the account name. | |||
*/ | |||
function isLoggedIn() { | |||
return mw.config.get('wgUserName') !== null; | |||
} | |||
/* | |||
* Create or retrieve the permanent TOC container. | |||
*/ | |||
function getTOCContainer() {* var container = | |||
* document.getElementById('gladius-sidebar-toc'); | |||
if (!container) { | |||
container = document.createElement('div'); | |||
if (! | |||
container.id = 'gladius-sidebar-toc'; | |||
container.className = 'portal mw-portlet'; | |||
container.setAttribute( | |||
'role', | 'role', | ||
'navigation' | 'navigation' | ||
); | ); | ||
container.setAttribute( | |||
'aria-label', | 'aria-label', | ||
'Page contents' | 'Page contents' | ||
); | ); | ||
} | |||
return container; | |||
} | |||
/* | |||
* Keep Contents permanently in the left sidebar. | |||
*/ | |||
function keepContentsInSidebar() { | |||
var sidebar = getGladiusSidebar(); | |||
var toc = document.getElementById('toc'); | |||
if (!sidebar) { | |||
return false; | |||
} | } | ||
if (! | /* | ||
* Do not create an empty Contents panel on pages | |||
* without a TOC. | |||
*/ | |||
var existingContainer = | |||
document.getElementById('gladius-sidebar-toc'); | |||
if (!toc && !existingContainer) { | |||
return false; | return false; | ||
} | } | ||
var container = | |||
existingContainer || getTOCContainer(); | |||
/* | /* | ||
* | * Attach the Contents container directly to | ||
* the left sidebar. | |||
* | * | ||
* This | * This makes placement independent of whether | ||
* | * Tools is visible or hidden. | ||
*/ | |||
if (container.parentNode !== sidebar) { | |||
sidebar.appendChild(container); | |||
} | |||
/* | |||
* Move the original article TOC into the | |||
* permanent sidebar container. | |||
*/ | |||
if (toc && toc.parentNode !== container) { | |||
container.appendChild(toc); | |||
} | |||
/* | |||
* Show the container when it contains a TOC. | |||
* Hide it on pages without a TOC. | |||
*/ | */ | ||
if (container.querySelector('#toc')) { | |||
container.style.removeProperty('display'); | |||
} else { | |||
container.style.setProperty( | |||
'display', | |||
'none', | |||
'important' | |||
); | |||
} | |||
return true; | return true; | ||
| Line 68: | Line 124: | ||
/* | /* | ||
* Hide | * Hide one element completely. | ||
*/ | */ | ||
function | function hideElement(element) { | ||
if (!element) { | |||
return; | |||
} | |||
element.style.setProperty( | |||
'display', | |||
'none', | |||
'important' | |||
); | |||
} | |||
/* | |||
* Restore an element when an administrator/editor | |||
* is logged in. | |||
*/ | |||
if ( | function restoreElement(element) { | ||
if (!element) { | |||
return; | return; | ||
} | } | ||
var | element.style.removeProperty('display'); | ||
} | |||
/* | |||
* Hide or show technical navigation links. | |||
*/ | |||
function updatePlayerNavigation() { | |||
var loggedIn = isLoggedIn(); | |||
/* | |||
* IDs commonly used by MediaWiki sidebar items. | |||
*/ | |||
var technicalElementIds * [ | |||
'n-recentchanges', | 'n-recentchanges', | ||
'n-randompage', | 'n-randompage', | ||
'n-help', | 'n-help', | ||
'n-help-mediawiki', | |||
'n-helppage', | |||
'p-tb' | 'p-tb' | ||
]; | ]; | ||
technicalElementIds.forEach(function (id) { | |||
var element = document.getElementById( | var element = document.getElementById(id); | ||
if ( | if (loggedIn) { | ||
element | restoreElement(element); | ||
} else { | |||
hideElement(element); | |||
); | |||
} | } | ||
}); | }); | ||
var | var sidebar = getGladiusSidebar(); | ||
if ( | if (!sidebar) { | ||
return; | return; | ||
} | } | ||
/* | /* | ||
* | * Fallback for older/custom skins where the | ||
* navigation items use different IDs. | |||
*/ | |||
var hiddenTexts = [ | |||
'recent changes', | |||
'random page', | |||
'help about mediawiki', | |||
'what links here', | |||
'related changes', | |||
'special pages', | |||
'printable version', | |||
'permanent link', | |||
'page information' | |||
]; | |||
var links = sidebar.q*erySelectorAll('a'); | |||
Arra*.prototype.forEach.call( | |||
* links, | |||
function (lin*) { | |||
var text = (li*k.textContent || '') | |||
.replace(/\s+/g, ' ') | |||
.trim() | |||
.toLowerCase(); | |||
var href = | |||
link.getAttribute('href') || ''; | |||
var hideThisLink = | |||
hiddenTexts.indexOf(text) !== -1 || | |||
href.indexOf( | |||
'mediawiki.org/wiki/Help' | |||
) !== -1; | |||
if (!hideThisLink) { | |||
return; | |||
} | |||
/* | |||
* Hide or restore the complete list row, | |||
* avoiding empty spaces in the sidebar. | |||
*/ | |||
var row = | |||
link.closest('li') || | |||
link.parentElement; | |||
if (loggedIn) { | |||
restoreElement(row); | |||
restoreElement(link); | |||
} else { | |||
hideElement(row || link); | |||
} | |||
} | |||
); | |||
/* | |||
* Fallback: find a section with the visible | |||
* heading "Tools" if #p-tb is unavailable. | |||
*/ | */ | ||
var sidebarElements = | |||
sidebar.querySelectorAll('div, h3, h4'); | |||
Array.prototype.forEach.call( | |||
sidebarElements, | |||
function (element) { | |||
var headingText = | |||
(element.textContent || '') | |||
.replace(/\s+/g, ' ') | |||
.trim() | |||
.toLowerCase(); | |||
/* | |||
* Avoid matching the whole sidebar, whose | |||
* text may include the word "Tools". | |||
*/ | |||
if ( | |||
headingText === 'tools' && | |||
!loggedIn | |||
) { | |||
var toolsSection = | |||
element.closest( | |||
'.portal, .mw-portlet' | |||
); | |||
if (toolsSection) { | |||
hideElement(toolsSection); | |||
} | |||
} | |||
} | |||
); | |||
} | } | ||
/* | /* | ||
* | * Apply all sidebar corrections. | ||
* | |||
* Contents is moved first. Technical links are hidden | |||
* afterward, ensuring that hiding Tools does not prevent | |||
* the TOC from being moved. | |||
*/ | */ | ||
function applyGladiusSidebar() { | |||
keepContentsInSidebar(); | |||
updatePlayerNavigation(); | |||
} | } | ||
/* | /* | ||
* | * Watch for MediaWiki or skin changes. | ||
* | |||
* If MediaWiki places Contents inside the article again, | |||
* the observer moves Contents back to the sidebar. | |||
*/ | */ | ||
function startGladiusObserve*() { | |||
' | if ( | ||
obse*verRunning || | |||
!document.body || | |||
typeof MutationObserver === 'undefined' | |||
) { | |||
return; | |||
} | } | ||
observerRunning = true; | |||
var observer = new MutationObserver(function () { | |||
window.clearTimeout(refreshTimer); | |||
window.setTimeout( | refreshTimer = window.setTimeout( | ||
applyGladiusSidebar, | |||
100 | 100 | ||
); | ); | ||
}); | |||
observer.observe(document.body, { | |||
childList: true, | |||
subtree: true | |||
}); | }); | ||
} | } | ||
/* | |||
* Initial setup. | |||
*/ | |||
function initialiseGladiusSidebar() { | |||
applyGladiusSidebar(); | |||
startGladiusObserver(); | |||
/* | |||
* Additional checks for older skins and | |||
* delayed ResourceLoader components. | |||
*/ | |||
window.setTimeout( | |||
applyGladiusSidebar, | |||
250 | |||
); | |||
window.setTimeout( | |||
applyGladiusSidebar, | |||
800 | |||
); | ); | ||
window.setTimeout( | |||
applyGladiusSidebar, | |||
1600 | |||
); | |||
} | } | ||
/* | |||
* Start when the document is ready. | |||
*/ | |||
if (document.readyState === 'loading') { | if (document.readyState === 'loading') { | ||
document.addEventListener( | document.addEventListener( | ||
'DOMContentLoaded', | 'DOMContentLoaded', | ||
initialiseGladiusSidebar | |||
); | ); | ||
} else { | } else { | ||
initialiseGladiusSidebar(); | |||
} | } | ||
/* | /* | ||
* Run again after | * Run again after images and skin assets finish loading. | ||
*/ | */ | ||
window.addEventListener( | window.addEventListener( | ||
'load', | 'load', | ||
applyGladiusSidebar | |||
); | ); | ||
/* | /* | ||
* Run | * Run after MediaWiki dynamically updates article content. | ||
*/ | */ | ||
if ( | if (mw.hook) { | ||
mw.ho*k('wikipage.content').add(function*() { | |||
window.setTimeout* | |||
applyGladiusSideb*r, | |||
window. | |||
100 | 100 | ||
*); | |||
}); | }); | ||
} | } | ||
}(mediaWiki)*; | |||
Revision as of 03:23, 2 August 2026
/*
* ==========================================================
* GladiusRO Wiki - Permanent Sidebar Configuration
*
* Functions:
* 1. Keep Contents permanently in the left sidebar.
* 2. Hide technical links from logged-out players.
* 3. Show technical links to logged-in administrators/editors.
* ==========================================================
*/
(function (mw) {
'use strict';
var observerRunning = false;
var refreshTimer = null;
/*
* Find the left sidebar used by the current wiki skin.
*/
function getGladiusSidebar() {
return document.getElementById('mw-panel') ||
document.getElementById('mw-navigation') ||
document.querySelector('.sidebar');
}
/*
* Check whether the current visitor is logged in.
*
* Logged-out player:
* wgUserName is null.
*
* Logged-in administrator/editor:
* wgUserName contains the account name.
*/
function isLoggedIn() {
return mw.config.get('wgUserName') !== null;
}
/*
* Create or retrieve the permanent TOC container.
*/
function getTOCContainer() {* var container =
* document.getElementById('gladius-sidebar-toc');
if (!container) {
container = document.createElement('div');
container.id = 'gladius-sidebar-toc';
container.className = 'portal mw-portlet';
container.setAttribute(
'role',
'navigation'
);
container.setAttribute(
'aria-label',
'Page contents'
);
}
return container;
}
/*
* Keep Contents permanently in the left sidebar.
*/
function keepContentsInSidebar() {
var sidebar = getGladiusSidebar();
var toc = document.getElementById('toc');
if (!sidebar) {
return false;
}
/*
* Do not create an empty Contents panel on pages
* without a TOC.
*/
var existingContainer =
document.getElementById('gladius-sidebar-toc');
if (!toc && !existingContainer) {
return false;
}
var container =
existingContainer || getTOCContainer();
/*
* Attach the Contents container directly to
* the left sidebar.
*
* This makes placement independent of whether
* Tools is visible or hidden.
*/
if (container.parentNode !== sidebar) {
sidebar.appendChild(container);
}
/*
* Move the original article TOC into the
* permanent sidebar container.
*/
if (toc && toc.parentNode !== container) {
container.appendChild(toc);
}
/*
* Show the container when it contains a TOC.
* Hide it on pages without a TOC.
*/
if (container.querySelector('#toc')) {
container.style.removeProperty('display');
} else {
container.style.setProperty(
'display',
'none',
'important'
);
}
return true;
}
/*
* Hide one element completely.
*/
function hideElement(element) {
if (!element) {
return;
}
element.style.setProperty(
'display',
'none',
'important'
);
}
/*
* Restore an element when an administrator/editor
* is logged in.
*/
function restoreElement(element) {
if (!element) {
return;
}
element.style.removeProperty('display');
}
/*
* Hide or show technical navigation links.
*/
function updatePlayerNavigation() {
var loggedIn = isLoggedIn();
/*
* IDs commonly used by MediaWiki sidebar items.
*/
var technicalElementIds * [
'n-recentchanges',
'n-randompage',
'n-help',
'n-help-mediawiki',
'n-helppage',
'p-tb'
];
technicalElementIds.forEach(function (id) {
var element = document.getElementById(id);
if (loggedIn) {
restoreElement(element);
} else {
hideElement(element);
}
});
var sidebar = getGladiusSidebar();
if (!sidebar) {
return;
}
/*
* Fallback for older/custom skins where the
* navigation items use different IDs.
*/
var hiddenTexts = [
'recent changes',
'random page',
'help about mediawiki',
'what links here',
'related changes',
'special pages',
'printable version',
'permanent link',
'page information'
];
var links = sidebar.q*erySelectorAll('a');
Arra*.prototype.forEach.call(
* links,
function (lin*) {
var text = (li*k.textContent || '')
.replace(/\s+/g, ' ')
.trim()
.toLowerCase();
var href =
link.getAttribute('href') || '';
var hideThisLink =
hiddenTexts.indexOf(text) !== -1 ||
href.indexOf(
'mediawiki.org/wiki/Help'
) !== -1;
if (!hideThisLink) {
return;
}
/*
* Hide or restore the complete list row,
* avoiding empty spaces in the sidebar.
*/
var row =
link.closest('li') ||
link.parentElement;
if (loggedIn) {
restoreElement(row);
restoreElement(link);
} else {
hideElement(row || link);
}
}
);
/*
* Fallback: find a section with the visible
* heading "Tools" if #p-tb is unavailable.
*/
var sidebarElements =
sidebar.querySelectorAll('div, h3, h4');
Array.prototype.forEach.call(
sidebarElements,
function (element) {
var headingText =
(element.textContent || '')
.replace(/\s+/g, ' ')
.trim()
.toLowerCase();
/*
* Avoid matching the whole sidebar, whose
* text may include the word "Tools".
*/
if (
headingText === 'tools' &&
!loggedIn
) {
var toolsSection =
element.closest(
'.portal, .mw-portlet'
);
if (toolsSection) {
hideElement(toolsSection);
}
}
}
);
}
/*
* Apply all sidebar corrections.
*
* Contents is moved first. Technical links are hidden
* afterward, ensuring that hiding Tools does not prevent
* the TOC from being moved.
*/
function applyGladiusSidebar() {
keepContentsInSidebar();
updatePlayerNavigation();
}
/*
* Watch for MediaWiki or skin changes.
*
* If MediaWiki places Contents inside the article again,
* the observer moves Contents back to the sidebar.
*/
function startGladiusObserve*() {
if (
obse*verRunning ||
!document.body ||
typeof MutationObserver === 'undefined'
) {
return;
}
observerRunning = true;
var observer = new MutationObserver(function () {
window.clearTimeout(refreshTimer);
refreshTimer = window.setTimeout(
applyGladiusSidebar,
100
);
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
/*
* Initial setup.
*/
function initialiseGladiusSidebar() {
applyGladiusSidebar();
startGladiusObserver();
/*
* Additional checks for older skins and
* delayed ResourceLoader components.
*/
window.setTimeout(
applyGladiusSidebar,
250
);
window.setTimeout(
applyGladiusSidebar,
800
);
window.setTimeout(
applyGladiusSidebar,
1600
);
}
/*
* Start when the document is ready.
*/
if (document.readyState === 'loading') {
document.addEventListener(
'DOMContentLoaded',
initialiseGladiusSidebar
);
} else {
initialiseGladiusSidebar();
}
/*
* Run again after images and skin assets finish loading.
*/
window.addEventListener(
'load',
applyGladiusSidebar
);
/*
* Run after MediaWiki dynamically updates article content.
*/
if (mw.hook) {
mw.ho*k('wikipage.content').add(function*() {
window.setTimeout*
applyGladiusSideb*r,
100
*);
});
}
}(mediaWiki)*;