MediaWiki:Common.js
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.
// Script to ensure the sidebar remains always visible
// Add this script to MediaWiki:Common.js or include in HTML
(function() {
'use strict';
// Function to force sidebar visibility
function forceSidebarVisibility() {
const sidebar = document.getElementById('mw-panel');
if (sidebar) {
sidebar.style.display = 'block';
sidebar.style.visibility = 'visible';
sidebar.style.opacity = '1';
sidebar.style.position = 'fixed';
sidebar.style.left = '0';
sidebar.style.top = '0';
sidebar.style.width = '180px';
sidebar.style.height = '100vh';
sidebar.style.zIndex = '100';
}
}
// Function to force back-to-top button visibility and functionality
function forceBackToTopButton() {
const backToTopBtn = document.getElementById('back-to-top-btn');
if (backToTopBtn) {
// Force visibility styles
backToTopBtn.style.position = 'fixed';
backToTopBtn.style.bottom = '20px';
backToTopBtn.style.right = '20px';
backToTopBtn.style.zIndex = '99999';
backToTopBtn.style.display = 'block';
backToTopBtn.style.visibility = 'visible';
backToTopBtn.style.opacity = '1';
backToTopBtn.style.pointerEvents = 'auto';
// Ensure the link inside is also visible
const link = backToTopBtn.querySelector('a');
if (link) {
link.style.display = 'inline-block';
link.style.visibility = 'visible';
link.style.opacity = '1';
link.style.pointerEvents = 'auto';
// Add click event if not already present
if (!link.hasAttribute('data-click-added')) {
link.addEventListener('click', function(e) {
e.preventDefault();
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
link.setAttribute('data-click-added', 'true');
}
}
}
}
// Execute when DOM is loaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
forceSidebarVisibility();
forceBackToTopButton();
});
} else {
forceSidebarVisibility();
forceBackToTopButton();
}
// Execute when page is completely loaded
window.addEventListener('load', function() {
forceSidebarVisibility();
forceBackToTopButton();
});
// Observe DOM changes to react to dynamic modifications
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' && mutation.target.id === 'mw-panel') {
forceSidebarVisibility();
}
if (mutation.type === 'attributes' && mutation.target.id === 'back-to-top-btn') {
forceBackToTopButton();
}
});
});
// Start observation when element exists
function startObserving() {
const sidebar = document.getElementById('mw-panel');
if (sidebar) {
observer.observe(sidebar, {
attributes: true,
attributeFilter: ['style', 'class']
});
} else {
// Try again after a small delay
setTimeout(startObserving, 100);
}
const backToTopBtn = document.getElementById('back-to-top-btn');
if (backToTopBtn) {
observer.observe(backToTopBtn, {
attributes: true,
attributeFilter: ['style', 'class']
});
}
}
startObserving();
// Execute functions periodically as backup
setInterval(function() {
forceSidebarVisibility();
forceBackToTopButton();
}, 1000);
// Execute when window is resized
window.addEventListener('resize', function() {
forceSidebarVisibility();
forceBackToTopButton();
});
// Execute when page visibility changes
document.addEventListener('visibilitychange', function() {
if (!document.hidden) {
forceSidebarVisibility();
forceBackToTopButton();
}
});
// Execute when page is scrolled (for back-to-top button)
window.addEventListener('scroll', forceBackToTopButton);
// Execute after MediaWiki scripts load
if (typeof mw !== 'undefined' && mw.loader) {
mw.loader.using(['mediawiki.util'], function() {
forceSidebarVisibility();
forceBackToTopButton();
});
}
})();
/* ========================================
CARDS NAVIGATION SCRIPT
Makes highlight cards clickable
======================================== */
(function() {
'use strict';
// Function to make cards clickable
function makeCardsClickable() {
// Select all highlight cards
const cards = document.querySelectorAll('.destaque-card[data-link]');
cards.forEach(function(card) {
// Add pointer cursor
card.style.cursor = 'pointer';
// Add click event
card.addEventListener('click', function() {
const linkTarget = this.getAttribute('data-link');
if (linkTarget) {
// Check if it's an anchor link (starts with #)
if (linkTarget.startsWith('#')) {
// Navigate to section within the same page
const targetElement = document.querySelector(linkTarget);
if (targetElement) {
targetElement.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
} else {
// Fallback: use window.location.hash
window.location.hash = linkTarget;
}
} else {
// Build MediaWiki page URL for external links
const pageUrl = linkTarget.replace(/\s+/g, '_');
// Navigate to page
if (typeof mw !== 'undefined' && mw.config) {
// In MediaWiki - use MediaWiki API
const baseUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath');
window.location.href = baseUrl + '/index.php/' + encodeURIComponent(pageUrl);
} else {
// Fallback - assume standard MediaWiki structure
window.location.href = '/wiki/' + encodeURIComponent(pageUrl);
}
}
}
});
// Add visual hover effect
card.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-8px)';
this.style.boxShadow = '0 12px 40px rgba(255, 107, 157, 0.3)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
this.style.boxShadow = '0 8px 32px rgba(255, 107, 157, 0.2)';
});
});
console.log('Highlight cards made clickable:', cards.length + ' cards processed');
}
// Function to initialize when DOM is ready
function initializeCards() {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', makeCardsClickable);
} else {
makeCardsClickable();
}
}
// Observe DOM changes for dynamically added cards
function observeChanges() {
if (typeof MutationObserver !== 'undefined') {
const observer = new MutationObserver(function(mutations) {
let shouldReinitialize = false;
mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
// Check if new cards were added
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) { // Element node
if (node.classList && node.classList.contains('destaque-card') ||
node.querySelector && node.querySelector('.destaque-card')) {
shouldReinitialize = true;
}
}
});
}
});
if (shouldReinitialize) {
setTimeout(makeCardsClickable, 100);
}
});
// Observe changes in body
observer.observe(document.body, {
childList: true,
subtree: true
});
}
}
// Initialize the script
initializeCards();
// Start observing changes
observeChanges();
// Reinitialize after complete page load
window.addEventListener('load', function() {
setTimeout(makeCardsClickable, 500);
});
// Export function for manual use if needed
window.initializeHighlightCards = makeCardsClickable;
})();
/* ========================================
RESPONSIVE TABS MENU SCRIPT
Provides compact mobile-friendly navigation for MediaWiki tabs
======================================== */
(function() {
'use strict';
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initResponsiveTabs);
} else {
initResponsiveTabs();
}
function initResponsiveTabs() {
// Create toggle buttons for each tab container
createToggleButtons();
// Handle window resize
window.addEventListener('resize', handleResize);
// Initial setup
handleResize();
}
function createToggleButtons() {
const tabContainers = [
{ selector: '#p-namespaces ul', label: 'Namespaces ▼', id: 'namespace-dropdown' },
{ selector: '#p-views ul', label: 'Views ▼', id: 'views-dropdown' },
{ selector: '#p-cactions ul', label: 'Actions ▼', id: 'actions-dropdown' },
{ selector: '#p-personal ul', label: 'Personal ▼', id: 'personal-dropdown' }
];
tabContainers.forEach(container => {
const element = document.querySelector(container.selector);
if (element && !element.previousElementSibling?.classList.contains('mw-tabs-toggle')) {
createToggleButton(element, container.label, container.id);
}
});
}
function createToggleButton(tabContainer, label, id) {
const toggle = document.createElement('button');
toggle.className = 'mw-tabs-toggle';
toggle.textContent = label;
toggle.setAttribute('aria-expanded', 'false');
toggle.setAttribute('aria-controls', id || 'tabs-menu');
toggle.setAttribute('data-target', id);
// Insert toggle before the tab container
tabContainer.parentNode.insertBefore(toggle, tabContainer);
// Add click event listener
toggle.addEventListener('click', function(e) {
e.preventDefault();
toggleMenu(toggle, tabContainer);
});
// Close menu when clicking outside
document.addEventListener('click', function(e) {
if (!toggle.contains(e.target) && !tabContainer.contains(e.target)) {
closeMenu(toggle, tabContainer);
}
});
}
function toggleMenu(toggle, tabContainer) {
const isOpen = tabContainer.classList.contains('show');
if (isOpen) {
closeMenu(toggle, tabContainer);
} else {
openMenu(toggle, tabContainer);
}
}
function openMenu(toggle, tabContainer) {
// Close other open menus first
document.querySelectorAll('#p-namespaces ul.show, #p-views ul.show, #p-cactions ul.show, #p-personal ul.show')
.forEach(menu => {
if (menu !== tabContainer) {
menu.classList.remove('show');
const relatedToggle = menu.previousElementSibling;
if (relatedToggle && relatedToggle.classList.contains('mw-tabs-toggle')) {
relatedToggle.setAttribute('aria-expanded', 'false');
const originalText = relatedToggle.textContent.replace(' ▲', ' ▼');
relatedToggle.textContent = originalText;
}
}
});
tabContainer.classList.add('show');
toggle.setAttribute('aria-expanded', 'true');
const newText = toggle.textContent.replace(' ▼', ' ▲');
toggle.textContent = newText;
}
function closeMenu(toggle, tabContainer) {
tabContainer.classList.remove('show');
toggle.setAttribute('aria-expanded', 'false');
const originalText = toggle.textContent.replace(' ▲', ' ▼');
toggle.textContent = originalText;
}
function handleResize() {
const isSmallScreen = window.innerWidth <= 1366;
// Show/hide toggle buttons based on screen size
document.querySelectorAll('.mw-tabs-toggle').forEach(toggle => {
toggle.style.display = isSmallScreen ? 'inline-block' : 'none';
});
// Reset menu state on larger screens
if (!isSmallScreen) {
document.querySelectorAll('#p-namespaces ul, #p-views ul, #p-cactions ul, #p-personal ul').forEach(menu => {
menu.classList.remove('show');
menu.style.display = '';
});
document.querySelectorAll('.mw-tabs-toggle').forEach(toggle => {
toggle.setAttribute('aria-expanded', 'false');
const originalText = toggle.textContent.replace(' ▲', ' ▼');
toggle.textContent = originalText;
});
}
}
// Handle dropdown menus for overflow tabs
function initDropdownMenus() {
const dropdowns = document.querySelectorAll('.mw-tabs-dropdown');
dropdowns.forEach(dropdown => {
const trigger = dropdown.querySelector('.mw-tabs-dropdown-trigger');
if (trigger) {
trigger.addEventListener('click', function(e) {
e.preventDefault();
dropdown.classList.toggle('active');
});
}
});
// Close dropdowns when clicking outside
document.addEventListener('click', function(e) {
dropdowns.forEach(dropdown => {
if (!dropdown.contains(e.target)) {
dropdown.classList.remove('active');
}
});
});
}
// Initialize dropdown functionality
initDropdownMenus();
// Add keyboard navigation support
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
// Close all open menus on Escape
document.querySelectorAll('#p-namespaces ul.show, #p-views ul.show, #p-cactions ul.show, #p-personal ul.show').forEach(menu => {
menu.classList.remove('show');
const toggle = menu.previousElementSibling;
if (toggle && toggle.classList.contains('mw-tabs-toggle')) {
toggle.setAttribute('aria-expanded', 'false');
const originalText = toggle.textContent.replace(' ▲', ' ▼');
toggle.textContent = originalText;
}
});
// Close dropdowns
document.querySelectorAll('.mw-tabs-dropdown.active').forEach(dropdown => {
dropdown.classList.remove('active');
});
}
});
})();