MediaWiki:Common.js: Difference between revisions

From Sanatan Hindu Dharma
No edit summary
No edit summary
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* === Move Category Links Above Footer === */
 
/*
 
$(document).ready(function () {
$(document).ready(function () {
   var catlinks = $('#catlinks');
   var catlinks = $('#catlinks');
Line 17: Line 14:
});
});


 
/* === Floating Upload Button === */
 
 
 
$(document).ready(function() {
$(document).ready(function() {
    if (mw.config.get('wgNamespaceNumber') >= 0) { // Only show on normal pages
  if (mw.config.get('wgNamespaceNumber') >= 0) { // Only show on normal pages
        var pageName = mw.config.get('wgPageName');
    var pageName = mw.config.get('wgPageName');
        var uploadUrl = mw.util.getUrl('Form:UploadVideo', { 'page': pageName });
    var uploadUrl = mw.util.getUrl('Form:UploadVideo', { 'page': pageName });


        $('<div style="position:fixed; bottom:20px; right:20px; background:#007bff; color:white; padding:10px; border-radius:5px; cursor:pointer; font-weight:bold;">Upload a Video</div>')
    $('<div style="position:fixed; bottom:20px; right:20px; background:#007bff; color:white; padding:10px; border-radius:5px; cursor:pointer; font-weight:bold; z-index:9999;">Upload a Video</div>')
        .click(function() {
      .click(function() {
            window.location.href = uploadUrl;
        window.location.href = uploadUrl;
        }).appendTo('body');
      }).appendTo('body');
    }
  }
});
});
*/
/* Functions of Slider One */


/* === Responsive Slider (mw-slider) === */
(function () {
(function () {
   function initSliders() {
   function initSliders() {
     var sliders = document.querySelectorAll('.mw-slider');
     var sliders = document.querySelectorAll('.mw-slider');
     sliders.forEach(function (slider) {
     sliders.forEach(function (slider) {
      // Avoid double-init
       if (slider._mwSliderInited) return;
       if (slider._mwSliderInited) return;
       slider._mwSliderInited = true;
       slider._mwSliderInited = true;


      var viewport = slider.querySelector('.mw-slider-viewport');
       var track = slider.querySelector('.mw-slider-track');
       var track = slider.querySelector('.mw-slider-track');
       var items = Array.from(slider.querySelectorAll('.mw-slider-item'));
       var items = Array.from(slider.querySelectorAll('.mw-slider-item'));
       var btnPrev = slider.querySelector('.mw-slider-btn.prev');
       var btnPrev = slider.querySelector('.mw-slider-btn.prev');
       var btnNext = slider.querySelector('.mw-slider-btn.next');
       var btnNext = slider.querySelector('.mw-slider-btn.next');
       var currentIndex = 0;
       var currentIndex = 0;
      var itemsToShow = getItemsToShow();
      var gap = parseFloat(getComputedStyle(track).columnGap || getComputedStyle(track).gap || 16);


       function getItemsToShow() {
       function getItemsToShow() {
Line 61: Line 48:
       }
       }


       function updateSizes() {
       function update() {
         itemsToShow = getItemsToShow();
         var itemsToShow = getItemsToShow();
        // compute single item width including gap
        if (!items[0]) return;
         var itemRect = items[0].getBoundingClientRect();
         var itemRect = items[0].getBoundingClientRect();
         gap = parseFloat(getComputedStyle(track).columnGap || getComputedStyle(track).gap || 16);
         var gap = parseFloat(getComputedStyle(track).gap || 16);
         var single = itemRect.width + gap;
         var translateX = -currentIndex * (itemRect.width + gap);
        // ensure currentIndex in range
        var maxIndex = Math.max(0, items.length - itemsToShow);
        currentIndex = Math.min(currentIndex, maxIndex);
        // apply transform
        var translateX = -currentIndex * single;
         track.style.transform = 'translateX(' + translateX + 'px)';
         track.style.transform = 'translateX(' + translateX + 'px)';
         updateButtons();
         btnPrev.disabled = currentIndex <= 0;
      }
         btnNext.disabled = currentIndex >= items.length - itemsToShow;
 
      function updateButtons() {
        var maxIndex = Math.max(0, items.length - itemsToShow);
        if (btnPrev) btnPrev.disabled = currentIndex <= 0;
         if (btnNext) btnNext.disabled = currentIndex >= maxIndex;
       }
       }


       function gotoIndex(index) {
       btnPrev && btnPrev.addEventListener('click', function() {
        var maxIndex = Math.max(0, items.length - itemsToShow);
         currentIndex = Math.max(0, currentIndex - 1);
        currentIndex = Math.max(0, Math.min(maxIndex, index));
         update();
        updateSizes();
      }
 
      if (btnPrev) btnPrev.addEventListener('click', function () {
         gotoIndex(currentIndex - 1);
      });
      if (btnNext) btnNext.addEventListener('click', function () {
        gotoIndex(currentIndex + 1);
      });
 
      // Keyboard support
      slider.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowLeft') gotoIndex(currentIndex - 1);
         if (e.key === 'ArrowRight') gotoIndex(currentIndex + 1);
       });
       });


       // Resize handling
       btnNext && btnNext.addEventListener('click', function() {
      var resizeTimeout;
         currentIndex = Math.min(items.length - getItemsToShow(), currentIndex + 1);
      window.addEventListener('resize', function () {
         update();
         clearTimeout(resizeTimeout);
         resizeTimeout = setTimeout(updateSizes, 120);
       });
       });


       // Touch / drag support
       window.addEventListener('resize', update);
      (function () {
       setTimeout(update, 200);
        var startX = 0;
        var currentTranslate = 0;
        var dragging = false;
        var pointerId = null;
 
        function pointerDown(e) {
          if (e.pointerType === 'mouse' && e.button !== 0) return;
          dragging = true;
          pointerId = e.pointerId;
          startX = e.clientX;
          track.style.transition = 'none';
          track.setPointerCapture && track.setPointerCapture(pointerId);
        }
 
        function pointerMove(e) {
          if (!dragging || e.pointerId !== pointerId) return;
          var dx = e.clientX - startX;
          var itemRect = items[0] && items[0].getBoundingClientRect();
          var single = itemRect ? (itemRect.width + gap) : 0;
          var baseTranslate = -currentIndex * single;
          track.style.transform = 'translateX(' + (baseTranslate + dx) + 'px)';
        }
 
        function pointerUp(e) {
          if (!dragging || e.pointerId !== pointerId) return;
          dragging = false;
          track.style.transition = '';
          var dx = e.clientX - startX;
          var threshold = Math.max(40, (items[0] ? items[0].getBoundingClientRect().width : 200) * 0.15);
          if (dx > threshold) {
            gotoIndex(currentIndex - 1);
          } else if (dx < -threshold) {
            gotoIndex(currentIndex + 1);
          } else {
            updateSizes();
          }
          try { track.releasePointerCapture(pointerId); } catch (err) {}
          pointerId = null;
        }
 
        track.addEventListener('pointerdown', pointerDown);
        window.addEventListener('pointermove', pointerMove);
        window.addEventListener('pointerup', pointerUp);
        track.addEventListener('pointercancel', pointerUp);
      })();
 
      // Initial sizes
       setTimeout(updateSizes, 60);
     });
     });
   }
   }


  // init on DOM ready
   if (document.readyState === 'loading') {
   if (document.readyState === 'loading') {
     document.addEventListener('DOMContentLoaded', initSliders);
     document.addEventListener('DOMContentLoaded', initSliders);
Line 168: Line 78:
     initSliders();
     initSliders();
   }
   }
 
   if (window.mw && mw.hook) mw.hook('wikipage.content').add(initSliders);
  // If new content is loaded via AJAX on the wiki, re-init
   if (window.mw && mw.hook) {
    mw.hook('wikipage.content').add(initSliders);
  }
})();
})();


/* Full width Slider */
/* === Full Width Slider (mw-fullslider) === */
(function () {
(function () {
   function initFullSliders() {
   function initFullSliders() {
Line 187: Line 93:
       var btnPrev = slider.querySelector('.mw-fullslider-btn.prev');
       var btnPrev = slider.querySelector('.mw-fullslider-btn.prev');
       var btnNext = slider.querySelector('.mw-fullslider-btn.next');
       var btnNext = slider.querySelector('.mw-fullslider-btn.next');
      var dots = Array.from(slider.querySelectorAll('.mw-fullslider-dots .dot'));
       var current = 0;
       var current = 0;
      var slideCount = slides.length;


       function goTo(index, animate) {
       function goTo(index) {
         current = (index % slideCount + slideCount) % slideCount;
         current = (index + slides.length) % slides.length;
         var x = -current * slider.clientWidth;
         var x = -current * slider.clientWidth;
        if (animate === false) track.style.transition = 'none';
        else track.style.transition = '';
         track.style.transform = 'translateX(' + x + 'px)';
         track.style.transform = 'translateX(' + x + 'px)';
        updateControls();
        if (animate === false) {
          // force reflow then restore
          void track.offsetWidth;
          track.style.transition = '';
        }
      }
      function updateControls() {
        if (btnPrev) btnPrev.disabled = false;
        if (btnNext) btnNext.disabled = false;
        // update dots
        dots.forEach(function (d) {
          d.classList.toggle('active', +d.getAttribute('data-index') === current);
          d.setAttribute('aria-pressed', (+d.getAttribute('data-index') === current).toString());
        });
       }
       }


       if (btnPrev) btnPrev.addEventListener('click', function () { goTo(current - 1); });
       btnPrev && btnPrev.addEventListener('click', () => goTo(current - 1));
       if (btnNext) btnNext.addEventListener('click', function () { goTo(current + 1); });
       btnNext && btnNext.addEventListener('click', () => goTo(current + 1));
 
      dots.forEach(function (dot) {
        dot.addEventListener('click', function () {
          var idx = parseInt(this.getAttribute('data-index'), 10);
          goTo(idx);
        });
      });
 
      // Resize handling: ensure slide width matches viewport
      var resizeTimer;
      function onResize() {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(function () {
          // Recompute translate in case width changed
          goTo(current, false);
        }, 80);
      }
      window.addEventListener('resize', onResize);


       // Touch / drag support
       window.addEventListener('resize', () => goTo(current));
      (function () {
        var startX = 0, startTranslate = 0, dragging = false, pointerId = null;
        function down(e) {
          if (e.pointerType === 'mouse' && e.button !== 0) return;
          dragging = true;
          pointerId = e.pointerId;
          startX = e.clientX;
          var style = window.getComputedStyle(track);
          var matrix = new WebKitCSSMatrix(style.transform);
          startTranslate = matrix.m41 || 0;
          track.style.transition = 'none';
          e.target.setPointerCapture && e.target.setPointerCapture(pointerId);
        }
        function move(e) {
          if (!dragging || e.pointerId !== pointerId) return;
          var dx = e.clientX - startX;
          track.style.transform = 'translateX(' + (startTranslate + dx) + 'px)';
        }
        function up(e) {
          if (!dragging || e.pointerId !== pointerId) return;
          dragging = false;
          track.style.transition = '';
          var dx = e.clientX - startX;
          var threshold = Math.max(40, slider.clientWidth * 0.12);
          if (dx > threshold) goTo(current - 1);
          else if (dx < -threshold) goTo(current + 1);
          else goTo(current);
          try { e.target.releasePointerCapture(pointerId); } catch (err) {}
          pointerId = null;
        }
        track.addEventListener('pointerdown', down);
        window.addEventListener('pointermove', move);
        window.addEventListener('pointerup', up);
        track.addEventListener('pointercancel', up);
      })();


      // Autoplay (optional): change interval or set autoplay = false
       var autoplay = true, interval = 4500, timer;
       var autoplay = true;
       function start() {
      var autoplayInterval = 4500; // ms
      var autoplayTimer = null;
       function startAutoplay() {
         if (!autoplay) return;
         if (!autoplay) return;
         stopAutoplay();
         stop();
         autoplayTimer = setInterval(function () { goTo(current + 1); }, autoplayInterval);
         timer = setInterval(() => goTo(current + 1), interval);
      }
      function stopAutoplay() {
        if (autoplayTimer) { clearInterval(autoplayTimer); autoplayTimer = null; }
      }
      slider.addEventListener('mouseenter', stopAutoplay);
      slider.addEventListener('mouseleave', startAutoplay);
      slider.addEventListener('focusin', stopAutoplay);
      slider.addEventListener('focusout', startAutoplay);
 
      // Respect prefers-reduced-motion
      var rmq = window.matchMedia('(prefers-reduced-motion: reduce)');
      if (rmq.matches) autoplay = false;
 
      // Ensure initial sizing: make each slide exactly slider.clientWidth
      function layoutSlides() {
        var w = slider.clientWidth;
        slides.forEach(function (s) { s.style.minWidth = w + 'px'; s.style.maxWidth = w + 'px'; });
        goTo(current, false);
      }
 
      // Wait for images then layout
      function imgsReady(cb) {
        var imgs = Array.from(slider.querySelectorAll('img'));
        var rem = imgs.length;
        if (!rem) return cb();
        imgs.forEach(function (img) {
          if (img.complete) { rem--; if (!rem) cb(); }
          else {
            img.addEventListener('load', function () { rem--; if (!rem) cb(); });
            img.addEventListener('error', function () { rem--; if (!rem) cb(); });
          }
        });
       }
       }
 
       function stop() { if (timer) clearInterval(timer); }
       imgsReady(function () {
      slider.addEventListener('mouseenter', stop);
        layoutSlides();
       slider.addEventListener('mouseleave', start);
        startAutoplay();
       start();
        window.addEventListener('resize', onResize);
       });
 
       // expose for debug (optional)
      slider._goTo = goTo;
     });
     });
   }
   }
Line 329: Line 121:
   if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initFullSliders);
   if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initFullSliders);
   else initFullSliders();
   else initFullSliders();
   if (window.mw && mw.hook) mw.hook('wikipage.content').add(initFullSliders);
   if (window.mw && mw.hook) mw.hook('wikipage.content').add(initFullSliders);
})();
})();

Revision as of 11:17, 28 October 2025

/* === Move Category Links Above Footer === */
$(document).ready(function () {
  var catlinks = $('#catlinks');
  var footer = $('.mw-footer, footer, #footer'); // works with most skins
  var content = $('#bodyContent, #content, .mw-body');

  if (catlinks.length && footer.length) {
    // Move categories just before footer
    catlinks.insertBefore(footer);
  } else if (catlinks.length && content.length) {
    // Fallback: move it to the end of main content
    catlinks.appendTo(content);
  }
});

/* === Floating Upload Button === */
$(document).ready(function() {
  if (mw.config.get('wgNamespaceNumber') >= 0) { // Only show on normal pages
    var pageName = mw.config.get('wgPageName');
    var uploadUrl = mw.util.getUrl('Form:UploadVideo', { 'page': pageName });

    $('<div style="position:fixed; bottom:20px; right:20px; background:#007bff; color:white; padding:10px; border-radius:5px; cursor:pointer; font-weight:bold; z-index:9999;">Upload a Video</div>')
      .click(function() {
        window.location.href = uploadUrl;
      }).appendTo('body');
  }
});

/* === Responsive Slider (mw-slider) === */
(function () {
  function initSliders() {
    var sliders = document.querySelectorAll('.mw-slider');
    sliders.forEach(function (slider) {
      if (slider._mwSliderInited) return;
      slider._mwSliderInited = true;

      var track = slider.querySelector('.mw-slider-track');
      var items = Array.from(slider.querySelectorAll('.mw-slider-item'));
      var btnPrev = slider.querySelector('.mw-slider-btn.prev');
      var btnNext = slider.querySelector('.mw-slider-btn.next');
      var currentIndex = 0;

      function getItemsToShow() {
        var w = window.innerWidth;
        if (w <= 600) return 1;
        if (w <= 900) return 2;
        return 3;
      }

      function update() {
        var itemsToShow = getItemsToShow();
        var itemRect = items[0].getBoundingClientRect();
        var gap = parseFloat(getComputedStyle(track).gap || 16);
        var translateX = -currentIndex * (itemRect.width + gap);
        track.style.transform = 'translateX(' + translateX + 'px)';
        btnPrev.disabled = currentIndex <= 0;
        btnNext.disabled = currentIndex >= items.length - itemsToShow;
      }

      btnPrev && btnPrev.addEventListener('click', function() {
        currentIndex = Math.max(0, currentIndex - 1);
        update();
      });

      btnNext && btnNext.addEventListener('click', function() {
        currentIndex = Math.min(items.length - getItemsToShow(), currentIndex + 1);
        update();
      });

      window.addEventListener('resize', update);
      setTimeout(update, 200);
    });
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initSliders);
  } else {
    initSliders();
  }
  if (window.mw && mw.hook) mw.hook('wikipage.content').add(initSliders);
})();

/* === Full Width Slider (mw-fullslider) === */
(function () {
  function initFullSliders() {
    var sliders = document.querySelectorAll('.mw-fullslider');
    sliders.forEach(function (slider) {
      if (slider._fullSliderInit) return;
      slider._fullSliderInit = true;

      var track = slider.querySelector('.mw-fullslider-track');
      var slides = Array.from(track.children);
      var btnPrev = slider.querySelector('.mw-fullslider-btn.prev');
      var btnNext = slider.querySelector('.mw-fullslider-btn.next');
      var current = 0;

      function goTo(index) {
        current = (index + slides.length) % slides.length;
        var x = -current * slider.clientWidth;
        track.style.transform = 'translateX(' + x + 'px)';
      }

      btnPrev && btnPrev.addEventListener('click', () => goTo(current - 1));
      btnNext && btnNext.addEventListener('click', () => goTo(current + 1));

      window.addEventListener('resize', () => goTo(current));

      var autoplay = true, interval = 4500, timer;
      function start() {
        if (!autoplay) return;
        stop();
        timer = setInterval(() => goTo(current + 1), interval);
      }
      function stop() { if (timer) clearInterval(timer); }
      slider.addEventListener('mouseenter', stop);
      slider.addEventListener('mouseleave', start);
      start();
    });
  }

  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initFullSliders);
  else initFullSliders();
  if (window.mw && mw.hook) mw.hook('wikipage.content').add(initFullSliders);
})();