MediaWiki:Common.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 91: | Line 91: | ||
'क':'க','ख':'க','ग':'க','घ':'க','ङ':'ங', | 'क':'க','ख':'க','ग':'க','घ':'க','ङ':'ங', | ||
'च':'ச','छ':'ச','ज':'ஜ','झ':'ஜ','ञ':'ஞ', | 'च':'ச','छ':'ச','ज':'ஜ','झ':'ஜ','ञ':'ஞ', | ||
'ट':'ட','ठ':'ட','ड':'ட','ढ':'ட',' | 'ट':'ட','ठ':'ட','ड':'ட','ढ':'ட','ण':'ண', | ||
'त':'த','थ':'த','द':'த','ध':'த','न':'ந', | 'त':'த','थ':'த','द':'த','ध':'த','न':'ந', | ||
'प':'ப','फ':'ப','ब':'ப','भ':'ப','म':'ம', | 'प':'ப','फ':'ப','ब':'ப','भ':'ப','म':'ம', | ||
'य':'ய','र':'ர',' | 'य':'ய','र':'ர','ल':'ல','ळ':'ழ','व':'வ', | ||
'श':'ஶ','ष':'ஷ','स':'ஸ','ह':'ஹ', | 'श':'ஶ','ष':'ஷ','स':'ஸ','ह':'ஹ', | ||
'ा':'ா','ि':'ி','ी':'ீ',' | 'ा':'ா','ि':'ி','ी':'ீ','ु':'ு','ू':'ூ', | ||
'ृ':'ு','ॄ':'ூ', | 'ृ':'ு','ॄ':'ூ', | ||
'े':'ே',' | 'े':'ே','ै':'ை','ो':'ோ','ौ':'ௌ', | ||
'ं':'ம்','ः':':','ँ':'ம்','्':'்','ॐ':'ௐ','ऽ':'ௗ', | 'ं':'ம்','ः':':','ँ':'ம்','्':'்','ॐ':'ௐ','ऽ':'ௗ', | ||
'०':'0','१':'1','२':'2','३':'3','४':'4', | '०':'0','१':'1','२':'2','३':'3','४':'4', | ||
| Line 139: | Line 139: | ||
if ( p.closest( '.gr-controls' ) ) return; | if ( p.closest( '.gr-controls' ) ) return; | ||
if ( p.closest( '.mw-editsection' ) ) return; | if ( p.closest( '.mw-editsection' ) ) return; | ||
} | } | ||
var orig = node.textContent; | var orig = node.textContent; | ||
| Line 194: | Line 193: | ||
var LABEL = 'विषयसूची'; | var LABEL = 'विषयसूची'; | ||
var span = titleEl.querySelector('.gr-toc-title'); | var span = titleEl.querySelector('.gr-toc-title'); | ||
| Line 205: | Line 203: | ||
titleEl.appendChild(span); | titleEl.appendChild(span); | ||
translatableSpans.push(span); | translatableSpans.push(span); | ||
} | } | ||
| Line 218: | Line 216: | ||
var toc = document.querySelector( '.vector-toc' ); | var toc = document.querySelector( '.vector-toc' ); | ||
if ( !toc ) return; | if ( !toc ) return; | ||
var el = toc.querySelector( '#vector-toc-beginning' ); | var el = toc.querySelector( '#vector-toc-beginning' ); | ||
if ( !el ) { | if ( !el ) { | ||
var items = toc.querySelectorAll( '.vector-toc-list-item' ); | var items = toc.querySelectorAll( '.vector-toc-list-item' ); | ||
for ( var i = 0; i < items.length; i++ ) { | for ( var i = 0; i < items.length; i++ ) { | ||
| Line 288: | Line 284: | ||
nav.setAttribute( 'class', 'toc-main-links'); | nav.setAttribute( 'class', 'toc-main-links'); | ||
function makeBtn( href, label ) { | function makeBtn( href, label ) { | ||
var a = document.createElement( 'a' ); | var a = document.createElement( 'a' ); | ||
| Line 448: | Line 442: | ||
// ── TOC: Use Vector's native TOC, add highlight + expand + rename ────── | // ── TOC: Use Vector's native TOC, add highlight + expand + rename ────── | ||
function setupToc() { | function setupToc() { | ||
if ( _isNoTocPage() ) return; | if ( _isNoTocPage() ) return; | ||
| Line 469: | Line 455: | ||
// ── IntersectionObserver on actual heading elements ────────────── | // ── IntersectionObserver on actual heading elements ────────────── | ||
var _headingObserver = null; | var _headingObserver = null; | ||
function attachHeadingObserver() { | function attachHeadingObserver() { | ||
if ( _isNoTocPage() ) return; | if ( _isNoTocPage() ) return; | ||
if ( _headingObserver ) return; | if ( _headingObserver ) return; | ||
if ( !window.IntersectionObserver ) { | if ( !window.IntersectionObserver ) { | ||
return; /* IntersectionObserver not available — skip active highlight */ | |||
} | } | ||
| Line 484: | Line 467: | ||
var _activeId = null; | var _activeId = null; | ||
var content = document.querySelector( '.mw-parser-output' ); | var content = document.querySelector( '.mw-parser-output' ); | ||
if ( !content ) return; | if ( !content ) return; | ||
| Line 496: | Line 478: | ||
function getTocLink( id ) { | function getTocLink( id ) { | ||
return toc.querySelector( 'a[href="#' + CSS.escape( id ) + '"]' ); | return toc.querySelector( 'a[href="#' + CSS.escape( id ) + '"]' ); | ||
} | } | ||
| Line 506: | Line 487: | ||
function clearActive() { | function clearActive() { | ||
toc.querySelectorAll( '.vector-toc-list-item | /* Clear ALL toc items — prevents multiple items staying highlighted simultaneously */ | ||
toc.querySelectorAll( '.vector-toc-list-item' ).forEach( function ( li ) { | |||
li.classList.remove( 'vector-toc-list-item-active' ); | li.classList.remove( 'vector-toc-list-item-active' ); | ||
var lnk = li.querySelector( '.vector-toc-link' ); | var lnk = li.querySelector( '.vector-toc-link' ); | ||
| Line 530: | Line 512: | ||
li.classList.add( 'vector-toc-list-item-active' ); | li.classList.add( 'vector-toc-list-item-active' ); | ||
var hasActiveChild = !!li.querySelector( | var hasActiveChild = !!li.querySelector( | ||
'.vector-toc-list-item .vector-toc-list-item-active' | '.vector-toc-list-item .vector-toc-list-item-active' | ||
| Line 546: | Line 527: | ||
} | } | ||
// Expand collapsed | // Expand ALL ancestor sections — remove collapsed, force display | ||
var anc = li.parentNode; | var anc = li.parentNode; | ||
while ( anc && anc !== toc ) { | while ( anc && anc !== toc ) { | ||
if ( anc.classList | if ( anc.classList ) { | ||
anc.classList.remove( 'vector-toc-list-item-collapsed' ); | anc.classList.remove( 'vector-toc-list-item-collapsed' ); | ||
} | |||
if ( anc.tagName === 'UL' || anc.tagName === 'LI' ) { | |||
anc.style.removeProperty( 'display' ); | |||
} | } | ||
anc = anc.parentNode; | anc = anc.parentNode; | ||
| Line 567: | Line 551: | ||
} | } | ||
var _visible = new Set(); | var _visible = new Set(); | ||
| Line 579: | Line 562: | ||
} ); | } ); | ||
var topId = null; | var topId = null; | ||
var topY = Infinity; | var topY = Infinity; | ||
| Line 590: | Line 572: | ||
} ); | } ); | ||
if ( !topId ) { | if ( !topId ) { | ||
var bestY = -Infinity; | var bestY = -Infinity; | ||
| Line 601: | Line 582: | ||
setActive( topId || null ); | setActive( topId || null ); | ||
}, { | }, { | ||
rootMargin: '-60px 0px -65% 0px', | rootMargin: '-60px 0px -65% 0px', | ||
threshold: 0 | threshold: 0 | ||
| Line 677: | Line 657: | ||
else { currentScript = 'deva'; } | else { currentScript = 'deva'; } | ||
setTimeout( setupToc, 200 ); | setTimeout( setupToc, 200 ); | ||
} | } | ||
| Line 689: | Line 667: | ||
// ── React to gr-new-content (siteNav panel rendered new items) ── | // ── React to gr-new-content (siteNav panel rendered new items) ── | ||
window.addEventListener( 'gr-new-content', function ( e ) { | window.addEventListener( 'gr-new-content', function ( e ) { | ||
var container = e && e.detail && e.detail.container; | var container = e && e.detail && e.detail.container; | ||
| Line 859: | Line 836: | ||
if ( !needle || needle.length < 4 ) return; | if ( !needle || needle.length < 4 ) return; | ||
function doHighlight() { | function doHighlight() { | ||
var content = document.querySelector( '.mw-parser-output' ); | var content = document.querySelector( '.mw-parser-output' ); | ||
| Line 868: | Line 843: | ||
var found = false; | var found = false; | ||
var spans = content.querySelectorAll( '[data-deva]' ); | var spans = content.querySelectorAll( '[data-deva]' ); | ||
for ( var i = 0; i < spans.length && !found; i++ ) { | for ( var i = 0; i < spans.length && !found; i++ ) { | ||
| Line 875: | Line 849: | ||
if ( orig.indexOf( snippet ) === -1 ) continue; | if ( orig.indexOf( snippet ) === -1 ) continue; | ||
var idx = orig.indexOf( snippet ); | var idx = orig.indexOf( snippet ); | ||
var hlText = orig.slice( idx, Math.min( idx + needle.length, orig.length ) ); | var hlText = orig.slice( idx, Math.min( idx + needle.length, orig.length ) ); | ||
| Line 899: | Line 872: | ||
} | } | ||
if ( !found ) { | if ( !found ) { | ||
var walker = document.createTreeWalker( content, NodeFilter.SHOW_TEXT ); | var walker = document.createTreeWalker( content, NodeFilter.SHOW_TEXT ); | ||
| Line 924: | Line 896: | ||
} | } | ||
doHighlight(); | |||
} | } | ||
| Line 951: | Line 922: | ||
wireUllekhaLinks(); | wireUllekhaLinks(); | ||
} | } | ||
}() );/* ── Search result highlight ──────────────────────────────────── */ | |||
( function () { | |||
function storeQueryForLink( url, query ) { | |||
try { | |||
var a = document.createElement( 'a' ); | |||
a.href = url; | |||
sessionStorage.setItem( 'gr_search_hl', JSON.stringify({ | |||
query: query, | |||
pathname: a.pathname | |||
}) ); | |||
} catch(e) {} | |||
} | |||
function applyHighlight() { | |||
var stored; | |||
try { | |||
stored = JSON.parse( sessionStorage.getItem( 'gr_search_hl' ) || 'null' ); | |||
} catch(e) { return; } | |||
if ( !stored || !stored.query ) return; | |||
var currentPath = window.location.pathname; | |||
var storedPath = stored.pathname || ''; | |||
function normPath(p) { return decodeURIComponent(p).replace(/\/+$/, ''); } | |||
if ( storedPath && normPath(storedPath) !== normPath(currentPath) ) { | |||
try { sessionStorage.removeItem( 'gr_search_hl' ); } catch(e) {} | |||
return; | |||
} | |||
var query = stored.query.trim(); | |||
if ( !query ) return; | |||
try { sessionStorage.removeItem( 'gr_search_hl' ); } catch(e) {} | |||
var delays = [0, 200, 600]; | |||
delays.forEach( function(ms) { | |||
setTimeout( function () { | |||
if ( !document.querySelector( '.gr-search-hl' ) ) { | |||
highlightText( query ); | |||
} | |||
}, ms ); | |||
} ); | |||
} | |||
function highlightText( query ) { | |||
var content = document.querySelector( '#mw-content-text .mw-parser-output' ); | |||
if ( !content ) return; | |||
var raw = query.replace( /^"|"$/g, '' ).trim(); | |||
if ( !raw ) return; | |||
var patterns = []; | |||
patterns.push( escapeRegex( raw ) ); | |||
raw.split( /\s+/ ).forEach( function(w) { | |||
if ( w.length >= 2 ) patterns.push( escapeRegex( w ) ); | |||
} ); | |||
var matched = false; | |||
for ( var pi = 0; pi < patterns.length; pi++ ) { | |||
var re; | |||
try { re = new RegExp( '(' + patterns[pi] + ')', 'gi' ); } | |||
catch(e) { continue; } | |||
var count = wrapMatches( content, re ); | |||
if ( count > 0 ) { matched = true; break; } | |||
} | |||
if ( !matched ) return; | |||
var first = document.querySelector( '.gr-search-hl' ); | |||
if ( first ) { | |||
first.scrollIntoView({ behavior: 'smooth', block: 'center' }); | |||
first.classList.add( 'gr-search-hl-pulse' ); | |||
setTimeout( function() { | |||
first.classList.remove( 'gr-search-hl-pulse' ); | |||
}, 2000 ); | |||
} | |||
showDismissBar( query ); | |||
} | |||
function escapeRegex( s ) { | |||
return s.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); | |||
} | |||
function wrapMatches( root, re ) { | |||
var count = 0; | |||
var walker = document.createTreeWalker( | |||
root, NodeFilter.SHOW_TEXT, { | |||
acceptNode: function( node ) { | |||
var p = node.parentElement; | |||
if ( !p ) return NodeFilter.FILTER_REJECT; | |||
var tag = p.tagName.toUpperCase(); | |||
if ( tag === 'SCRIPT' || tag === 'STYLE' || tag === 'NOSCRIPT' ) return NodeFilter.FILTER_REJECT; | |||
if ( p.classList.contains( 'gr-search-hl' ) ) return NodeFilter.FILTER_REJECT; | |||
return NodeFilter.FILTER_ACCEPT; | |||
} | |||
}, false | |||
); | |||
var nodes = []; | |||
var node; | |||
while ( ( node = walker.nextNode() ) ) nodes.push( node ); | |||
nodes.forEach( function( textNode ) { | |||
var val = textNode.nodeValue; | |||
if ( !re.test( val ) ) return; | |||
re.lastIndex = 0; | |||
var frag = document.createDocumentFragment(); | |||
var last = 0; | |||
var m; | |||
while ( ( m = re.exec( val ) ) !== null ) { | |||
if ( m.index > last ) { | |||
frag.appendChild( document.createTextNode( val.slice( last, m.index ) ) ); | |||
} | |||
var span = document.createElement( 'span' ); | |||
span.className = 'gr-search-hl'; | |||
span.textContent = m[0]; | |||
frag.appendChild( span ); | |||
last = m.index + m[0].length; | |||
count++; | |||
} | |||
if ( last < val.length ) { | |||
frag.appendChild( document.createTextNode( val.slice( last ) ) ); | |||
} | |||
textNode.parentNode.replaceChild( frag, textNode ); | |||
} ); | |||
return count; | |||
} | |||
function showDismissBar( query ) { | |||
var isMob = window.innerWidth < 768; | |||
var bar = document.createElement( 'div' ); | |||
bar.id = 'gr-hl-bar'; | |||
if ( isMob ) { | |||
bar.style.cssText = [ | |||
'position:fixed', | |||
'top:calc(var(--gr-header-height,56px) + var(--gr-toc-top,52px) + 8px)', | |||
'left:50%', 'transform:translateX(-50%)', | |||
'z-index:10200', | |||
'background:#b5451b', 'color:#fff', | |||
'padding:8px 14px', | |||
'border-radius:24px', | |||
'display:flex', 'align-items:center', 'gap:8px', | |||
'font-family:system-ui,sans-serif', 'font-size:13px', | |||
'box-shadow:0 3px 12px rgba(0,0,0,0.25)', | |||
'white-space:nowrap', | |||
'max-width:calc(100vw - 32px)' | |||
].join(';'); | |||
} else { | |||
bar.style.cssText = [ | |||
'position:fixed', 'bottom:0', 'left:0', 'right:0', 'z-index:10200', | |||
'background:#b5451b', 'color:#fff', 'padding:10px 16px', | |||
'display:flex', 'align-items:center', 'justify-content:space-between', | |||
'font-family:system-ui,sans-serif', 'font-size:14px', | |||
'box-shadow:0 -2px 8px rgba(0,0,0,0.2)' | |||
].join(';'); | |||
} | |||
var count = document.querySelectorAll( '.gr-search-hl' ).length; | |||
if ( isMob ) { | |||
bar.innerHTML = | |||
'<span style="flex-shrink:0">🔍 ' + count + '</span>' + | |||
'<button id="gr-hl-prev" style="background:rgba(255,255,255,0.2);border:none;color:#fff;min-width:36px;height:36px;border-radius:50%;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;">↑</button>' + | |||
'<button id="gr-hl-next" style="background:rgba(255,255,255,0.2);border:none;color:#fff;min-width:36px;height:36px;border-radius:50%;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;">↓</button>' + | |||
'<button id="gr-hl-results" style="background:rgba(255,255,255,0.2);border:none;color:#fff;min-width:36px;height:36px;border-radius:50%;cursor:pointer;font-size:14px;display:flex;align-items:center;justify-content:center;">←</button>' + | |||
'<button id="gr-hl-dismiss" style="background:rgba(255,255,255,0.15);border:none;color:#fff;min-width:36px;height:36px;border-radius:50%;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;">✕</button>'; | |||
} else { | |||
var nav = document.createElement( 'div' ); | |||
nav.style.cssText = 'display:flex;align-items:center;gap:12px;'; | |||
nav.innerHTML = | |||
'<span>🔍 <strong>' + escHtml(query) + '</strong> — ' + count + ' match' + (count===1?'':'es') + '</span>' + | |||
'<button id="gr-hl-prev" style="background:rgba(255,255,255,0.2);border:none;color:#fff;padding:4px 10px;border-radius:4px;cursor:pointer;font-size:13px;min-height:32px;">↑ Prev</button>' + | |||
'<button id="gr-hl-next" style="background:rgba(255,255,255,0.2);border:none;color:#fff;padding:4px 10px;border-radius:4px;cursor:pointer;font-size:13px;min-height:32px;">↓ Next</button>' + | |||
'<button id="gr-hl-results" style="background:rgba(255,255,255,0.2);border:none;color:#fff;padding:4px 10px;border-radius:4px;cursor:pointer;font-size:13px;min-height:32px;">← Results</button>'; | |||
bar.appendChild( nav ); | |||
} | |||
var dismiss = isMob | |||
? bar.querySelector( '#gr-hl-dismiss' ) | |||
: ( function() { | |||
var b = document.createElement( 'button' ); | |||
b.textContent = '✕ Close'; | |||
b.id = 'gr-hl-dismiss'; | |||
b.style.cssText = 'background:rgba(255,255,255,0.15);border:none;color:#fff;padding:4px 12px;border-radius:4px;cursor:pointer;font-size:13px;min-height:32px;'; | |||
bar.appendChild( b ); | |||
return b; | |||
}() ); | |||
dismiss.onclick = function () { | |||
clearHighlights(); | |||
bar.remove(); | |||
}; | |||
document.body.appendChild( bar ); | |||
var hlEls = Array.from( document.querySelectorAll( '.gr-search-hl' ) ); | |||
var currentIdx = 0; | |||
function goTo( idx ) { | |||
hlEls.forEach( function(el) { el.classList.remove( 'gr-search-hl-current' ); } ); | |||
currentIdx = ( idx + hlEls.length ) % hlEls.length; | |||
var el = hlEls[ currentIdx ]; | |||
el.classList.add( 'gr-search-hl-current' ); | |||
el.scrollIntoView({ behavior: 'smooth', block: 'center' }); | |||
} | |||
var nextBtn = document.getElementById( 'gr-hl-next' ); | |||
var prevBtn = document.getElementById( 'gr-hl-prev' ); | |||
var resultsBtn = document.getElementById( 'gr-hl-results' ); | |||
if ( nextBtn ) nextBtn.onclick = function() { goTo( currentIdx + 1 ); }; | |||
if ( prevBtn ) prevBtn.onclick = function() { goTo( currentIdx - 1 ); }; | |||
if ( resultsBtn ) resultsBtn.onclick = function() { | |||
bar.remove(); | |||
/* Re-open search dialog with the same query prefilled */ | |||
if ( window.showSearchDialog ) { window.showSearchDialog( query ); } | |||
}; | |||
} | |||
function clearHighlights() { | |||
document.querySelectorAll( '.gr-search-hl' ).forEach( function( span ) { | |||
var parent = span.parentNode; | |||
while ( span.firstChild ) parent.insertBefore( span.firstChild, span ); | |||
parent.removeChild( span ); | |||
} ); | |||
} | |||
function escHtml( s ) { | |||
return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); | |||
} | |||
function injectHighlightCSS() { | |||
if ( document.getElementById( 'gr-hl-css' ) ) return; | |||
var s = document.createElement( 'style' ); | |||
s.id = 'gr-hl-css'; | |||
s.textContent = [ | |||
'.gr-search-hl{', | |||
' background:#fff176;color:#1a1a1a;', | |||
' border-radius:2px;padding:0 1px;', | |||
' box-shadow:0 0 0 1px rgba(181,69,27,0.25);', | |||
'}', | |||
'.gr-search-hl-current{', | |||
' background:#ffb300!important;', | |||
' box-shadow:0 0 0 2px #b5451b!important;', | |||
'}', | |||
'@keyframes gr-hl-pulse{', | |||
' 0%{background:#ffb300;}', | |||
' 50%{background:#fff176;}', | |||
' 100%{background:#fff176;}', | |||
'}', | |||
'.gr-search-hl-pulse{animation:gr-hl-pulse 1.2s ease 2;}', | |||
].join(''); | |||
document.head.appendChild( s ); | |||
} | |||
injectHighlightCSS(); | |||
if ( document.readyState === 'loading' ) { | |||
document.addEventListener( 'DOMContentLoaded', applyHighlight ); | |||
} else { | |||
applyHighlight(); | |||
} | |||
window.grStoreSearchHL = storeQueryForLink; | |||
}() ); | |||
/* ═══════════════════════════════════════════════════════════════ | |||
Mobile addon — paste at bottom of MediaWiki:Common.js | |||
Only runs on Minerva (mobile) skin | |||
═══════════════════════════════════════════════════════════════ */ | |||
( function () { | |||
if ( !document.body.classList.contains( 'skin-minerva' ) ) return; | |||
/* ── 1. CSS injected into <head> ── */ | |||
function injectCSS() { | |||
if ( document.getElementById( 'gr-mob-css' ) ) return; | |||
var s = document.createElement( 'style' ); | |||
s.id = 'gr-mob-css'; | |||
s.textContent = | |||
'body,#mw-mf-viewport,#mw-mf-page-center{padding-top:0!important;margin-top:0!important;}' + | |||
'html,body,#mw-mf-viewport,#mw-mf-page-center{overflow-x:hidden!important;max-width:100vw!important;}' + | |||
'header.header-container{background:#b5451b!important;position:sticky!important;top:0!important;z-index:300!important;}' + | |||
'.minerva-header{background:#b5451b!important;min-height:54px!important;}' + | |||
'.minerva-header .search-toggle,.minerva-header .minerva-user-notifications{display:none!important;}' + | |||
'.branding-box a{display:flex!important;align-items:center!important;' + | |||
'text-decoration:none!important;max-width:calc(100vw - 80px)!important;}' + | |||
'.branding-box a::before{content:"";display:block;width:30px;height:30px;flex-shrink:0;' + | |||
'background:url("/favicon.png") center/contain no-repeat;' + | |||
'margin-right:8px;}' + | |||
'.branding-box a span{color:#fff!important;font-size:16px!important;font-weight:700!important;' + | |||
'font-family:system-ui,sans-serif!important;line-height:1.2!important;' + | |||
'flex:1 1 auto!important;min-width:0!important;}' + | |||
'.minerva-header svg path,.minerva-header svg rect,.minerva-header svg circle{fill:#fff!important;}' + | |||
'.minerva-header label{color:#fff!important;}' + | |||
'.minerva-tabs,.mw-portlet-associated-pages,.page-actions-menu,' + | |||
'#page-secondary-actions,.last-modified-bar,.minerva-anon-talk-link{display:none!important;}' + | |||
'#gr-mob-menu-items{display:block!important;}' + | |||
'.mw-footer.minerva-footer,.footer-places,.footer-info,' + | |||
'.minerva-footer-logo,#footer-places-about,' + | |||
'#footer-places-disclaimers,#footer-places-privacy{display:none!important;}' + | |||
'#gr-static-bar{position:sticky!important;top:54px!important;z-index:200!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{display:block!important;visibility:visible!important;}' + | |||
'.collapsible-block{display:block!important;}' + | |||
'.section-heading .indicator,.collapsible-heading .indicator{display:none!important;}' + | |||
'.section-heading,.collapsible-heading{pointer-events:none!important;}' + | |||
'.gr-home-grid{flex-direction:column!important;flex-wrap:nowrap!important;' + | |||
'gap:12px!important;width:100%!important;}' + | |||
'.gr-home-card{width:100%!important;max-width:100%!important;' + | |||
'min-width:unset!important;box-sizing:border-box!important;flex:none!important;}' + | |||
'.gr-home-toggle{flex-wrap:wrap!important;}' + | |||
'.mw-parser-output{font-size:18px!important;line-height:1.8!important;}' + | |||
'.mw-parser-output h2,.mw-parser-output h3{width:100%!important;}' + | |||
'.bhashyam-block{margin-left:8px!important;}' + | |||
'#footer,.mw-footer,.catlinks,#catlinks{display:none!important;}' + | |||
'.gr-mob-toc-panel{position:fixed!important;top:0!important;left:0!important;' + | |||
'bottom:0!important;width:82vw!important;max-width:340px!important;' + | |||
'background:#fff!important;z-index:10400!important;' + | |||
'box-shadow:4px 0 28px rgba(0,0,0,0.22)!important;overflow-y:auto!important;' + | |||
'padding:0 0 40px!important;transform:translateX(-110%)!important;' + | |||
'transition:transform 0.26s cubic-bezier(0.4,0,0.2,1)!important;display:block!important;}' + | |||
'.gr-mob-toc-panel.open{transform:translateX(0)!important;}' + | |||
'.gr-mob-toc-backdrop{display:none!important;position:fixed!important;inset:0!important;' + | |||
'background:rgba(0,0,0,0.4)!important;z-index:10399!important;}' + | |||
'.gr-mob-toc-backdrop.open{display:block!important;}' + | |||
'.gr-mob-toc-header{position:sticky!important;top:0!important;background:#fff!important;' + | |||
'display:flex!important;align-items:center!important;justify-content:space-between!important;' + | |||
'padding:16px 16px 12px!important;border-bottom:1px solid #f0ebe6!important;z-index:1!important;}' + | |||
'.gr-mob-toc-title{font-size:13px!important;font-weight:700!important;text-transform:uppercase!important;' + | |||
'letter-spacing:0.08em!important;color:#b5451b!important;font-family:system-ui,sans-serif!important;}' + | |||
'.gr-mob-toc-close{background:none!important;border:none!important;' + | |||
'font-size:22px!important;color:#999!important;cursor:pointer!important;padding:4px 8px!important;}' + | |||
'.gr-mob-toc-body{padding:12px 16px!important;}' + | |||
'.gr-mob-toc-body a{display:block!important;font-size:16px!important;line-height:1.6!important;' + | |||
'color:#2c1810!important;text-decoration:none!important;padding:8px 0!important;' + | |||
'border-bottom:1px solid #f5f0ed!important;}'; | |||
document.head.appendChild( s ); | |||
} | |||
/* ── 2. Expand hidden 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' ); | |||
} ); | |||
} | |||
function watchSections() { | |||
var t = null; | |||
var obs = new MutationObserver( function ( ms ) { | |||
if ( ms.some( function(m){ return m.attributeName === 'hidden'; } ) ) { | |||
clearTimeout(t); t = setTimeout( expandSections, 30 ); | |||
} | |||
} ); | |||
var root = document.querySelector( '#mw-content-text' ) || document.body; | |||
obs.observe( root, { subtree:true, attributes:true, attributeFilter:['hidden','aria-hidden'] } ); | |||
} | |||
/* ── 3. Body padding observer ── */ | |||
function watchBodyPadding() { | |||
new MutationObserver( function () { | |||
if ( document.body.style.paddingTop && document.body.style.paddingTop !== '0px' ) { | |||
document.body.style.paddingTop = ''; | |||
} | |||
} ).observe( document.body, { attributes:true, attributeFilter:['style'] } ); | |||
} | |||
/* ── 4. Inject custom links into drawer ── */ | |||
function injectMenuLinks() { | |||
if ( document.getElementById( 'gr-mob-menu-items' ) ) return; | |||
var navDrawer = document.querySelector( '.navigation-drawer' ); | |||
if ( !navDrawer ) return; | |||
var wrap = document.createElement( 'div' ); | |||
wrap.id = 'gr-mob-menu-items'; | |||
wrap.style.cssText = 'width:100%;background:#fff;margin-top:8px;'; | |||
var itemStyle = 'display:flex;align-items:center;gap:14px;padding:15px 20px;' + | |||
'font-size:16px;color:#2c1810;text-decoration:none;' + | |||
'font-family:system-ui,sans-serif;border-bottom:1px solid #f0ebe6;background:#fff;'; | |||
function makeItem( href, emoji, label ) { | |||
var a = document.createElement( 'a' ); | |||
a.href = href; | |||
a.style.cssText = itemStyle; | |||
a.innerHTML = | |||
'<span>' + label + '</span>'; | |||
return a; | |||
} | |||
wrap.appendChild( makeItem( '/Main_Page', '', 'Home' ) ); | |||
wrap.appendChild( makeItem( '/My_wiki:Help', '', 'Help' ) ); | |||
wrap.appendChild( makeItem( '/My_wiki:About', '', 'About' ) ); | |||
var userName = window.mw ? mw.config.get( 'wgUserName' ) : null; | |||
if ( userName ) { | |||
var la = document.querySelector( 'a[href*="action=logout"]' ); | |||
wrap.appendChild( makeItem( | |||
la ? la.href : '/index.php?title=Special:UserLogout', '', 'Log out' | |||
) ); | |||
} else { | |||
wrap.appendChild( makeItem( '/index.php?title=Special:UserLogin', '', 'Log in' ) ); | |||
} | |||
var pageLeft = document.getElementById( 'mw-mf-page-left' ); | |||
if ( pageLeft ) { | |||
while ( pageLeft.firstChild ) pageLeft.removeChild( pageLeft.firstChild ); | |||
pageLeft.style.removeProperty( 'display' ); | |||
pageLeft.appendChild( wrap ); | |||
} else { | |||
navDrawer.appendChild( wrap ); | |||
} | |||
document.querySelectorAll( | |||
'.mw-footer.minerva-footer,.footer-places,.footer-info,' + | |||
'.minerva-footer-logo,#footer-places-about,' + | |||
'#footer-places-disclaimers,#footer-places-privacy' | |||
).forEach( function(el) { el.style.setProperty('display','none','important'); } ); | |||
} | |||
/* ── 5. Mobile TOC overlay ── */ | |||
var _tocDone = false; | |||
function initToc() { | |||
if ( _tocDone ) return; | |||
var tocList = document.querySelector( '.vector-toc-contents, .vector-toc .vector-toc-list' ); | |||
if ( !tocList ) return; | |||
if ( !tocList.querySelector( 'li' ) ) return; | |||
_tocDone = 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 ); | |||
var btn = document.createElement( 'button' ); | |||
btn.id = 'gr-mob-toc-btn'; | |||
btn.innerHTML = '☰ Contents'; | |||
btn.style.cssText = 'position:fixed;bottom:148px;left:16px;z-index:9100;' + | |||
'background:#fff;border:1.5px solid #b5451b;border-radius:24px;' + | |||
'padding:10px 16px;font-size:15px;font-family:system-ui,sans-serif;' + | |||
'color:#b5451b;font-weight:600;box-shadow:0 3px 14px rgba(0,0,0,0.15);cursor:pointer;'; | |||
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.onclick = open; cls.onclick = close; bd.onclick = close; | |||
body.querySelectorAll('a').forEach(function(a){ a.onclick = close; }); | |||
} | |||
/* ── 6. Moolam / Ullekha links below page title (mobile only) ── */ | |||
function injectMoolaUllekhaLinks() { | |||
if ( document.getElementById( 'gr-mob-doc-nav' ) ) return; | |||
var pageName = ( window.mw && mw.config && mw.config.get( 'wgPageName' ) ) || ''; | |||
if ( pageName === 'Main_Page' || !pageName ) return; | |||
function wikiUrl( slug ) { | |||
if ( window.mw && mw.util && mw.util.getUrl ) return mw.util.getUrl( slug ); | |||
var ap = ( window.mw && mw.config && mw.config.get( 'wgArticlePath' ) ) || '/wiki/$1'; | |||
return ap.replace( '$1', encodeURIComponent( slug ).replace( /%2F/g, '/' ) ); | |||
} | |||
var teekaPage = document.querySelector( '.gr-teeka-page' ); | |||
var primarySlug = teekaPage | |||
? ( teekaPage.getAttribute( 'data-primary' ) || pageName.split('/')[0] ) | |||
: pageName.split('/')[0]; | |||
var docTitleEl = document.querySelector( '.gr-doc-title' ); | |||
var hasMoolaPage = docTitleEl && docTitleEl.getAttribute( 'data-has-moola' ) === '1'; | |||
var hasUllekhaPage = docTitleEl && docTitleEl.getAttribute( 'data-has-ullekha' ) === '1'; | |||
var showMoolam = !!teekaPage || hasMoolaPage; | |||
var showUllekha = hasUllekhaPage || !!teekaPage; | |||
if ( !showMoolam && !showUllekha ) return; | |||
var nav = document.createElement( 'div' ); | |||
nav.id = 'gr-mob-doc-nav'; | |||
nav.style.cssText = 'display:flex;gap:10px;padding:10px 16px 8px;' + | |||
'background:#fdf8f5;border-bottom:1px solid #f0e0d6;font-family:system-ui,sans-serif;'; | |||
function makeLink( href, label ) { | |||
var a = document.createElement( 'a' ); | |||
a.href = href; a.textContent = label; | |||
a.style.cssText = 'display:inline-flex;align-items:center;padding:5px 16px;' + | |||
'border-radius:20px;background:#fff;border:1.5px solid #e8cfc4;' + | |||
'color:#b5451b;font-size:14px;font-weight:600;text-decoration:none;'; | |||
return a; | |||
} | |||
if ( teekaPage ) nav.appendChild( makeLink( wikiUrl( primarySlug ), 'मूल' ) ); | |||
else if ( hasMoolaPage ) nav.appendChild( makeLink( wikiUrl( primarySlug + '/Moola' ), 'मूलम्' ) ); | |||
if ( showUllekha ) nav.appendChild( makeLink( wikiUrl( primarySlug + '/Ullekha' ), 'उल्लेख' ) ); | |||
/* Insert below the page h1 */ | |||
var h1 = document.getElementById( 'firstHeading' ) || | |||
document.querySelector( '.page-heading, h1.firstHeading, .mw-first-heading' ); | |||
if ( h1 && h1.parentNode ) { | |||
h1.parentNode.insertBefore( nav, h1.nextSibling ); | |||
} else { | |||
var ct = document.getElementById( 'mw-content-text' ); | |||
if ( ct ) ct.insertBefore( nav, ct.firstChild ); | |||
} | |||
} | |||
/* ── Boot ── */ | |||
injectCSS(); | |||
watchBodyPadding(); | |||
function boot() { | |||
expandSections(); | |||
watchSections(); | |||
injectMenuLinks(); | |||
injectMoolaUllekhaLinks(); | |||
[100, 400, 900, 1800].forEach(function(ms){ setTimeout(expandSections, ms); }); | |||
setTimeout(initToc, 700); | |||
} | |||
if ( document.readyState === 'loading' ) { | |||
document.addEventListener( 'DOMContentLoaded', boot ); | |||
} else { | |||
boot(); | |||
} | |||
if ( window.mw ) { | |||
mw.hook( 'wikipage.content' ).add(function() { | |||
setTimeout(function(){ | |||
expandSections(); injectMenuLinks(); injectMoolaUllekhaLinks(); initToc(); | |||
}, 300); | |||
}); | |||
} | |||
}() ); | |||
/** | |||
* grantha-mobile-fixes.js | |||
*/ | |||
( function () { | |||
'use strict'; | |||
mw.hook( 'wikipage.content' ).add( function () { | |||
setTimeout( function () { | |||
var blocks = document.querySelectorAll( '.collapsible-block, .toggle-list' ); | |||
Array.prototype.forEach.call( blocks, function ( el ) { | |||
if ( !el.parentNode ) { | |||
try { el.remove(); } catch(e) {} | |||
} | |||
} ); | |||
}, 0 ); | |||
} ); | |||
if ( mw.config.get( 'wgPageName' ) !== 'Main_Page' ) return; | |||
mw.loader.using( 'mediawiki.util' ).done( function () { | |||
$( function () { | |||
applyHomeToggleOffset(); | |||
window.addEventListener( 'resize', applyHomeToggleOffset, { passive: true } ); | |||
setTimeout( applyHomeToggleOffset, 300 ); | |||
setTimeout( applyHomeToggleOffset, 800 ); | |||
} ); | |||
} ); | |||
function applyHomeToggleOffset() { | |||
var bar = document.getElementById( 'gr-static-bar' ); | |||
if ( !bar ) return; | |||
var barRect = bar.getBoundingClientRect(); | |||
var barBottom = Math.round( barRect.bottom ); | |||
var homeEl = document.getElementById( 'gr-home' ); | |||
var toggleEl = document.getElementById( 'gr-home-toggle' ); | |||
var firstChild = document.querySelector( | |||
'#mw-content-text .mw-parser-output > .gr-home, ' + | |||
'#mw-content-text .mw-parser-output > *:first-child' | |||
); | |||
[ homeEl, toggleEl, firstChild ].forEach( function ( el ) { | |||
if ( el ) el.style.scrollMarginTop = ( barBottom + 4 ) + 'px'; | |||
} ); | |||
var contentText = document.getElementById( 'mw-content-text' ); | |||
if ( contentText ) { | |||
var isMob = window.innerWidth < 768 || !!document.getElementById( 'mw-mf-viewport' ); | |||
if ( isMob ) { | |||
if ( toggleEl ) { | |||
var toggleRect = toggleEl.getBoundingClientRect(); | |||
if ( toggleRect.top < barBottom ) { | |||
var currentPT = parseInt( window.getComputedStyle( document.body ).paddingTop, 10 ) || 0; | |||
var needed = currentPT + ( barBottom - toggleRect.top ) + 4; | |||
document.body.style.paddingTop = needed + 'px'; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
$( function () { | |||
var $toggle = $( '#gr-home-toggle' ); | |||
var $viewG = $( '#gr-view-grantha' ); | |||
var $viewA = $( '#gr-view-author' ); | |||
var $btnG = $( '#gr-toggle-grantha' ); | |||
var $btnA = $( '#gr-toggle-author' ); | |||
if ( !$toggle.length || !$viewG.length || !$viewA.length ) return; | |||
if ( $toggle.data( 'gr-wired' ) ) return; | |||
$toggle.data( 'gr-wired', true ); | |||
function showView( which ) { | |||
if ( which === 'grantha' ) { | |||
$viewG.show(); $viewA.hide(); | |||
$btnG.addClass( 'gr-toggle-active' ); | |||
$btnA.removeClass( 'gr-toggle-active' ); | |||
} else { | |||
$viewA.show(); $viewG.hide(); | |||
$btnA.addClass( 'gr-toggle-active' ); | |||
$btnG.removeClass( 'gr-toggle-active' ); | |||
} | |||
try { localStorage.setItem( 'grantha_home_tab', which ); } catch(e){} | |||
} | |||
$btnG.on( 'click keydown', function(e){ | |||
if ( e.type === 'keydown' && e.key !== 'Enter' && e.key !== ' ' ) return; | |||
showView( 'grantha' ); | |||
}); | |||
$btnA.on( 'click keydown', function(e){ | |||
if ( e.type === 'keydown' && e.key !== 'Enter' && e.key !== ' ' ) return; | |||
showView( 'author' ); | |||
}); | |||
try { | |||
var saved = localStorage.getItem( 'grantha_home_tab' ); | |||
if ( saved === 'author' ) showView( 'author' ); | |||
else showView( 'grantha' ); | |||
} catch(e) { showView( 'grantha' ); } | |||
} ); | |||
}() ); | }() ); | ||