MediaWiki:Common.js: Difference between revisions
Appearance
No edit summary |
No edit summary |
||
| Line 41: | Line 41: | ||
obs.observe(document.documentElement, { childList: true, subtree: true }); | obs.observe(document.documentElement, { childList: true, subtree: true }); | ||
})(); | })(); | ||
// | // DOOM ARCHIVES header (Vector 2022): robust, survives re-renders | ||
(function () { | (function () { | ||
const HEADER_CLASS = 'doom-archives-header'; | const HEADER_CLASS = 'doom-archives-header'; | ||
function | function styleHeader(header) { | ||
// | // Inline styles (no dependency on Common.css) | ||
header.style.display = 'block'; | |||
header.style.width = '100%'; | |||
header.style.boxSizing = 'border-box'; | |||
header.style.margin = '10px 0 10px'; | |||
header.style.padding = '12px 14px'; | |||
header.style.background = 'rgba(0,0,0,0.75)'; | |||
header.style.border = '1px solid #3a0000'; | |||
header.style.borderRadius = '12px'; | |||
header.style.boxShadow = 'inset 0 0 20px rgba(180,0,0,0.30), 0 0 8px rgba(0,0,0,0.8)'; | |||
header.style.color = '#b30000'; | |||
header.style.fontWeight = '900'; | |||
header.style.letterSpacing = '0.14em'; | |||
header.style.textTransform = 'uppercase'; | |||
header.style.textAlign = 'center'; | |||
} | } | ||
function | function findMenuContentContainer() { | ||
const | // Prefer Vector 2022 pinned container | ||
if ( | const pinned = | ||
document.querySelector('#vector-main-menu-pinned-container nav.vector-main-menu .vector-menu-content') || | |||
document.querySelector('#vector-main-menu-pinned-container .vector-menu-content'); | |||
if (pinned) return pinned; | |||
// | // Non-pinned Vector 2022 menu (some states) | ||
if ( | const main = | ||
document.querySelector('nav.vector-main-menu .vector-menu-content') || | |||
document.querySelector('#vector-main-menu .vector-menu-content'); | |||
if (main) return main; | |||
// Logged-out dropdown menu content (hamburger) | |||
const dropdown = | |||
document.querySelector('#vector-main-menu-dropdown .vector-menu-content') || | |||
document.querySelector('#vector-main-menu-dropdown .vector-dropdown-content'); | |||
if (dropdown) return dropdown; | |||
// Legacy fallback | |||
const legacy = document.querySelector('#mw-panel .vector-menu-content'); | |||
if (legacy) return legacy; | |||
return null; | |||
} | |||
function ensureHeader() { | |||
const container = findMenuContentContainer(); | |||
if (!container) return; | |||
// If already exists, just ensure it’s styled & visible | |||
let existing = container.querySelector('.' + HEADER_CLASS); | |||
if (existing) { | |||
existing.style.display = 'block'; | |||
styleHeader(existing); | |||
return; | |||
} | |||
const header = document.createElement('div'); | const header = document.createElement('div'); | ||
header.className = HEADER_CLASS; | header.className = HEADER_CLASS; | ||
header.textContent = 'DOOM ARCHIVES'; | header.textContent = 'DOOM ARCHIVES'; | ||
styleHeader(header); | |||
container.insertBefore(header, container.firstChild); | |||
} | } | ||
// | function start() { | ||
ensureHeader(); | |||
// Re-run a few times during init (Vector can rebuild the menu) | |||
setTimeout(ensureHeader, 150); | |||
setTimeout(ensureHeader, 600); | |||
setTimeout(ensureHeader, 1200); | |||
// Keep it enforced if DOM changes | |||
const obs = new MutationObserver(() => ensureHeader()); | |||
obs.observe(document.documentElement, { childList: true, subtree: true }); | |||
} | |||
// Wait until Vector signals it’s ready (when possible) | |||
if (document.documentElement.classList.contains('vector-animations-ready')) { | |||
start(); | |||
} else { | |||
const readyObs = new MutationObserver(() => { | |||
if (document.documentElement.classList.contains('vector-animations-ready')) { | |||
readyObs.disconnect(); | |||
start(); | |||
} | |||
}); | |||
readyObs.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] }); | |||
// Also start on load as a fallback | |||
window.addEventListener('load', start); | |||
} | |||
})(); | })(); | ||
document.body.insertAdjacentHTML( | |||
'afterbegin', | |||
'<div style="position:fixed;top:0;left:0;right:0;z-index:999999;background:#b30000;color:#000;padding:8px 12px;font-weight:900;letter-spacing:.12em;text-transform:uppercase;text-align:center;">COMMON.JS LOADED</div>' | |||
); | |||
Revision as of 16:24, 24 December 2025
/* Any JavaScript here will be loaded for all users on every page load. */
// Vector 2022: pin main menu for logged-out users on desktop
if (!mw.config.get('wgUserName') && window.matchMedia('(min-width: 1120px)').matches) {
const observer = new MutationObserver((_, obs) => {
if (document.documentElement.classList.contains('vector-animations-ready')) {
const pin = document.querySelector('[data-event-name="pinnable-header.vector-main-menu.pin"]');
if (pin) pin.click();
obs.disconnect();
}
});
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
}
// Remove "Main menu" headings/labels injected by Vector/Vector 2022 (works across variants)
(function () {
function killMainMenuText(root = document) {
// Look for common heading/label elements
const candidates = root.querySelectorAll(
'#vector-main-menu, #vector-main-menu-pinned-container, #mw-panel, nav.vector-main-menu, #vector-main-menu-dropdown'
);
candidates.forEach(container => {
// Remove elements whose visible text is exactly "Main menu"
container.querySelectorAll('*').forEach(el => {
const txt = (el.textContent || '').trim();
if (txt === 'Main menu') {
el.style.display = 'none';
}
// Also catch the longer hint text variants
if (txt.toLowerCase().includes('main menu has moved here')) {
el.style.display = 'none';
}
});
});
}
// Run now, on load, and after Vector finishes UI init
killMainMenuText();
window.addEventListener('load', () => killMainMenuText());
const obs = new MutationObserver(() => killMainMenuText());
obs.observe(document.documentElement, { childList: true, subtree: true });
})();
// DOOM ARCHIVES header (Vector 2022): robust, survives re-renders
(function () {
const HEADER_CLASS = 'doom-archives-header';
function styleHeader(header) {
// Inline styles (no dependency on Common.css)
header.style.display = 'block';
header.style.width = '100%';
header.style.boxSizing = 'border-box';
header.style.margin = '10px 0 10px';
header.style.padding = '12px 14px';
header.style.background = 'rgba(0,0,0,0.75)';
header.style.border = '1px solid #3a0000';
header.style.borderRadius = '12px';
header.style.boxShadow = 'inset 0 0 20px rgba(180,0,0,0.30), 0 0 8px rgba(0,0,0,0.8)';
header.style.color = '#b30000';
header.style.fontWeight = '900';
header.style.letterSpacing = '0.14em';
header.style.textTransform = 'uppercase';
header.style.textAlign = 'center';
}
function findMenuContentContainer() {
// Prefer Vector 2022 pinned container
const pinned =
document.querySelector('#vector-main-menu-pinned-container nav.vector-main-menu .vector-menu-content') ||
document.querySelector('#vector-main-menu-pinned-container .vector-menu-content');
if (pinned) return pinned;
// Non-pinned Vector 2022 menu (some states)
const main =
document.querySelector('nav.vector-main-menu .vector-menu-content') ||
document.querySelector('#vector-main-menu .vector-menu-content');
if (main) return main;
// Logged-out dropdown menu content (hamburger)
const dropdown =
document.querySelector('#vector-main-menu-dropdown .vector-menu-content') ||
document.querySelector('#vector-main-menu-dropdown .vector-dropdown-content');
if (dropdown) return dropdown;
// Legacy fallback
const legacy = document.querySelector('#mw-panel .vector-menu-content');
if (legacy) return legacy;
return null;
}
function ensureHeader() {
const container = findMenuContentContainer();
if (!container) return;
// If already exists, just ensure it’s styled & visible
let existing = container.querySelector('.' + HEADER_CLASS);
if (existing) {
existing.style.display = 'block';
styleHeader(existing);
return;
}
const header = document.createElement('div');
header.className = HEADER_CLASS;
header.textContent = 'DOOM ARCHIVES';
styleHeader(header);
container.insertBefore(header, container.firstChild);
}
function start() {
ensureHeader();
// Re-run a few times during init (Vector can rebuild the menu)
setTimeout(ensureHeader, 150);
setTimeout(ensureHeader, 600);
setTimeout(ensureHeader, 1200);
// Keep it enforced if DOM changes
const obs = new MutationObserver(() => ensureHeader());
obs.observe(document.documentElement, { childList: true, subtree: true });
}
// Wait until Vector signals it’s ready (when possible)
if (document.documentElement.classList.contains('vector-animations-ready')) {
start();
} else {
const readyObs = new MutationObserver(() => {
if (document.documentElement.classList.contains('vector-animations-ready')) {
readyObs.disconnect();
start();
}
});
readyObs.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
// Also start on load as a fallback
window.addEventListener('load', start);
}
})();
document.body.insertAdjacentHTML(
'afterbegin',
'<div style="position:fixed;top:0;left:0;right:0;z-index:999999;background:#b30000;color:#000;padding:8px 12px;font-weight:900;letter-spacing:.12em;text-transform:uppercase;text-align:center;">COMMON.JS LOADED</div>'
);