MediaWiki:Common.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 3: | Line 3: | ||
* Changes vs v6: | * Changes vs v6: | ||
* 1. BUG FIX: Main IIFE was never properly closed — About link block was | * 1. BUG FIX: Main IIFE was never properly closed — About link block was | ||
* pasted inside it without closing }() ); which broke the module | * pasted inside it without the closing }() ); which broke the module | ||
* boundary and killed the by-Author toggle. Each block is now its | * boundary and killed the by-Author toggle. Each block is now its | ||
* own self-contained IIFE. | * own self-contained IIFE. | ||
* 2. TOC: "Beginning" link removed. | * 2. TOC: "Beginning" link removed. | ||
* 3. TOC: Heading label | * 3. TOC: Heading label → "विषयसूची". | ||
* 4. TOC: मूल / उल्लेख nav links injected at top of TOC panel. | * 4. TOC: मूल / उल्लेख nav links injected at top of TOC panel. | ||
* 5. TOC: All subsections expanded by default | * 5. TOC: All subsections expanded by default. | ||
* 6. TOC: Only the active item is bold; all others | * 6. TOC: Only the active item is bold; all others are normal weight. | ||
* 7. About link | * 7. About link URL derived from wgArticlePath — works under any | ||
* | * sub-path install (e.g. /My_wiki/). Points to "My_wiki:About". | ||
* 8. TOC customisations skipped on Main_Page and About pages | * 8. TOC customisations skipped on Main_Page and About pages. | ||
*/ | */ | ||
| Line 96: | Line 95: | ||
'य':'ய','र':'ர','ல':'ல','ळ':'ழ','व':'வ', | 'य':'ய','र':'ர','ல':'ல','ळ':'ழ','व':'வ', | ||
'श':'ஶ','ष':'ஷ','स':'ஸ','ह':'ஹ', | 'श':'ஶ','ष':'ஷ','स':'ஸ','ह':'ஹ', | ||
'ा':'ா','ि':'ி','ी':'ீ',' | 'ा':'ா','ि':'ி','ी':'ீ','ு':'ு','ू':'ூ', | ||
'ृ':'ு','ॄ':'ூ', | 'ृ':'ு','ॄ':'ூ', | ||
'े':'ே','ை':'ை','ो':'ோ','ौ':'ௌ', | 'े':'ே','ை':'ை','ो':'ோ','ौ':'ௌ', | ||
| Line 137: | Line 136: | ||
if ( p.hasAttribute && p.hasAttribute( 'data-deva' ) ) return; | if ( p.hasAttribute && p.hasAttribute( 'data-deva' ) ) return; | ||
if ( p.closest ) { | if ( p.closest ) { | ||
if ( p.closest( '.gr-controls' ) | if ( p.closest( '.gr-controls' ) ) return; | ||
if ( p.closest( '.mw-editsection' ) ) return; | if ( p.closest( '.mw-editsection' ) ) return; | ||
if ( p.closest( '#gr-toc-doc-nav' ) ) return; | if ( p.closest( '#gr-toc-doc-nav' ) ) return; | ||
} | } | ||
var orig = node.textContent; | var orig = node.textContent; | ||
| Line 151: | Line 150: | ||
} | } | ||
document.querySelectorAll( '.vector-toc .vector-toc-text' ).forEach( function ( span ) { | document.querySelectorAll( '.vector-toc .vector-toc-text' ).forEach( function ( span ) { | ||
if ( span.hasAttribute( 'data-deva' ) ) return; | if ( span.hasAttribute( 'data-deva' ) ) return; | ||
| Line 174: | Line 172: | ||
} | } | ||
// ── Pages where | // ── Pages where sidebar TOC should not be modified ────────────── | ||
function _isNoTocPage() { | function _isNoTocPage() { | ||
var pn = ( window.mw && mw.config && mw.config.get( 'wgPageName' ) ) || ''; | var pn = ( window.mw && mw.config && mw.config.get( 'wgPageName' ) ) || ''; | ||
| Line 188: | Line 185: | ||
var titleEl = toc.querySelector( '.vector-toc-title' ); | var titleEl = toc.querySelector( '.vector-toc-title' ); | ||
if ( !titleEl ) return; | if ( !titleEl ) return; | ||
var replaced = false; | var replaced = false; | ||
titleEl.childNodes.forEach( function ( n ) { | titleEl.childNodes.forEach( function ( n ) { | ||
| Line 201: | Line 197: | ||
} | } | ||
// ── TOC: Remove the | // ── TOC: Remove the "Beginning" / top-of-page link ───────────── | ||
function removeTocBeginning() { | function removeTocBeginning() { | ||
if ( _isNoTocPage() ) return; | if ( _isNoTocPage() ) return; | ||
| Line 208: | Line 204: | ||
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 256: | Line 251: | ||
var ullekhaUrl = wikiUrl( primarySlug + '/Ullekha' ); | var ullekhaUrl = wikiUrl( primarySlug + '/Ullekha' ); | ||
var isMoola = !teekaPage && | var isMoola = !teekaPage && | ||
( pageTitle === primarySlug || | ( pageTitle === primarySlug || | ||
| Line 264: | Line 258: | ||
nav.id = 'gr-toc-doc-nav'; | nav.id = 'gr-toc-doc-nav'; | ||
nav.setAttribute( 'style', [ | nav.setAttribute( 'style', [ | ||
'display:flex', 'gap:6px', | 'display:flex', 'gap:6px', 'padding:5px 8px 6px', | ||
'border-bottom:1px solid var(--border-color-base,#dcc9a8)', | 'border-bottom:1px solid var(--border-color-base,#dcc9a8)', | ||
'margin-bottom:4px', 'flex-wrap:wrap', | 'margin-bottom:4px', 'flex-wrap:wrap', | ||
| Line 277: | Line 270: | ||
].join( ';' ); | ].join( ';' ); | ||
function | function makeBtn( href, label, color, bg ) { | ||
var a = document.createElement( 'a' ); | var a = document.createElement( 'a' ); | ||
a.href = href; | a.href = href; | ||
| Line 287: | Line 280: | ||
} | } | ||
if ( !isMoola ) nav.appendChild( | if ( !isMoola ) nav.appendChild( makeBtn( moolaUrl, 'मूल', '#b04b00', '#fff3e0' ) ); | ||
nav.appendChild( | nav.appendChild( makeBtn( ullekhaUrl, 'उल्लेख', '#1a5f8a', '#e8f4fc' ) ); | ||
var tocContents = toc.querySelector( '.vector-toc-contents' ); | var tocContents = toc.querySelector( '.vector-toc-contents' ); | ||
| Line 296: | Line 289: | ||
// ── TOC active-item highlight ──────────────────────────────────── | // ── TOC active-item highlight ──────────────────────────────────── | ||
// v7: inactive items get font-weight:400 explicitly — only active gets 700. | |||
// v7 | |||
function watchTocActive() { | function watchTocActive() { | ||
if ( _isNoTocPage() ) return; | if ( _isNoTocPage() ) return; | ||
| Line 358: | Line 345: | ||
if ( active ) { | if ( active ) { | ||
/ | // Expand collapsed ancestor sections | ||
var anc = li.parentNode; | var anc = li.parentNode; | ||
while ( anc && anc !== document.body ) { | while ( anc && anc !== document.body ) { | ||
| Line 369: | Line 356: | ||
} | } | ||
/ | // Scroll active item into visible TOC area | ||
var container = document.querySelector( '.vector-sticky-pinned-container' ); | var container = document.querySelector( '.vector-sticky-pinned-container' ); | ||
if ( container ) { | if ( container ) { | ||
| Line 384: | Line 371: | ||
var ov = window.getComputedStyle( node ).overflowY; | var ov = window.getComputedStyle( node ).overflowY; | ||
if ( ( ov === 'auto' || ov === 'scroll' ) && | if ( ( ov === 'auto' || ov === 'scroll' ) && | ||
node.scrollHeight > node.clientHeight ) { | node.scrollHeight > node.clientHeight ) { sh = node; break; } | ||
node = node.parentNode; | node = node.parentNode; | ||
} | } | ||
| Line 409: | Line 394: | ||
if ( n.classList && n.classList.contains( 'vector-toc-list-item' ) ) attachHighlight( n ); | if ( n.classList && n.classList.contains( 'vector-toc-list-item' ) ) attachHighlight( n ); | ||
if ( n.querySelectorAll ) n.querySelectorAll( '.vector-toc-list-item' ).forEach( attachHighlight ); | if ( n.querySelectorAll ) n.querySelectorAll( '.vector-toc-list-item' ).forEach( attachHighlight ); | ||
var newSpans = []; | var newSpans = []; | ||
if ( n.classList && n.classList.contains( 'vector-toc-text' ) ) newSpans.push( n ); | if ( n.classList && n.classList.contains( 'vector-toc-text' ) ) newSpans.push( n ); | ||
| Line 465: | Line 449: | ||
removeHiddenEls(); | removeHiddenEls(); | ||
( function detectTeekaMode() { | ( function detectTeekaMode() { | ||
var tp = document.querySelector( '.gr-teeka-page' ); | var tp = document.querySelector( '.gr-teeka-page' ); | ||
| Line 478: | Line 461: | ||
} | } | ||
var ref = document.referrer || ''; | var ref = document.referrer || ''; | ||
document.body.classList.add( ( ref && primary && ref.indexOf( mainUrl ) !== -1 ) | document.body.classList.add( | ||
( ref && primary && ref.indexOf( mainUrl ) !== -1 ) ? 'gr-ref-mode' : 'gr-standalone' | |||
); | |||
}() ); | }() ); | ||
| Line 512: | Line 496: | ||
else { currentScript = 'deva'; } | else { currentScript = 'deva'; } | ||
/ | // Vector 2022 defers TOC render — retry at 300ms and 800ms | ||
setupToc(); | setupToc(); | ||
setTimeout( setupToc, 300 ); | setTimeout( setupToc, 300 ); | ||
| Line 524: | Line 508: | ||
} ); | } ); | ||
// ── MediaWiki SPA-style navigation | // ── MediaWiki SPA-style navigation ────────────────────────────── | ||
if ( window.mw ) { | if ( window.mw ) { | ||
mw.hook( 'wikipage.content' ).add( function () { | mw.hook( 'wikipage.content' ).add( function () { | ||
| Line 553: | Line 537: | ||
} | } | ||
}() ); /* ← end of main | }() ); /* ← end of main IIFE */ | ||
// ── Inject "About" link into the header ──────────────────────────── | // ── Inject "About" link into the header ──────────────────────────── | ||
// | // Separate IIFE — v6 had this nested inside the main IIFE without a | ||
// }() ); broke the module boundary and killed the by-Author toggle | // closing }() ); which broke the module boundary and killed the | ||
// by-Author toggle on the main page. | |||
( function () { | ( function () { | ||
function injectAboutLink() { | function injectAboutLink() { | ||
| Line 568: | Line 553: | ||
if ( !headerEnd ) return; | if ( !headerEnd ) return; | ||
/ | // mw.util.getUrl() uses wgArticlePath internally, so it always produces | ||
// the correct URL regardless of whether the wiki is at / or /My_wiki/. | |||
var href; | var href; | ||
if ( window.mw && mw.util && mw.util.getUrl ) { | if ( window.mw && mw.util && mw.util.getUrl ) { | ||
| Line 580: | Line 563: | ||
} | } | ||
var a | var a = document.createElement( 'a' ); | ||
a.id | a.id = 'gr-about-link'; | ||
a.href | a.href = href; | ||
a.textContent = 'About'; | a.textContent = 'About'; | ||
a.style.cssText = [ | a.style.cssText = [ | ||
| Line 592: | Line 575: | ||
].join( ';' ); | ].join( ';' ); | ||
a.addEventListener( 'mouseover', function () { | a.addEventListener( 'mouseover', function () { | ||
this.style.color = '#fff'; this.style.background = 'rgba(255,255,255,0.12)'; | this.style.color = '#fff'; | ||
this.style.background = 'rgba(255,255,255,0.12)'; | |||
} ); | } ); | ||
a.addEventListener( 'mouseout', function () { | a.addEventListener( 'mouseout', function () { | ||
this.style.color = 'rgba(255,255,255,0.88)'; this.style.background = 'transparent'; | this.style.color = 'rgba(255,255,255,0.88)'; | ||
this.style.background = 'transparent'; | |||
} ); | } ); | ||