MediaWiki:Common.js: Difference between revisions

No edit summary
Tag: Reverted
Undo revision 5588 by Chandrashekars (talk)
Tag: Undo
Line 179: Line 179:


   // ── TOC: rename "Contents" → "विषयसूची" ────────────────────────
   // ── TOC: rename "Contents" → "विषयसूची" ────────────────────────
  function renameTocTitle() {
function renameTocTitle() {
    if ( _isNoTocPage() ) return;
  if ( _isNoTocPage() ) return;
    var toc = document.querySelector( '.vector-toc' );
 
    if ( !toc ) return;
  var toc = document.querySelector('.vector-toc');
    var titleEl = toc.querySelector( '.vector-toc-title' );
  if ( !toc ) return;
    if ( !titleEl ) return;
 
    var TITLE = 'विषयसूची';
  var titleEl =
    var replaced = false;
    toc.querySelector('.vector-toc-title') ||
    titleEl.childNodes.forEach( function ( n ) {
    toc.querySelector('.vector-pinnable-header-label');
      if ( n.nodeType === 3 && n.textContent.trim() ) {
 
        n.textContent = TITLE;
  if ( !titleEl ) return;
        replaced = true;
 
      }
  var LABEL = 'विषयसूची';
    } );
 
    if ( !replaced && titleEl.childElementCount === 0 ) {
  /* If already inserted, just refresh text */
      titleEl.textContent = TITLE;
  var span = titleEl.querySelector('.gr-toc-title');
    }
 
     // Fix up any <span data-deva> wrappers that tagTextNodes created
  if ( !span ) {
     // over "Contents" — update their data-deva to the new Sanskrit text
    titleEl.innerHTML = '';
    titleEl.querySelectorAll( '[data-deva]' ).forEach( function ( span ) {
 
      span.setAttribute( 'data-deva', TITLE );
     span = document.createElement('span');
      if ( currentScript !== 'deva' ) {
     span.className = 'gr-toc-title';
        span.textContent = transliterateText( TITLE, currentScript );
    span.setAttribute('data-deva', LABEL);
      } else {
 
        span.textContent = TITLE;
    titleEl.appendChild(span);
      }
    translatableSpans.push(span);   // uses your internal array
    } );
   }
   }


  span.textContent =
    currentScript === 'deva'
      ? LABEL
      : transliterateText(LABEL, currentScript);
}
   // ── TOC: Remove the "Beginning" / top-of-page link ─────────────
   // ── TOC: Remove the "Beginning" / top-of-page link ─────────────
   function removeTocBeginning() {
   function removeTocBeginning() {
Line 613: Line 617:
     }
     }


     // ── Scroll-based active anchor detection ──────────────────────
     // Track which anchors are visible
     // Find the last anchor whose top edge is above the scroll threshold
     var _visibleIds = new Set();
    // (1/3 of viewport height). This is robust for zero-height anchor spans
    // and matches how the ref site tracks active sections.
    var SCROLL_THRESHOLD_RATIO = 0.33; // top 1/3 of viewport


     function findActiveAnchor() {
     var observer = new IntersectionObserver( function ( entries ) {
       var threshold = window.innerHeight * SCROLL_THRESHOLD_RATIO;
       entries.forEach( function ( entry ) {
      var best = null;
         var id = entry.target.id;
      // Walk anchors in order; keep updating best as long as anchor is above threshold
         if ( entry.isIntersecting ) {
      for ( var k = 0; k < anchors.length; k++ ) {
           _visibleIds.add( id );
         var r = anchors[ k ].getBoundingClientRect();
        // Use top of the heading AFTER the anchor (anchor is height:0)
        // The anchor has padding-top:60px so its effective visual top is r.top
         if ( r.top <= threshold ) {
           best = anchors[ k ].id;
         } else {
         } else {
           break; // anchors are in document order — no need to continue
           _visibleIds.delete( id );
         }
         }
      } );
      // Find the topmost visible anchor
      var topId = null;
      var topY  = Infinity;
      _visibleIds.forEach( function ( id ) {
        var el = document.getElementById( id );
        if ( el ) {
          var y = el.getBoundingClientRect().top;
          if ( y < topY ) { topY = y; topId = id; }
        }
      } );
      // If nothing visible (scrolled past), find the last anchor above viewport
      if ( !topId ) {
        var best = null, bestBottom = -Infinity;
        anchors.forEach( function ( span ) {
          var r = span.getBoundingClientRect();
          if ( r.bottom < 80 && r.bottom > bestBottom ) {
            bestBottom = r.bottom;
            best = span.id;
          }
        } );
        topId = best;
       }
       }
      return best;
    }


    var _scrollRaf = null;
       setTocActive( topId );
    function onScroll() {
    }, { rootMargin: '-60px 0px -70% 0px', threshold: 0 } );
       if ( _scrollRaf ) return;
      _scrollRaf = requestAnimationFrame( function () {
        _scrollRaf = null;
        setTocActive( findActiveAnchor() );
      } );
    }


     window.addEventListener( 'scroll', onScroll, { passive: true } );
     anchors.forEach( function ( span ) { observer.observe( span ); } );
    // Also run once on load so initial position is highlighted
    setTimeout( function () { setTocActive( findActiveAnchor() ); }, 200 );
   }
   }


Line 976: Line 986:
     wireUllekhaLinks();
     wireUllekhaLinks();
   }
   }
}() );
// ── Special pages: remove MW branding + wire "Forgot password" ───────
// Runs on Special:UserLogin, Special:CreateAccount, Special:UserLogout
// Hides all elements that reveal the site is built on MediaWiki.
( function () {
  var ns = window.mw && mw.config.get( 'wgNamespaceNumber' );
  if ( ns !== -1 ) return;  // -1 = Special namespace
  var specialPage = ( window.mw && mw.config.get( 'wgCanonicalSpecialPageName' ) ) || '';
  var isLogin    = specialPage === 'Userlogin';
  var isCreate  = specialPage === 'CreateAccount';
  var isLogout  = specialPage === 'UserLogout';
  var isPwReset  = specialPage === 'PasswordReset';
  function hideEl( sel ) {
    document.querySelectorAll( sel ).forEach( function ( el ) {
      el.style.setProperty( 'display', 'none', 'important' );
    } );
  }
  function cleanSpecialPage() {
    // ── Always: remove "Powered by MediaWiki" and footer ─────────────
    hideEl( '#footer, .mw-footer, #footer-icons, #footer-places' );
    hideEl( 'a[href*="mediawiki.org"], img[alt*="MediaWiki"]' );
    hideEl( '#mw-panel, .vector-sidebar, .vector-sidebar-container' );
    if ( isLogin ) {
      // "Help with logging in" → external MW help link
      hideEl( '.mw-userlogin-help' );
      // "Don't have an account?" CTA block + avatar
      hideEl( '#mw-createaccount-cta' );
      hideEl( '.mw-createacct-benefits-container' );
      // "Forgot your password?" — replace href with mailto
      document.querySelectorAll( 'a[href*="PasswordReset"], .mw-userlogin-forgotpassword a' )
        .forEach( function ( a ) {
          a.href = 'mailto:feedback@anandamakaranda.in?subject=Password%20Reset%20Request';
          a.textContent = 'Forgot your password?';
        } );
    }
    if ( isCreate ) {
      hideEl( '.mw-createacct-benefits-container' );
      hideEl( '.mw-createacct-help' );
      // Replace any MW-branded heading
      var h1 = document.querySelector( '#firstHeading, h1.firstHeading' );
      if ( h1 ) h1.style.display = 'none';
    }
  }
  if ( document.readyState === 'loading' ) {
    document.addEventListener( 'DOMContentLoaded', cleanSpecialPage );
  } else {
    cleanSpecialPage();
  }
  // Re-run after a short delay in case Vector injects elements dynamically
  setTimeout( cleanSpecialPage, 500 );
}() );
}() );