MediaWiki:Common.js: Difference between revisions
Appearance
Replacing page with '→* Moved to Monobook.js for testing purposes in order to have the ability to switch skins instead of injecting the code in this page to everyone *: ' |
No edit summary |
||
| (One intermediate revision by one other user not shown) | |||
| Line 1: | Line 1: | ||
/** | /* Any JavaScript here will be loaded for all users on every page load. */ | ||
/* ========================================================================== | |||
DEV VANIQUOTES - VECTOR 2022 COMMON.JS | |||
Adapted from the working dev Vanisource Common.js. | |||
========================================================================== */ | |||
// SIDEBAR ACCORDION - STRICT LEFT-COLUMN ISOLATION & TRUE ACCORDION | |||
(function() { | |||
function tagSidebarMenus() { | |||
var allMenus = document.querySelectorAll('.vector-menu'); | |||
for (var i = 0; i < allMenus.length; i++) { | |||
var menu = allMenus[i]; | |||
// Only menus inside the modern or legacy left sidebar containers | |||
if (menu.closest('#vector-main-menu, #mw-panel, #mw-navigation')) { | |||
menu.classList.add('vanipedia-sidebar-menu'); | |||
if (menu.querySelector('.vector-menu-heading') && !menu.classList.contains('vanipedia-collapsed')) { | |||
menu.classList.add('vanipedia-collapsed'); | |||
} | |||
} | |||
} | |||
} | |||
tagSidebarMenus(); | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', tagSidebarMenus); | |||
} | |||
// Inject CSS targeted strictly at our tagged sidebar menus | |||
var style = document.createElement('style'); | |||
style.textContent = | |||
'.vanipedia-sidebar-menu { width: 185px !important; } ' + | |||
'.vanipedia-sidebar-menu.vanipedia-collapsed .vector-menu-content { display: none !important; } ' + | |||
'.vanipedia-sidebar-menu .vector-menu-heading { ' + | |||
' cursor: pointer !important; ' + | |||
' background-color: #2c4c50 !important; ' + | |||
' border: 1px solid #1b3033 !important; ' + | |||
' border-radius: 4px !important; ' + | |||
' margin-bottom: 4px !important; ' + | |||
' padding: 10px 12px !important; ' + | |||
' font-weight: 600 !important; ' + | |||
' color: #ffffff !important; ' + | |||
' display: flex !important; ' + | |||
' justify-content: space-between !important; ' + | |||
' align-items: center !important; ' + | |||
' gap: 10px !important; ' + | |||
' transition: all 0.2s ease; ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu:not(.vanipedia-collapsed) .vector-menu-heading { ' + | |||
' border-radius: 4px 4px 0 0 !important; ' + | |||
' margin-bottom: 0 !important; ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu .vector-menu-heading:hover { ' + | |||
' background-color: #385e63 !important; ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu .vector-menu-heading::after { ' + | |||
' content: "▼"; ' + | |||
' font-size: 0.75em; ' + | |||
' color: #ffffff !important; ' + | |||
' transition: transform 0.2s ease; ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu.vanipedia-collapsed .vector-menu-heading::after { ' + | |||
' transform: rotate(-90deg); ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu .vector-menu-content { ' + | |||
' background-color: #eaeff0 !important; ' + | |||
' border: 1px solid #2c4c50 !important; ' + | |||
' border-top: none !important; ' + | |||
' border-radius: 0 0 4px 4px !important; ' + | |||
' padding: 0 0 4px 0 !important; ' + | |||
' margin-bottom: 6px !important; ' + | |||
' box-shadow: 0 3px 6px rgba(0,0,0,0.15) !important; ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu .vector-menu-content ul { ' + | |||
' list-style: none !important; ' + | |||
' margin: 0 !important; ' + | |||
' padding: 0 !important; ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu .vector-menu-content li a { ' + | |||
' display: block !important; ' + | |||
' padding: 8px 12px 8px 16px !important; ' + | |||
' color: #1b3033 !important; ' + | |||
' text-decoration: none !important; ' + | |||
' border-left: 3px solid transparent !important; ' + | |||
' border-bottom: 1px solid rgba(44, 76, 80, 0.1) !important; ' + | |||
' transition: all 0.15s ease !important; ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu .vector-menu-content li:last-child a { ' + | |||
' border-bottom: none !important; ' + | |||
'} ' + | |||
'.vanipedia-sidebar-menu .vector-menu-content li a:hover { ' + | |||
' background-color: #dbe4e6 !important; ' + | |||
' border-left: 3px solid #2c4c50 !important; ' + | |||
' color: #000000 !important; ' + | |||
'} '; | |||
document.head.appendChild(style); | |||
function collapseAllSidebarMenus() { | |||
var menus = document.querySelectorAll('.vanipedia-sidebar-menu'); | |||
for (var i = 0; i < menus.length; i++) { | |||
menus[i].classList.add('vanipedia-collapsed'); | |||
} | |||
} | |||
document.addEventListener('click', function(e) { | |||
var heading = e.target.closest('.vector-menu-heading'); | |||
if (!heading) return; | |||
var navContainer = heading.closest('.vanipedia-sidebar-menu'); | |||
if (navContainer) { | |||
var isAlreadyOpen = !navContainer.classList.contains('vanipedia-collapsed'); | |||
collapseAllSidebarMenus(); | |||
if (!isAlreadyOpen) { | |||
navContainer.classList.remove('vanipedia-collapsed'); | |||
} | |||
e.stopPropagation(); | |||
e.preventDefault(); | |||
} | |||
}, true); | |||
})(); | |||
// RESTRICT ADMINISTRATIVE UI BY USER GROUP | |||
mw.loader.using('mediawiki.user').then(function() { | |||
var userGroups = mw.config.get('wgUserGroups') || []; | |||
var isAuthorized = | |||
userGroups.includes('sysop') || | |||
userGroups.includes('interface-admin') || | |||
userGroups.includes('Editor'); | |||
if (!isAuthorized) { | |||
document.body.classList.add('restricted-ui'); | |||
} | |||
}); | |||
// OPEN ACCORDIONS FROM TABLE OF CONTENTS | |||
mw.hook('wikipage.content').add(function() { | |||
function handleAccordionTOC(hash) { | |||
if (!hash || hash === '#') return false; | |||
try { | |||
var targetId = hash.substring(1); | |||
var targetElement = | |||
document.getElementById(targetId) || | |||
document.getElementById(decodeURIComponent(targetId)); | |||
if (!targetElement) return false; | |||
var $target = $(targetElement); | |||
var $heading = $target.is('h2, h3') ? $target : $target.closest('h2, h3'); | |||
if (!$heading.length) return false; | |||
var $accordion = $heading.next('.book-accordion'); | |||
var $parentAccordions = $heading.parents('.book-accordion'); | |||
if (!$accordion.length && !$parentAccordions.length) return false; | |||
// Open all ancestor accordions | |||
$parentAccordions.each(function() { | |||
var $parentCollapsible = $(this).children('.mw-collapsible'); | |||
if ($parentCollapsible.length && $parentCollapsible.hasClass('mw-collapsed')) { | |||
var pId = $parentCollapsible.attr('id'); | |||
if (pId) { | |||
var pToggleClass = pId.replace( | |||
'mw-customcollapsible-', | |||
'mw-customtoggle-' | |||
); | |||
$('.' + pToggleClass).first().click(); | |||
} | |||
} | |||
}); | |||
// Open accordion immediately following heading | |||
if ($accordion.length) { | |||
var $collapsible = $accordion.children( | |||
'.mw-collapsible, .mw-collapsible-content' | |||
).first(); | |||
if (!$collapsible.length) { | |||
$collapsible = $accordion.find('.mw-collapsible'); | |||
} | |||
if ($collapsible.length && $collapsible.hasClass('mw-collapsed')) { | |||
var collapsibleId = $collapsible.attr('id'); | |||
if (collapsibleId) { | |||
var toggleClass = collapsibleId.replace( | |||
'mw-customcollapsible-', | |||
'mw-customtoggle-' | |||
); | |||
$('.' + toggleClass).first().click(); | |||
} | |||
} | |||
} | |||
var $scrollTarget = $accordion.length ? $accordion : $heading; | |||
setTimeout(function() { | |||
$('html, body').animate({ | |||
scrollTop: $scrollTarget.offset().top - 75 | |||
}, 300); | |||
}, 100); | |||
return true; | |||
} catch (e) { | |||
console.error('TOC Accordion script error:', e); | |||
return false; | |||
} | |||
} | |||
$(document) | |||
.off('click.tocAccordion') | |||
.on('click.tocAccordion', 'a[href^="#"]', function(e) { | |||
if ($(this).closest('#toc, .toc, .vector-toc').length > 0) { | |||
var href = $(this).attr('href'); | |||
var isAccordion = handleAccordionTOC(href); | |||
if (isAccordion) { | |||
e.preventDefault(); | |||
if (history.pushState) { | |||
history.pushState(null, null, href); | |||
} else { | |||
window.location.hash = href; | |||
} | |||
} | |||
} | |||
}); | |||
if (window.location.hash) { | |||
setTimeout(function() { | |||
handleAccordionTOC(window.location.hash); | |||
}, 500); | |||
} | |||
}); | |||
// STICKY BURGER MENU - PURE FLOATING DROPDOWN | |||
(function() { | |||
let isMenuOpen = false; | |||
function forceUnpinSidebar() { | |||
document.documentElement.classList.remove( | |||
'vector-feature-main-menu-pinned-enabled', | |||
'vector-feature-main-menu-pinned-clientpref-1' | |||
); | |||
document.documentElement.classList.add( | |||
'vector-feature-main-menu-pinned-disabled', | |||
'vector-feature-main-menu-pinned-clientpref-0' | |||
); | |||
if (document.body) { | |||
document.body.classList.remove( | |||
'vector-feature-main-menu-pinned-enabled', | |||
'vector-feature-main-menu-pinned-clientpref-1' | |||
); | |||
document.body.classList.add( | |||
'vector-feature-main-menu-pinned-disabled', | |||
'vector-feature-main-menu-pinned-clientpref-0' | |||
); | |||
} | |||
document.cookie = 'vector-feature-main-menu-pinned=0; path=/; max-age=31536000'; | |||
try { | |||
localStorage.setItem('vector-feature-main-menu-pinned', '0'); | |||
} catch(e) {} | |||
var mainMenu = document.getElementById('vector-main-menu'); | |||
var unpinnedContainer = | |||
document.getElementById('vector-main-menu-unpinned-container') || | |||
document.querySelector('#vector-main-menu-dropdown .vector-dropdown-content'); | |||
var pinnedContainer = | |||
document.getElementById('vector-main-menu-pinned-container'); | |||
if ( | |||
mainMenu && | |||
unpinnedContainer && | |||
pinnedContainer && | |||
pinnedContainer.contains(mainMenu) | |||
) { | |||
unpinnedContainer.appendChild(mainMenu); | |||
} | |||
} | |||
function getDropdownElement() { | |||
return ( | |||
document.querySelector('#vector-main-menu-dropdown .vector-dropdown-content') || | |||
document.getElementById('vector-main-menu-dropdown-content') || | |||
document.getElementById('vector-main-menu-unpinned-container') || | |||
document.getElementById('vector-main-menu') | |||
); | |||
} | |||
function openMenu(menuBtn) { | |||
forceUnpinSidebar(); | |||
var checkbox = document.getElementById('vector-main-menu-dropdown-checkbox'); | |||
var dropdown = getDropdownElement(); | |||
if (!dropdown) return; | |||
if (checkbox) { | |||
checkbox.checked = true; | |||
checkbox.dispatchEvent(new Event('change', { bubbles: true })); | |||
} | |||
var rect = menuBtn.getBoundingClientRect(); | |||
dropdown.style.setProperty('position', 'fixed', 'important'); | |||
dropdown.style.setProperty('top', rect.bottom + 'px', 'important'); | |||
dropdown.style.setProperty('left', rect.left + 'px', 'important'); | |||
dropdown.style.setProperty('z-index', '99999', 'important'); | |||
dropdown.style.setProperty( | |||
'max-height', | |||
(window.innerHeight - rect.bottom - 16) + 'px', | |||
'important' | |||
); | |||
dropdown.style.setProperty('overflow-y', 'auto', 'important'); | |||
dropdown.style.setProperty('display', 'block', 'important'); | |||
dropdown.style.setProperty('visibility', 'visible', 'important'); | |||
dropdown.style.setProperty('opacity', '1', 'important'); | |||
dropdown.style.setProperty( | |||
'background-color', | |||
'var(--background-color-base, #ffffff)', | |||
'important' | |||
); | |||
dropdown.style.setProperty( | |||
'box-shadow', | |||
'0 4px 16px rgba(0, 0, 0, 0.2)', | |||
'important' | |||
); | |||
dropdown.style.setProperty('border-radius', '4px', 'important'); | |||
isMenuOpen = true; | |||
} | |||
function closeMenu() { | |||
var checkbox = document.getElementById('vector-main-menu-dropdown-checkbox'); | |||
var dropdown = getDropdownElement(); | |||
if (!dropdown) return; | |||
if (checkbox) { | |||
checkbox.checked = false; | |||
checkbox.dispatchEvent(new Event('change', { bubbles: true })); | |||
} | |||
dropdown.style.removeProperty('position'); | |||
dropdown.style.removeProperty('top'); | |||
dropdown.style.removeProperty('left'); | |||
dropdown.style.removeProperty('z-index'); | |||
dropdown.style.removeProperty('max-height'); | |||
dropdown.style.removeProperty('overflow-y'); | |||
dropdown.style.removeProperty('background-color'); | |||
dropdown.style.removeProperty('box-shadow'); | |||
dropdown.style.removeProperty('border-radius'); | |||
dropdown.style.setProperty('display', 'none', 'important'); | |||
dropdown.style.setProperty('visibility', 'hidden', 'important'); | |||
dropdown.style.setProperty('opacity', '0', 'important'); | |||
isMenuOpen = false; | |||
} | |||
function initStickyBurger() { | |||
forceUnpinSidebar(); | |||
var stickyHeader = document.getElementById('vector-sticky-header'); | |||
if (!stickyHeader) return false; | |||
if (document.getElementById('vanipedia-sticky-main-menu')) { | |||
return true; | |||
} | |||
var menuBtn = document.createElement('div'); | |||
menuBtn.id = 'vanipedia-sticky-main-menu'; | |||
menuBtn.title = 'Main menu'; | |||
menuBtn.style.cursor = 'pointer'; | |||
menuBtn.className = | |||
'vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--icon-only'; | |||
var iconSpan = document.createElement('span'); | |||
iconSpan.className = | |||
'vector-icon mw-ui-icon-menu mw-ui-icon-wikimedia-menu'; | |||
menuBtn.appendChild(iconSpan); | |||
menuBtn.addEventListener('click', function(e) { | |||
e.preventDefault(); | |||
e.stopPropagation(); | |||
if (isMenuOpen) { | |||
closeMenu(); | |||
} else { | |||
openMenu(menuBtn); | |||
} | |||
}); | |||
var startContainer = stickyHeader.querySelector( | |||
'.vector-sticky-header-start' | |||
); | |||
if (!startContainer) { | |||
startContainer = document.createElement('div'); | |||
startContainer.className = 'vector-sticky-header-start'; | |||
stickyHeader.insertBefore(startContainer, stickyHeader.firstChild); | |||
} | |||
startContainer.insertBefore(menuBtn, startContainer.firstChild); | |||
return true; | |||
} | |||
// Close menu when clicking outside | |||
document.addEventListener('click', function(e) { | |||
if (!isMenuOpen) return; | |||
var menuBtn = document.getElementById('vanipedia-sticky-main-menu'); | |||
var dropdown = getDropdownElement(); | |||
if ( | |||
dropdown && | |||
menuBtn && | |||
!menuBtn.contains(e.target) && | |||
!dropdown.contains(e.target) | |||
) { | |||
closeMenu(); | |||
} | |||
}); | |||
// Bootstrap initializer | |||
if (!initStickyBurger()) { | |||
var checkTimer = setInterval(function() { | |||
if (initStickyBurger()) { | |||
clearInterval(checkTimer); | |||
} | |||
}, 100); | |||
setTimeout(function() { | |||
clearInterval(checkTimer); | |||
}, 4000); | |||
} | |||
mw.hook('wikipage.content').add(initStickyBurger); | |||
$(initStickyBurger); | |||
})(); | |||
// FLOATING "BACK TO TOP" BUTTON | |||
(function() { | |||
function initBackToTop() { | |||
if (document.getElementById('vanipedia-back-to-top')) return; | |||
var btn = document.createElement('button'); | |||
btn.id = 'vanipedia-back-to-top'; | |||
btn.title = 'Back to top'; | |||
btn.setAttribute('aria-label', 'Back to top'); | |||
btn.innerHTML = | |||
'<svg xmlns="http://www.w3.org/2000/svg" ' + | |||
'width="22" height="22" viewBox="0 0 24 24" ' + | |||
'fill="none" stroke="currentColor" stroke-width="2.5" ' + | |||
'stroke-linecap="round" stroke-linejoin="round">' + | |||
'<polyline points="18 15 12 9 6 15"></polyline>' + | |||
'</svg>'; | |||
btn.addEventListener('click', function(e) { | |||
e.preventDefault(); | |||
window.scrollTo({ | |||
top: 0, | |||
behavior: 'smooth' | |||
}); | |||
}); | |||
function toggleVisibility() { | |||
if (window.scrollY > 300) { | |||
btn.classList.add('visible'); | |||
} else { | |||
btn.classList.remove('visible'); | |||
} | |||
} | |||
window.addEventListener('scroll', toggleVisibility, { passive: true }); | |||
toggleVisibility(); | |||
document.body.appendChild(btn); | |||
} | |||
$(initBackToTop); | |||
mw.hook('wikipage.content').add(initBackToTop); | |||
})(); | |||
Latest revision as of 05:56, 20 September 2026
/* Any JavaScript here will be loaded for all users on every page load. */
/* ==========================================================================
DEV VANIQUOTES - VECTOR 2022 COMMON.JS
Adapted from the working dev Vanisource Common.js.
========================================================================== */
// SIDEBAR ACCORDION - STRICT LEFT-COLUMN ISOLATION & TRUE ACCORDION
(function() {
function tagSidebarMenus() {
var allMenus = document.querySelectorAll('.vector-menu');
for (var i = 0; i < allMenus.length; i++) {
var menu = allMenus[i];
// Only menus inside the modern or legacy left sidebar containers
if (menu.closest('#vector-main-menu, #mw-panel, #mw-navigation')) {
menu.classList.add('vanipedia-sidebar-menu');
if (menu.querySelector('.vector-menu-heading') && !menu.classList.contains('vanipedia-collapsed')) {
menu.classList.add('vanipedia-collapsed');
}
}
}
}
tagSidebarMenus();
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', tagSidebarMenus);
}
// Inject CSS targeted strictly at our tagged sidebar menus
var style = document.createElement('style');
style.textContent =
'.vanipedia-sidebar-menu { width: 185px !important; } ' +
'.vanipedia-sidebar-menu.vanipedia-collapsed .vector-menu-content { display: none !important; } ' +
'.vanipedia-sidebar-menu .vector-menu-heading { ' +
' cursor: pointer !important; ' +
' background-color: #2c4c50 !important; ' +
' border: 1px solid #1b3033 !important; ' +
' border-radius: 4px !important; ' +
' margin-bottom: 4px !important; ' +
' padding: 10px 12px !important; ' +
' font-weight: 600 !important; ' +
' color: #ffffff !important; ' +
' display: flex !important; ' +
' justify-content: space-between !important; ' +
' align-items: center !important; ' +
' gap: 10px !important; ' +
' transition: all 0.2s ease; ' +
'} ' +
'.vanipedia-sidebar-menu:not(.vanipedia-collapsed) .vector-menu-heading { ' +
' border-radius: 4px 4px 0 0 !important; ' +
' margin-bottom: 0 !important; ' +
'} ' +
'.vanipedia-sidebar-menu .vector-menu-heading:hover { ' +
' background-color: #385e63 !important; ' +
'} ' +
'.vanipedia-sidebar-menu .vector-menu-heading::after { ' +
' content: "▼"; ' +
' font-size: 0.75em; ' +
' color: #ffffff !important; ' +
' transition: transform 0.2s ease; ' +
'} ' +
'.vanipedia-sidebar-menu.vanipedia-collapsed .vector-menu-heading::after { ' +
' transform: rotate(-90deg); ' +
'} ' +
'.vanipedia-sidebar-menu .vector-menu-content { ' +
' background-color: #eaeff0 !important; ' +
' border: 1px solid #2c4c50 !important; ' +
' border-top: none !important; ' +
' border-radius: 0 0 4px 4px !important; ' +
' padding: 0 0 4px 0 !important; ' +
' margin-bottom: 6px !important; ' +
' box-shadow: 0 3px 6px rgba(0,0,0,0.15) !important; ' +
'} ' +
'.vanipedia-sidebar-menu .vector-menu-content ul { ' +
' list-style: none !important; ' +
' margin: 0 !important; ' +
' padding: 0 !important; ' +
'} ' +
'.vanipedia-sidebar-menu .vector-menu-content li a { ' +
' display: block !important; ' +
' padding: 8px 12px 8px 16px !important; ' +
' color: #1b3033 !important; ' +
' text-decoration: none !important; ' +
' border-left: 3px solid transparent !important; ' +
' border-bottom: 1px solid rgba(44, 76, 80, 0.1) !important; ' +
' transition: all 0.15s ease !important; ' +
'} ' +
'.vanipedia-sidebar-menu .vector-menu-content li:last-child a { ' +
' border-bottom: none !important; ' +
'} ' +
'.vanipedia-sidebar-menu .vector-menu-content li a:hover { ' +
' background-color: #dbe4e6 !important; ' +
' border-left: 3px solid #2c4c50 !important; ' +
' color: #000000 !important; ' +
'} ';
document.head.appendChild(style);
function collapseAllSidebarMenus() {
var menus = document.querySelectorAll('.vanipedia-sidebar-menu');
for (var i = 0; i < menus.length; i++) {
menus[i].classList.add('vanipedia-collapsed');
}
}
document.addEventListener('click', function(e) {
var heading = e.target.closest('.vector-menu-heading');
if (!heading) return;
var navContainer = heading.closest('.vanipedia-sidebar-menu');
if (navContainer) {
var isAlreadyOpen = !navContainer.classList.contains('vanipedia-collapsed');
collapseAllSidebarMenus();
if (!isAlreadyOpen) {
navContainer.classList.remove('vanipedia-collapsed');
}
e.stopPropagation();
e.preventDefault();
}
}, true);
})();
// RESTRICT ADMINISTRATIVE UI BY USER GROUP
mw.loader.using('mediawiki.user').then(function() {
var userGroups = mw.config.get('wgUserGroups') || [];
var isAuthorized =
userGroups.includes('sysop') ||
userGroups.includes('interface-admin') ||
userGroups.includes('Editor');
if (!isAuthorized) {
document.body.classList.add('restricted-ui');
}
});
// OPEN ACCORDIONS FROM TABLE OF CONTENTS
mw.hook('wikipage.content').add(function() {
function handleAccordionTOC(hash) {
if (!hash || hash === '#') return false;
try {
var targetId = hash.substring(1);
var targetElement =
document.getElementById(targetId) ||
document.getElementById(decodeURIComponent(targetId));
if (!targetElement) return false;
var $target = $(targetElement);
var $heading = $target.is('h2, h3') ? $target : $target.closest('h2, h3');
if (!$heading.length) return false;
var $accordion = $heading.next('.book-accordion');
var $parentAccordions = $heading.parents('.book-accordion');
if (!$accordion.length && !$parentAccordions.length) return false;
// Open all ancestor accordions
$parentAccordions.each(function() {
var $parentCollapsible = $(this).children('.mw-collapsible');
if ($parentCollapsible.length && $parentCollapsible.hasClass('mw-collapsed')) {
var pId = $parentCollapsible.attr('id');
if (pId) {
var pToggleClass = pId.replace(
'mw-customcollapsible-',
'mw-customtoggle-'
);
$('.' + pToggleClass).first().click();
}
}
});
// Open accordion immediately following heading
if ($accordion.length) {
var $collapsible = $accordion.children(
'.mw-collapsible, .mw-collapsible-content'
).first();
if (!$collapsible.length) {
$collapsible = $accordion.find('.mw-collapsible');
}
if ($collapsible.length && $collapsible.hasClass('mw-collapsed')) {
var collapsibleId = $collapsible.attr('id');
if (collapsibleId) {
var toggleClass = collapsibleId.replace(
'mw-customcollapsible-',
'mw-customtoggle-'
);
$('.' + toggleClass).first().click();
}
}
}
var $scrollTarget = $accordion.length ? $accordion : $heading;
setTimeout(function() {
$('html, body').animate({
scrollTop: $scrollTarget.offset().top - 75
}, 300);
}, 100);
return true;
} catch (e) {
console.error('TOC Accordion script error:', e);
return false;
}
}
$(document)
.off('click.tocAccordion')
.on('click.tocAccordion', 'a[href^="#"]', function(e) {
if ($(this).closest('#toc, .toc, .vector-toc').length > 0) {
var href = $(this).attr('href');
var isAccordion = handleAccordionTOC(href);
if (isAccordion) {
e.preventDefault();
if (history.pushState) {
history.pushState(null, null, href);
} else {
window.location.hash = href;
}
}
}
});
if (window.location.hash) {
setTimeout(function() {
handleAccordionTOC(window.location.hash);
}, 500);
}
});
// STICKY BURGER MENU - PURE FLOATING DROPDOWN
(function() {
let isMenuOpen = false;
function forceUnpinSidebar() {
document.documentElement.classList.remove(
'vector-feature-main-menu-pinned-enabled',
'vector-feature-main-menu-pinned-clientpref-1'
);
document.documentElement.classList.add(
'vector-feature-main-menu-pinned-disabled',
'vector-feature-main-menu-pinned-clientpref-0'
);
if (document.body) {
document.body.classList.remove(
'vector-feature-main-menu-pinned-enabled',
'vector-feature-main-menu-pinned-clientpref-1'
);
document.body.classList.add(
'vector-feature-main-menu-pinned-disabled',
'vector-feature-main-menu-pinned-clientpref-0'
);
}
document.cookie = 'vector-feature-main-menu-pinned=0; path=/; max-age=31536000';
try {
localStorage.setItem('vector-feature-main-menu-pinned', '0');
} catch(e) {}
var mainMenu = document.getElementById('vector-main-menu');
var unpinnedContainer =
document.getElementById('vector-main-menu-unpinned-container') ||
document.querySelector('#vector-main-menu-dropdown .vector-dropdown-content');
var pinnedContainer =
document.getElementById('vector-main-menu-pinned-container');
if (
mainMenu &&
unpinnedContainer &&
pinnedContainer &&
pinnedContainer.contains(mainMenu)
) {
unpinnedContainer.appendChild(mainMenu);
}
}
function getDropdownElement() {
return (
document.querySelector('#vector-main-menu-dropdown .vector-dropdown-content') ||
document.getElementById('vector-main-menu-dropdown-content') ||
document.getElementById('vector-main-menu-unpinned-container') ||
document.getElementById('vector-main-menu')
);
}
function openMenu(menuBtn) {
forceUnpinSidebar();
var checkbox = document.getElementById('vector-main-menu-dropdown-checkbox');
var dropdown = getDropdownElement();
if (!dropdown) return;
if (checkbox) {
checkbox.checked = true;
checkbox.dispatchEvent(new Event('change', { bubbles: true }));
}
var rect = menuBtn.getBoundingClientRect();
dropdown.style.setProperty('position', 'fixed', 'important');
dropdown.style.setProperty('top', rect.bottom + 'px', 'important');
dropdown.style.setProperty('left', rect.left + 'px', 'important');
dropdown.style.setProperty('z-index', '99999', 'important');
dropdown.style.setProperty(
'max-height',
(window.innerHeight - rect.bottom - 16) + 'px',
'important'
);
dropdown.style.setProperty('overflow-y', 'auto', 'important');
dropdown.style.setProperty('display', 'block', 'important');
dropdown.style.setProperty('visibility', 'visible', 'important');
dropdown.style.setProperty('opacity', '1', 'important');
dropdown.style.setProperty(
'background-color',
'var(--background-color-base, #ffffff)',
'important'
);
dropdown.style.setProperty(
'box-shadow',
'0 4px 16px rgba(0, 0, 0, 0.2)',
'important'
);
dropdown.style.setProperty('border-radius', '4px', 'important');
isMenuOpen = true;
}
function closeMenu() {
var checkbox = document.getElementById('vector-main-menu-dropdown-checkbox');
var dropdown = getDropdownElement();
if (!dropdown) return;
if (checkbox) {
checkbox.checked = false;
checkbox.dispatchEvent(new Event('change', { bubbles: true }));
}
dropdown.style.removeProperty('position');
dropdown.style.removeProperty('top');
dropdown.style.removeProperty('left');
dropdown.style.removeProperty('z-index');
dropdown.style.removeProperty('max-height');
dropdown.style.removeProperty('overflow-y');
dropdown.style.removeProperty('background-color');
dropdown.style.removeProperty('box-shadow');
dropdown.style.removeProperty('border-radius');
dropdown.style.setProperty('display', 'none', 'important');
dropdown.style.setProperty('visibility', 'hidden', 'important');
dropdown.style.setProperty('opacity', '0', 'important');
isMenuOpen = false;
}
function initStickyBurger() {
forceUnpinSidebar();
var stickyHeader = document.getElementById('vector-sticky-header');
if (!stickyHeader) return false;
if (document.getElementById('vanipedia-sticky-main-menu')) {
return true;
}
var menuBtn = document.createElement('div');
menuBtn.id = 'vanipedia-sticky-main-menu';
menuBtn.title = 'Main menu';
menuBtn.style.cursor = 'pointer';
menuBtn.className =
'vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--icon-only';
var iconSpan = document.createElement('span');
iconSpan.className =
'vector-icon mw-ui-icon-menu mw-ui-icon-wikimedia-menu';
menuBtn.appendChild(iconSpan);
menuBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
if (isMenuOpen) {
closeMenu();
} else {
openMenu(menuBtn);
}
});
var startContainer = stickyHeader.querySelector(
'.vector-sticky-header-start'
);
if (!startContainer) {
startContainer = document.createElement('div');
startContainer.className = 'vector-sticky-header-start';
stickyHeader.insertBefore(startContainer, stickyHeader.firstChild);
}
startContainer.insertBefore(menuBtn, startContainer.firstChild);
return true;
}
// Close menu when clicking outside
document.addEventListener('click', function(e) {
if (!isMenuOpen) return;
var menuBtn = document.getElementById('vanipedia-sticky-main-menu');
var dropdown = getDropdownElement();
if (
dropdown &&
menuBtn &&
!menuBtn.contains(e.target) &&
!dropdown.contains(e.target)
) {
closeMenu();
}
});
// Bootstrap initializer
if (!initStickyBurger()) {
var checkTimer = setInterval(function() {
if (initStickyBurger()) {
clearInterval(checkTimer);
}
}, 100);
setTimeout(function() {
clearInterval(checkTimer);
}, 4000);
}
mw.hook('wikipage.content').add(initStickyBurger);
$(initStickyBurger);
})();
// FLOATING "BACK TO TOP" BUTTON
(function() {
function initBackToTop() {
if (document.getElementById('vanipedia-back-to-top')) return;
var btn = document.createElement('button');
btn.id = 'vanipedia-back-to-top';
btn.title = 'Back to top';
btn.setAttribute('aria-label', 'Back to top');
btn.innerHTML =
'<svg xmlns="http://www.w3.org/2000/svg" ' +
'width="22" height="22" viewBox="0 0 24 24" ' +
'fill="none" stroke="currentColor" stroke-width="2.5" ' +
'stroke-linecap="round" stroke-linejoin="round">' +
'<polyline points="18 15 12 9 6 15"></polyline>' +
'</svg>';
btn.addEventListener('click', function(e) {
e.preventDefault();
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
function toggleVisibility() {
if (window.scrollY > 300) {
btn.classList.add('visible');
} else {
btn.classList.remove('visible');
}
}
window.addEventListener('scroll', toggleVisibility, { passive: true });
toggleVisibility();
document.body.appendChild(btn);
}
$(initBackToTop);
mw.hook('wikipage.content').add(initBackToTop);
})();