MediaWiki:Common.js: Difference between revisions
No edit summary Tag: Manual revert |
No edit summary Tag: Reverted |
||
| Line 1,242: | Line 1,242: | ||
/* ── Expose storeQueryForLink for readerToolbar to call ── */ | /* ── Expose storeQueryForLink for readerToolbar to call ── */ | ||
window.grStoreSearchHL = storeQueryForLink; | window.grStoreSearchHL = storeQueryForLink; | ||
}() ); | |||
/* ═══════════════════════════════════════════════════════════════ | |||
Mobile addon — paste at bottom of MediaWiki:Common.js | |||
Fixes for Minerva skin (mobile): | |||
1. Hide Minerva page toolbar (Page/Discussion tabs, icons bar) | |||
2. Hide Minerva header extras (keep only hamburger+logo+search) | |||
3. ReaderToolbar sticky below header | |||
4. Hamburger menu with Help/About/Logout | |||
5. Expand hidden sections | |||
6. Home page x-scroll fix | |||
═══════════════════════════════════════════════════════════════ */ | |||
( function () { | |||
if ( !document.body.classList.contains( 'skin-minerva' ) ) return; | |||
/* ── 1. Inject CSS (runs before JS, beats inline styles) ── */ | |||
function injectMinervaCSS() { | |||
if ( document.getElementById( 'gr-minerva-css' ) ) return; | |||
var s = document.createElement( 'style' ); | |||
s.id = 'gr-minerva-css'; | |||
s.textContent = [ | |||
/* Kill body padding — readerToolbar sets it, we override */ | |||
'body,#mw-mf-viewport,#mw-mf-page-center{padding-top:0!important;margin-top:0!important;}', | |||
/* Header orange + sticky */ | |||
'header.header-container{background:#b5451b!important;position:sticky!important;top:0!important;z-index:300!important;}', | |||
'.minerva-header{background:#b5451b!important;min-height:56px!important;display:flex!important;align-items:center!important;padding:0 12px!important;}', | |||
/* Hide Minerva header items we don't want */ | |||
/* Keep: .navigation-drawer (hamburger), .branding-box (logo+name) */ | |||
/* Hide: .search-toggle (search icon in header), language, notifications */ | |||
'.minerva-header .search-toggle{display:none!important;}', | |||
'.minerva-header .minerva-user-notifications{display:none!important;}', | |||
/* Site name white */ | |||
'.branding-box a{display:flex!important;align-items:center!important;text-decoration:none!important;flex-wrap:wrap!important;}', | |||
'.branding-box a span{color:#fff!important;font-size:17px!important;font-weight:700!important;font-family:system-ui,sans-serif!important;line-height:1.2!important;flex-shrink:1!important;}', | |||
'.branding-box a::before{content:"";display:inline-block;width:26px;height:26px;background:url("/favicon.png") center/contain no-repeat;margin-right:8px;flex-shrink:0;}', | |||
'.branding-box a::after{content:"A Digital Archive of Dvaita Vedanta Literature";display:block;flex-basis:100%;font-size:10px;color:rgba(255,255,255,0.82);font-family:sans-serif;width:100%;margin-top:1px;padding-left:34px;}', | |||
/* Hamburger icon white */ | |||
'.navigation-drawer .toggle-list__toggle,.minerva-header label[for="main-menu-input"]{color:#fff!important;}', | |||
'.minerva-header svg path,.minerva-header svg rect,.minerva-header svg circle{fill:#fff!important;}', | |||
/* Hide the page/discussion tabs bar */ | |||
'.page-actions-menu,.minerva-tabs,.minerva-page-actions,.post-content .page-actions,', | |||
'#page-secondary-actions,.last-modified-bar,.minerva-overflow-button,', | |||
'.toolbar,.page-actions,.mw-portlet-views,.minerva-anon-talk-link{display:none!important;}', | |||
/* Hide the icon bar (translate, watchlist, history, edit, more) */ | |||
'.page-actions-menu{display:none!important;}', | |||
'.minerva-user-links{display:none!important;}', | |||
/* Hide default Minerva drawer menu items */ | |||
'#mw-mf-main-menu > .menu{display:none!important;}', | |||
'.navigation-drawer .menu__item--watchlist,.navigation-drawer .menu__item--contributions,.navigation-drawer .menu__item--settings,.navigation-drawer .menu__item--random{display:none!important;}', | |||
'#gr-mob-extra-links{display:block!important;}', | |||
/* Hide About/Disclaimers footer in drawer */ | |||
'.navigation-drawer .footer,.navigation-drawer__footer{display:none!important;}', | |||
'.navigation-drawer .mw-portlet-footer,.minerva-drawer-footer{display:none!important;}', | |||
/* ReaderToolbar sticky below header */ | |||
'#gr-static-bar{position:sticky!important;top:56px!important;z-index:200!important;order:0!important;}', | |||
/* Expand sections — CSS backup for hidden attribute */ | |||
'[hidden="until-found"],[hidden]{', | |||
' content-visibility:visible!important;', | |||
'}', | |||
'.mf-section-0,.mf-section-1,.mf-section-2,.mf-section-3,.mf-section-4,', | |||
'.mf-section-5,.mf-section-6,.mf-section-7,.mf-section-8,.mf-section-9,', | |||
'.mf-section-10,.collapsible-block{display:block!important;visibility:visible!important;}', | |||
'.section-heading .indicator,.collapsible-heading .indicator{display:none!important;}', | |||
'.section-heading,.collapsible-heading{pointer-events:none!important;}', | |||
/* Home page — no x-scroll, single column cards */ | |||
'.gr-home,body,#mw-mf-page-center{overflow-x:hidden!important;max-width:100vw!important;}', | |||
'.gr-home-grid{flex-direction:column!important;flex-wrap:nowrap!important;gap:12px!important;width:100%!important;overflow-x:hidden!important;}', | |||
'.gr-home-card{width:100%!important;max-width:100%!important;min-width:unset!important;box-sizing:border-box!important;flex:none!important;}', | |||
/* Content font */ | |||
'.mw-parser-output{font-size:18px!important;line-height:1.8!important;}', | |||
'.mw-parser-output h2,.mw-parser-output .mw-heading2 h2{width:100%!important;}', | |||
'.mw-parser-output h3,.mw-parser-output .mw-heading3 h3{width:100%!important;}', | |||
].join(''); | |||
document.head.appendChild(s); | |||
} | |||
/* ── 2. Remove hidden attribute from sections ── */ | |||
function expandSections() { | |||
document.querySelectorAll( | |||
'[class*="mf-section-"], .collapsible-block' | |||
).forEach(function(el) { | |||
el.removeAttribute('hidden'); | |||
el.style.setProperty('display', 'block', 'important'); | |||
el.style.setProperty('visibility', 'visible', 'important'); | |||
el.removeAttribute('aria-hidden'); | |||
}); | |||
document.querySelectorAll('.section-heading, .collapsible-heading').forEach(function(el) { | |||
el.setAttribute('aria-expanded', 'true'); | |||
el.style.setProperty('pointer-events', 'none', 'important'); | |||
}); | |||
} | |||
/* Persistent observer — MF re-adds hidden after we remove it */ | |||
function watchAndExpand() { | |||
var timer = null; | |||
var obs = new MutationObserver(function(mutations) { | |||
var need = mutations.some(function(m) { | |||
return m.type === 'attributes' && | |||
(m.attributeName === 'hidden' || m.attributeName === 'aria-hidden'); | |||
}); | |||
if (need) { | |||
clearTimeout(timer); | |||
timer = setTimeout(expandSections, 30); | |||
} | |||
}); | |||
var root = document.querySelector('#mw-content-text, #mw-mf-page-center, body'); | |||
if (root) obs.observe(root, {subtree:true, attributes:true, attributeFilter:['hidden','aria-hidden','style']}); | |||
} | |||
/* ── 3. Body padding observer ── */ | |||
function watchBodyPadding() { | |||
var obs = new MutationObserver(function() { | |||
if (document.body.style.paddingTop && document.body.style.paddingTop !== '0px') { | |||
document.body.style.paddingTop = ''; | |||
} | |||
}); | |||
obs.observe(document.body, {attributes:true, attributeFilter:['style']}); | |||
} | |||
/* ── 4. Hide Minerva page toolbar elements via JS ── */ | |||
function hideMinervaChrome() { | |||
var selectors = [ | |||
/* Page/Discussion tabs */ | |||
'.minerva-tabs', '.page-actions-menu', '.page-actions', | |||
'.post-content > .page-actions', | |||
/* Icon toolbar (translate, watchlist, history, edit, more) */ | |||
'#page-secondary-actions', '.toolbar', | |||
/* Last modified bar */ | |||
'.last-modified-bar', | |||
/* Anon talk link */ | |||
'.minerva-anon-talk-link', | |||
/* User notifications in header */ | |||
'.minerva-user-notifications', | |||
/* Overflow menu */ | |||
'.minerva-overflow-button', | |||
/* Page info footer */ | |||
'.post-content .page-actions', | |||
]; | |||
selectors.forEach(function(sel) { | |||
document.querySelectorAll(sel).forEach(function(el) { | |||
el.style.setProperty('display', 'none', 'important'); | |||
}); | |||
}); | |||
} | |||
/* ── 5. Hamburger menu: hide default items, inject custom ones ── */ | |||
function setupHamburgerMenu() { | |||
var drawer = document.getElementById('mw-mf-main-menu'); | |||
if (!drawer) return; | |||
if (drawer.querySelector('#gr-mob-extra-links')) return; | |||
/* Hide ALL default Minerva menu items */ | |||
drawer.querySelectorAll('ul, .menu, li').forEach(function(el) { | |||
el.style.setProperty('display', 'none', 'important'); | |||
}); | |||
/* Also hide the footer links (About/Disclaimers) */ | |||
var footer = drawer.querySelector('.footer, .navigation-drawer__footer, .mw-portlet-footer'); | |||
if (footer) footer.style.setProperty('display', 'none', 'important'); | |||
/* Build our custom menu */ | |||
var nav = document.createElement('div'); | |||
nav.id = 'gr-mob-extra-links'; | |||
nav.style.cssText = 'width:100%;'; | |||
var linkStyle = 'display:flex;align-items:center;gap:14px;padding:14px 20px;font-size:16px;color:#2c1810;text-decoration:none;font-family:system-ui,sans-serif;border-bottom:1px solid #f5f0ed;background:#fff;'; | |||
function menuItem(href, label, emoji) { | |||
var a = document.createElement('a'); | |||
a.href = href; | |||
a.style.cssText = linkStyle; | |||
a.innerHTML = '<span style="font-size:18px;width:24px;text-align:center;flex-shrink:0;">' + emoji + '</span><span>' + label + '</span>'; | |||
a.addEventListener('click', function() { | |||
var cb = document.getElementById('main-menu-input'); | |||
if (cb) cb.checked = false; | |||
}); | |||
return a; | |||
} | |||
/* Home */ | |||
nav.appendChild(menuItem('/', 'Home', '🏠')); | |||
/* Help */ | |||
nav.appendChild(menuItem('/Help:Contents', 'Help', '❓')); | |||
/* About */ | |||
nav.appendChild(menuItem('/My_wiki:About', 'About', 'ℹ️')); | |||
/* Logout / Login */ | |||
var userName = window.mw ? mw.config.get('wgUserName') : null; | |||
if (userName) { | |||
var logoutAnchor = document.querySelector('a[href*="action=logout"]'); | |||
var logoutHref = logoutAnchor ? logoutAnchor.href : '/index.php?title=Special:UserLogout'; | |||
nav.appendChild(menuItem(logoutHref, 'Log out', '↩️')); | |||
} else { | |||
nav.appendChild(menuItem('/index.php?title=Special:UserLogin', 'Log in', '→')); | |||
} | |||
drawer.appendChild(nav); | |||
} | |||
/* ── 6. Mobile TOC overlay (Contents button) ── */ | |||
var _tocInit = false; | |||
function initMobileToc() { | |||
if (_tocInit) return; | |||
var tocList = document.querySelector('.vector-toc-contents, .vector-toc .vector-toc-list'); | |||
if (!tocList) return; | |||
_tocInit = true; | |||
var bd = document.createElement('div'); | |||
bd.className = 'gr-mob-toc-backdrop'; | |||
document.body.appendChild(bd); | |||
var panel = document.createElement('div'); | |||
panel.className = 'gr-mob-toc-panel'; | |||
var hdr = document.createElement('div'); | |||
hdr.className = 'gr-mob-toc-header'; | |||
var ttl = document.createElement('div'); | |||
ttl.className = 'gr-mob-toc-title'; | |||
ttl.textContent = 'विषयसूची'; | |||
var cls = document.createElement('button'); | |||
cls.className = 'gr-mob-toc-close'; | |||
cls.textContent = '✕'; | |||
hdr.appendChild(ttl); hdr.appendChild(cls); | |||
panel.appendChild(hdr); | |||
var body = document.createElement('div'); | |||
body.className = 'gr-mob-toc-body'; | |||
body.appendChild(tocList.cloneNode(true)); | |||
panel.appendChild(body); | |||
document.body.appendChild(panel); | |||
/* TOC button — only on pages with headings */ | |||
var hasItems = tocList.querySelector('li,a'); | |||
var btn = document.createElement('button'); | |||
btn.className = 'gr-mob-toc-btn'; | |||
btn.id = 'gr-mob-toc-btn'; | |||
btn.innerHTML = '☰ Contents'; | |||
if (!hasItems) btn.style.display = 'none'; | |||
document.body.appendChild(btn); | |||
function open() { panel.classList.add('open'); bd.classList.add('open'); document.body.style.overflow='hidden'; } | |||
function close() { panel.classList.remove('open'); bd.classList.remove('open'); document.body.style.overflow=''; } | |||
btn.addEventListener('click', open); | |||
cls.addEventListener('click', close); | |||
bd.addEventListener('click', close); | |||
body.querySelectorAll('a').forEach(function(a){ a.addEventListener('click', close); }); | |||
} | |||
/* ── Boot ── */ | |||
injectMinervaCSS(); | |||
watchBodyPadding(); | |||
function onReady() { | |||
expandSections(); | |||
watchAndExpand(); | |||
hideMinervaChrome(); | |||
/* Retry expand multiple times to fight MF */ | |||
[100, 300, 700, 1500].forEach(function(ms) { | |||
setTimeout(expandSections, ms); | |||
}); | |||
/* Setup hamburger with delay for Minerva drawer to render */ | |||
setTimeout(setupHamburgerMenu, 800); | |||
setTimeout(initMobileToc, 600); | |||
} | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', onReady); | |||
} else { | |||
onReady(); | |||
} | |||
if (window.mw) { | |||
mw.hook('wikipage.content').add(function() { | |||
setTimeout(function() { | |||
expandSections(); | |||
hideMinervaChrome(); | |||
setupHamburgerMenu(); | |||
initMobileToc(); | |||
}, 200); | |||
}); | |||
} | |||
}() ); | }() ); | ||