MediaWiki:Common.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 657: | Line 657: | ||
if ( document.readyState === 'loading' ) document.addEventListener( 'DOMContentLoaded', initHomeToggle ); | if ( document.readyState === 'loading' ) document.addEventListener( 'DOMContentLoaded', initHomeToggle ); | ||
else initHomeToggle(); | else initHomeToggle(); | ||
}() ); | |||
// ── Ullekha reference link handler ───────────────────────────────── | |||
// Two behaviours: | |||
// A) On the Ullekha page: clicking a .gr-ullekha-ref-link opens the | |||
// bhashya page at the anchor with a ?hlUllekha= param that triggers | |||
// highlight on arrival. Opens in the same tab (wiki navigation). | |||
// B) On the bhashya page: if URL has ?hlUllekha=<text>, find that text | |||
// in the page, scroll to it, and highlight it with a yellow background. | |||
( function () { | |||
// ── B) Bhashya page — highlight on arrival ────────────────────── | |||
function highlightOnArrival() { | |||
var search = window.location.search; | |||
if ( !search ) return; | |||
var m = search.match( /[?&]hlUllekha=([^&]+)/ ); | |||
if ( !m ) return; | |||
var needle; | |||
try { needle = decodeURIComponent( m[ 1 ] ); } catch ( e ) { return; } | |||
if ( !needle || needle.length < 4 ) return; | |||
var content = document.querySelector( '.mw-parser-output' ); | |||
if ( !content ) return; | |||
/* Walk all text nodes and find the first occurrence of needle. | |||
* We search in the textContent of every leaf element. */ | |||
var walker = document.createTreeWalker( content, NodeFilter.SHOW_TEXT ); | |||
var found = false; | |||
while ( walker.nextNode() && !found ) { | |||
var node = walker.currentNode; | |||
var txt = node.textContent || ''; | |||
/* partial match — needle may span multiple text nodes, | |||
so check for the first 30 chars */ | |||
var snippet = needle.slice( 0, 30 ); | |||
if ( txt.indexOf( snippet ) !== -1 ) { | |||
var span = document.createElement( 'mark' ); | |||
span.className = 'gr-ullekha-highlight'; | |||
span.style.cssText = 'background:#fff176;border-radius:2px;padding:0 2px;'; | |||
var parent = node.parentNode; | |||
/* Wrap the matching portion */ | |||
var idx = txt.indexOf( snippet ); | |||
if ( idx >= 0 ) { | |||
var before = document.createTextNode( txt.slice( 0, idx ) ); | |||
var after = document.createTextNode( txt.slice( idx + snippet.length ) ); | |||
span.textContent = txt.slice( idx, idx + needle.length > txt.length | |||
? txt.length : needle.length ); | |||
parent.insertBefore( before, node ); | |||
parent.insertBefore( span, node ); | |||
parent.insertBefore( after, node ); | |||
parent.removeChild( node ); | |||
/* Scroll into view */ | |||
setTimeout( function () { | |||
span.scrollIntoView( { behavior: 'smooth', block: 'center' } ); | |||
}, 300 ); | |||
found = true; | |||
} | |||
} | |||
} | |||
} | |||
// ── A) Ullekha page — make ref links navigate with hlUllekha param ── | |||
function wireUllekhaLinks() { | |||
document.querySelectorAll( '.gr-ullekha-ref-link' ).forEach( function ( wrap ) { | |||
var anchor = wrap.getAttribute( 'data-anchor' ) || ''; | |||
var hl = wrap.getAttribute( 'data-hl' ) || ''; | |||
var a = wrap.querySelector( 'a' ); | |||
if ( !a ) return; | |||
/* Rebuild the href to include ?hlUllekha= */ | |||
var base = a.href.split( '#' )[ 0 ]; | |||
var encoded = encodeURIComponent( hl ); | |||
a.href = base + ( hl ? '?hlUllekha=' + encoded : '' ) | |||
+ ( anchor ? '#' + anchor : '' ); | |||
} ); | |||
} | |||
if ( document.readyState === 'loading' ) { | |||
document.addEventListener( 'DOMContentLoaded', function () { | |||
highlightOnArrival(); | |||
wireUllekhaLinks(); | |||
} ); | |||
} else { | |||
highlightOnArrival(); | |||
wireUllekhaLinks(); | |||
} | |||
}() ); | }() ); | ||