Jump to content

MediaWiki:Common.js

From Grantha

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();
    }
  }

}() );
mw.loader.using(['mediawiki.util']).then(function () {

  if (mw.config.get('wgPageName') !== 'Main_Page') return;

  // Create top bar
  var bar = document.createElement('div');
  bar.id = 'grantha-topbar';

  bar.innerHTML = `
    <div class="gt-left">
      <img src="/favicon.ico" class="gt-icon">
      <span class="gt-title">Grantha</span>
    </div>
    <div class="gt-right" id="gt-right"></div>
  `;

  document.body.appendChild(bar);

  // Admin check
  var groups = mw.config.get('wgUserGroups') || [];
  var isAdmin = groups.indexOf('sysop') !== -1;

  if (isAdmin) {
    var btn = document.createElement('button');
    btn.innerText = '+ New Document';
    btn.className = 'gt-btn';

    btn.onclick = function () {
      var name = prompt('Enter new page name:');
      if (!name) return;

      // Normalize title
      name = name.trim().replace(/\s+/g, '_');

      var url = mw.util.getUrl(name, { action: 'edit' });
      window.location.href = url;
    };

    document.getElementById('gt-right').appendChild(btn);
  }

});