Jump to content

MediaWiki:Common.js: Difference between revisions

From Grantha
No edit summary
No edit summary
Line 1: Line 1:
/* ── Verse Actions ─────────────────────────────────────────────────────── */
/* =========================
  VERSE ACTIONS
========================= */
( function () {
( function () {
    'use strict';
  '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;


    /* =========================
      var allBodies  = document.querySelectorAll( '.commentary-body[data-verse="' + verseId + '"]' );
   COPY FUNCTION + TOOLTIP
      var allBtns   = document.querySelectorAll( '.verse-action-commentary[data-verse="' + verseId + '"]' );
========================= */
      var isOpen    = allBodies.length && allBodies[0].classList.contains( 'open' );
function copyText(text, $btn) {
  function showTooltip() {
    // Remove any existing tip on this button first
    $btn.find('.copy-tooltip').remove();


    var $tip = $('<span class="copy-tooltip">Copied ✓</span>');
      // Close every open commentary first
    $btn.css('position', 'relative').append($tip);
      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' );
      } );


    // Trigger animation on next frame so transition fires
      // If it was closed, open it
    requestAnimationFrame(function () {
      if ( !isOpen ) {
      requestAnimationFrame(function () {
        allBodies.forEach( function ( el ) { el.classList.add( 'open' ); } );
        $tip.addClass('copy-tooltip-visible');
        allBtns.forEach(   function ( el ) { el.classList.add( 'active' ); } );
       });
       }
     });
      return;
     }


     setTimeout(function () {
     /* ── Copy verse ── */
       $tip.removeClass('copy-tooltip-visible');
    var copyBtn = closest( target, 'verse-action-copy' );
       // Remove after fade-out transition completes
    if ( copyBtn ) {
       setTimeout(function () { $tip.remove(); }, 400);
       e.preventDefault();
     }, 1400);
      var line1 = copyBtn.getAttribute( 'data-line1' ) || '';
      var line2 = copyBtn.getAttribute( 'data-line2' ) || '';
      var text  = line2 ? line1 + '\n' + line2 : line1;
      if ( !text ) return;
       copyText( text, 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;
     }
   }
   }


   if (navigator.clipboard && window.isSecureContext) {
   document.addEventListener( 'click', onDocClick );
    navigator.clipboard.writeText(text).then(showTooltip);
 
  } else {
  /* ── Copy helper + tooltip ───────────────────────────────────────────── */
    var $temp = $('<textarea>').val(text).appendTo('body');
  function copyText( text, btn ) {
    $temp[0].select();
     function showTooltip() {
    document.execCommand('copy');
      // Remove stale tooltip if double-clicked
    $temp.remove();
      var old = btn.querySelector( '.copy-tooltip' );
     showTooltip();
      if ( old ) old.remove();
  }
}
    // ── Commentary toggle handler ─────────────────────────────────────────
    function handleCommentary( btn ) {
        var verseId = btn.getAttribute( 'data-verse' );
        if ( !verseId ) return;


        var block = document.getElementById( verseId );
      btn.style.position = 'relative';
        if ( !block ) return;
      var tip = document.createElement( 'span' );
      tip.className  = 'copy-tooltip';
      tip.textContent = 'Copied ✓';
      btn.appendChild( tip );


        // Toggle visibility of all commentary panels inside this verse block
      requestAnimationFrame( function () {
        var panels = block.querySelectorAll( '.commentary-block' );
         requestAnimationFrame( function () {
         panels.forEach( function ( panel ) {
          tip.classList.add( 'copy-tooltip-visible' );
            var isHidden = panel.style.display === 'none' || !panel.style.display;
            panel.style.display = isHidden ? '' : 'none';
         } );
         } );
      } );


         btn.classList.toggle( 'verse-action-active' );
      setTimeout( function () {
         tip.classList.remove( 'copy-tooltip-visible' );
        setTimeout( function () { tip.remove(); }, 400 );
      }, 1400 );
     }
     }


     // ── Single delegated listener on the document ─────────────────────────
     if ( navigator.clipboard && window.isSecureContext ) {
    document.addEventListener( 'click', function ( e ) {
      navigator.clipboard.writeText( text ).then( showTooltip );
        var btn = e.target.closest( '.verse-action-btn' );
    } else {
        if ( !btn ) return;
      var ta = document.createElement( 'textarea' );
 
      ta.value = text;
        if ( btn.classList.contains( 'verse-action-copy' ) ) {
      ta.style.cssText = 'position:fixed;opacity:0;pointer-events:none;';
            handleCopy( btn );
      document.body.appendChild( ta );
        } else if ( btn.classList.contains( 'verse-action-commentary' ) ) {
      ta.select();
            handleCommentary( btn );
      document.execCommand( 'copy' );
        }
      document.body.removeChild( ta );
    } );
      showTooltip();
    }
  }


}() );
}() );

Revision as of 11:27, 27 March 2026

/* =========================
   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;

      var allBodies  = document.querySelectorAll( '.commentary-body[data-verse="' + verseId + '"]' );
      var allBtns    = document.querySelectorAll( '.verse-action-commentary[data-verse="' + verseId + '"]' );
      var isOpen     = allBodies.length && allBodies[0].classList.contains( 'open' );

      // Close every open commentary 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 ── */
    var copyBtn = closest( target, 'verse-action-copy' );
    if ( copyBtn ) {
      e.preventDefault();
      var line1 = copyBtn.getAttribute( 'data-line1' ) || '';
      var line2 = copyBtn.getAttribute( 'data-line2' ) || '';
      var text  = line2 ? line1 + '\n' + line2 : line1;
      if ( !text ) return;
      copyText( text, 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();
    }
  }

}() );