MediaWiki:Common.js
Appearance
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* =========================
VERSE ACTIONS
========================= */
( function () {
'use strict';
/* ── Safe delegated listener ─────────────────────────────────────────── */
function onDocClick( e ) {
var target = e.target;
// Walk up to find a matching action button
function closest( el, cls ) {
while ( el && el !== document ) {
if ( el.classList && el.classList.contains( cls ) ) return el;
el = el.parentNode;
}
return null;
}
/* ── Commentary toggle ── */
var commentBtn = closest( target, 'verse-action-commentary' );
if ( commentBtn ) {
e.preventDefault();
var verseId = commentBtn.getAttribute( 'data-verse' );
if ( !verseId ) return;
// Match all commentary bodies for this verse by id prefix
var allBodies = document.querySelectorAll( '[id^="commentary-body-' + verseId + '"]' );
var allBtns = document.querySelectorAll( '.verse-action-commentary[data-verse="' + verseId + '"]' );
var isOpen = allBodies.length && allBodies[0].classList.contains( 'open' );
// Close all open commentaries on the page first
document.querySelectorAll( '.commentary-body.open' ).forEach( function ( el ) {
el.classList.remove( 'open' );
} );
document.querySelectorAll( '.verse-action-commentary.active' ).forEach( function ( el ) {
el.classList.remove( 'active' );
} );
// If it was closed, open it
if ( !isOpen ) {
allBodies.forEach( function ( el ) { el.classList.add( 'open' ); } );
allBtns.forEach( function ( el ) { el.classList.add( 'active' ); } );
}
return;
}
/* ── Copy verse — copies verse ID for crosslinking ── */
var copyBtn = closest( target, 'verse-action-copy' );
if ( copyBtn ) {
e.preventDefault();
var verseId = copyBtn.getAttribute( 'data-verse' );
if ( !verseId ) return;
copyText( verseId, copyBtn );
return;
}
/* ── Copy ID ── */
var idBtn = closest( target, 'copy-id-btn' );
if ( idBtn ) {
e.preventDefault();
var id = idBtn.getAttribute( 'data-copyid' );
if ( !id ) return;
copyText( id, idBtn );
return;
}
}
document.addEventListener( 'click', onDocClick );
/* ── Copy helper + tooltip ───────────────────────────────────────────── */
function copyText( text, btn ) {
function showTooltip() {
// Remove stale tooltip if double-clicked
var old = btn.querySelector( '.copy-tooltip' );
if ( old ) old.remove();
btn.style.position = 'relative';
var tip = document.createElement( 'span' );
tip.className = 'copy-tooltip';
tip.textContent = 'Copied ✓';
btn.appendChild( tip );
requestAnimationFrame( function () {
requestAnimationFrame( function () {
tip.classList.add( 'copy-tooltip-visible' );
} );
} );
setTimeout( function () {
tip.classList.remove( 'copy-tooltip-visible' );
setTimeout( function () { tip.remove(); }, 400 );
}, 1400 );
}
if ( navigator.clipboard && window.isSecureContext ) {
navigator.clipboard.writeText( text ).then( showTooltip );
} else {
var ta = document.createElement( 'textarea' );
ta.value = text;
ta.style.cssText = 'position:fixed;opacity:0;pointer-events:none;';
document.body.appendChild( ta );
ta.select();
document.execCommand( 'copy' );
document.body.removeChild( ta );
showTooltip();
}
}
}() );
/* ════════════════════════════════════════════════════════════════
Grantha — MediaWiki:Common.js
Builds the top bar DOM on NS_MAIN pages.
All styles (chrome-hiding + top bar) live in MediaWiki:Common.css.
════════════════════════════════════════════════════════════════ */
( function () {
'use strict';
/* Only run on NS_MAIN pages */
if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 ) return;
mw.hook( 'wikipage.content' ).add( function () {
if ( document.getElementById( 'grantha-topbar' ) ) return;
/* Hide top bar on edit pages — the editor toolbar takes over */
var action = mw.config.get( 'wgAction' );
if ( action === 'edit' || action === 'submit' ) return;
var mainPage = ( mw.config.get( 'wgArticlePath' ) || '/wiki/$1' )
.replace( '$1', encodeURIComponent(
mw.config.get( 'wgMainPageTitle' ) || 'Main_Page'
) );
var bar = document.createElement( 'div' );
bar.id = 'grantha-topbar';
bar.innerHTML =
'<a class="gt-brand" href="' + mainPage + '">' +
' <img class="gt-favicon" src="/favicon.ico" alt="" />' +
' <span class="gt-name">Grantha</span>' +
'</a>' +
'<div class="gt-right">' +
' <button class="gt-btn" id="gt-newdoc">\u271a New Document</button>' +
'</div>';
document.body.prepend( bar );
document.getElementById( 'gt-newdoc' ).addEventListener( 'click', function () {
if ( window.NewPageDialog ) NewPageDialog.show();
} );
} );
}() );