Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 16:34, 11 April 2026 by Buildababe (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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.
// Adds a search box that filters category members in real time
if (document.querySelector('.mw-category')) {
  const input = document.createElement('input');
  input.placeholder = 'Filter pages...';
  input.style.cssText = `
    display: block; margin: 12px 0; padding: 8px 16px;
    border: 2px solid #b3e5fc; border-radius: 20px;
    font-family: Nunito, sans-serif; font-size: 1em; width: 300px;
  `;
  document.querySelector('.mw-category').before(input);
  input.addEventListener('input', () => {
    document.querySelectorAll('.mw-category li').forEach(li => {
      li.style.display = li.textContent.toLowerCase()
        .includes(input.value.toLowerCase()) ? '' : 'none';
    });
  });
}


/* ============================================================
   WIKI COMMON.JS — Bundled Scripts
   Paste into Special:EditPage/MediaWiki:Common.js
   ============================================================ */

( function () {
  'use strict';

  /* ----------------------------------------------------------
     1. RANDOM WELCOME MESSAGE on the main page
     ---------------------------------------------------------- */
  var greetings = [
    "Welcome to the show! 🎪",
    "Step right up! 🎠",
    "The circus is in town! 🎡",
    "Tonight's performance begins now! 🎭",
  ];
  var subtitleEl = document.querySelector('.circus-subtitle');
  if (subtitleEl) {
    subtitleEl.textContent = greetings[Math.floor(Math.random() * greetings.length)];
  }


  /* ----------------------------------------------------------
     2. CARDS CYCLE THROUGH COLORS on hover
     ---------------------------------------------------------- */
  var cardColors = ['#29b6f6','#f06292','#ab47bc','#66bb6a','#ffa726'];
  document.querySelectorAll('.circus-card').forEach(function (card) {
    card.addEventListener('mouseenter', function () {
      var c = cardColors[Math.floor(Math.random() * cardColors.length)];
      card.style.borderColor = c;
      var icon = card.querySelector('.circus-card-icon');
      if (icon) icon.style.color = c;
    });
    card.addEventListener('mouseleave', function () {
      card.style.borderColor = '';
      var icon = card.querySelector('.circus-card-icon');
      if (icon) icon.style.color = '';
    });
  });


  /* ----------------------------------------------------------
     3. LOGO SPIN on click
     ---------------------------------------------------------- */
  var logo = document.querySelector('.circus-logo-inner');
  if (logo) {
    logo.style.transition = 'transform 0.6s cubic-bezier(0.34,1.56,0.64,1)';
    logo.style.cursor = 'pointer';
    logo.addEventListener('click', function () {
      logo.style.transform = 'rotate(360deg) scale(1.2)';
      setTimeout(function () { logo.style.transform = ''; }, 600);
    });
  }


  /* ----------------------------------------------------------
     4. TYPEWRITER EFFECT on wiki subtitle
     ---------------------------------------------------------- */
  var typeEl = document.querySelector('.circus-subtitle');
  if (typeEl) {
    var fullText = typeEl.textContent;
    typeEl.textContent = '';
    var i = 0;
    var type = function () {
      if (i < fullText.length) {
        typeEl.textContent += fullText[i++];
        setTimeout(type, 40);
      }
    };
    type();
  }


  /* ----------------------------------------------------------
     5. DARK MODE TOGGLE button (bottom-right)
     ---------------------------------------------------------- */
  var darkBtn = document.createElement('button');
  darkBtn.title = 'Toggle dark mode';
  darkBtn.style.cssText = [
    'position:fixed','top:90px','right:16px',
    'width:40px','height:40px','border-radius:50%',
    'border:2px solid #b3e5fc','background:#f0f8ff',
    'font-size:18px','cursor:pointer','z-index:9999',
    'display:flex','align-items:center','justify-content:center'
  ].join(';');
  document.body.appendChild(darkBtn);

  var darkCSS = [
    'html,body,#content,.mw-body,.mw-page-container,',
    '#mw-panel,.vector-menu-portal,#mw-head{',
    'background-color:#0d1b2a!important;color:#cde8f6!important}',
    '.circus-card{background:#122336!important;border-color:#1e4060!important}',
    '.circus-title{color:#4fc3f7!important}',
    'a{color:#4fc3f7!important}'
  ].join('');
  var darkStyle = document.createElement('style');
  document.head.appendChild(darkStyle);

  function applyDark(on) {
    darkStyle.textContent = on ? darkCSS : '';
    darkBtn.textContent = on ? '☀️' : '🌙';
  }

  darkBtn.addEventListener('click', function () {
    var isDark = localStorage.getItem('wikiDarkMode') === '1';
    localStorage.setItem('wikiDarkMode', isDark ? '0' : '1');
    applyDark(!isDark);
  });

  applyDark(localStorage.getItem('wikiDarkMode') === '1');


  /* ----------------------------------------------------------
     6. WORD COUNT on article pages
     ---------------------------------------------------------- */
  var contentArea = document.querySelector('#mw-content-text');
  var isEditing = document.querySelector('.action-edit, .action-submit');
  if (contentArea && !isEditing) {
    var words = contentArea.innerText.trim().split(/\s+/).length;
    var wordBar = document.createElement('div');
    wordBar.style.cssText = 'font-family:Nunito,sans-serif;font-size:0.85em;color:#4a7a9e;margin-bottom:12px;';
    wordBar.textContent = '📄 ' + words.toLocaleString() + ' words';
    contentArea.prepend(wordBar);
  }


  /* ----------------------------------------------------------
     7. "LAST EDITED X AGO" in the footer
     ---------------------------------------------------------- */
  var lastMod = document.querySelector('#footer-info-lastmod');
  if (lastMod) {
    var match = lastMod.textContent.match(/(\d{1,2} \w+ \d{4})/);
    if (match) {
      var edited = new Date(match[1]);
      var mins = Math.floor((Date.now() - edited) / 60000);
      var ago = mins < 60
        ? mins + ' minutes ago'
        : mins < 1440
          ? Math.floor(mins / 60) + ' hours ago'
          : Math.floor(mins / 1440) + ' days ago';
      lastMod.textContent += ' (' + ago + ')';
    }
  }


  /* ----------------------------------------------------------
     8. HIGHLIGHT RED LINKS with a tooltip
     ---------------------------------------------------------- */
  document.querySelectorAll('a.new').forEach(function (link) {
    link.title = '⚠️ This page does not exist yet — click to create it!';
    link.style.cssText = 'background:#fff0f3;border-radius:4px;padding:1px 4px;text-decoration:none!important;';
  });


  /* ----------------------------------------------------------
     9. COPY BUTTON on code blocks
     ---------------------------------------------------------- */
  document.querySelectorAll('pre').forEach(function (pre) {
    var copyBtn = document.createElement('button');
    copyBtn.textContent = 'Copy';
    copyBtn.style.cssText = [
      'float:right','padding:2px 10px','font-size:0.8em',
      'border:2px solid #b3e5fc','border-radius:10px',
      'background:#f0f8ff','cursor:pointer',
      'font-family:Nunito,sans-serif'
    ].join(';');
    copyBtn.addEventListener('click', function () {
      navigator.clipboard.writeText(pre.innerText).then(function () {
        copyBtn.textContent = 'Copied!';
        setTimeout(function () { copyBtn.textContent = 'Copy'; }, 2000);
      });
    });
    pre.prepend(copyBtn);
  });


  /* ----------------------------------------------------------
     10. PRESS "/" TO FOCUS SEARCH
     ---------------------------------------------------------- */
  document.addEventListener('keydown', function (e) {
    var tag = document.activeElement.tagName;
    if (e.key === '/' && tag !== 'INPUT' && tag !== 'TEXTAREA') {
      e.preventDefault();
      var searchBox = document.querySelector('#searchInput, .vector-search-box input');
      if (searchBox) searchBox.focus();
    }
  });


  /* ----------------------------------------------------------
     11. STICKY TOC — highlights current section while scrolling
     ---------------------------------------------------------- */
  var toc = document.querySelector('#toc');
  var headings = document.querySelectorAll('h2, h3');
  if (toc && headings.length) {
    window.addEventListener('scroll', function () {
      var current = '';
      headings.forEach(function (h) {
        if (window.scrollY >= h.offsetTop - 100) current = h.id;
      });
      toc.querySelectorAll('a').forEach(function (a) {
        var active = a.href.includes(current) && current !== '';
        a.style.color = active ? '#0288d1' : '';
        a.style.fontWeight = active ? '900' : '';
      });
    });
  }


  /* ----------------------------------------------------------
     12. RANDOM ARTICLE BUTTON on main page
     ---------------------------------------------------------- */
  var heroEl = document.querySelector('.circus-hero');
  var isMainPage = document.title.toLowerCase().includes('main');
  if (heroEl && isMainPage) {
    var randBtn = document.createElement('a');
    randBtn.href = '/wiki/Special:Random';
    randBtn.textContent = '🎲 Take me somewhere random!';
    randBtn.style.cssText = [
      'display:inline-block','margin-top:10px',
      'padding:10px 24px','border-radius:24px',
      'background:#29b6f6','color:white!important',
      'font-family:Nunito,sans-serif','font-weight:700',
      'font-size:1em','text-decoration:none!important',
      'transition:transform 0.2s'
    ].join(';');
    randBtn.addEventListener('mouseenter', function () { randBtn.style.transform = 'scale(1.05)'; });
    randBtn.addEventListener('mouseleave', function () { randBtn.style.transform = ''; });
    heroEl.appendChild(randBtn);
  }


  /* ----------------------------------------------------------
     13. COLOR-CODED CATEGORY TAGS
     ---------------------------------------------------------- */
  var catPalette = [
    '#29b6f6','#f06292','#ab47bc','#66bb6a',
    '#ffa726','#ef5350','#26c6da','#d4e157'
  ];
  document.querySelectorAll('#catlinks a').forEach(function (a) {
    var idx = a.textContent.charCodeAt(0) % catPalette.length;
    var c = catPalette[idx];
    a.style.cssText = [
      'background:' + c + '22',
      'color:' + c,
      'border:1.5px solid ' + c + '66',
      'border-radius:12px',
      'padding:2px 10px',
      'margin:2px',
      'display:inline-block',
      'font-weight:700',
      'text-decoration:none!important'
    ].join(';');
  });


  /* ----------------------------------------------------------
     14. LIVE SEARCH FILTER on category pages
     ---------------------------------------------------------- */
  var catSection = document.querySelector('.mw-category');
  if (catSection) {
    var filterInput = document.createElement('input');
    filterInput.placeholder = '🔍 Filter pages...';
    filterInput.style.cssText = [
      'display:block','margin:12px 0','padding:8px 16px',
      'border:2px solid #b3e5fc','border-radius:20px',
      'font-family:Nunito,sans-serif','font-size:1em','width:300px'
    ].join(';');
    catSection.before(filterInput);
    filterInput.addEventListener('input', function () {
      var val = filterInput.value.toLowerCase();
      document.querySelectorAll('.mw-category li').forEach(function (li) {
        li.style.display = li.textContent.toLowerCase().includes(val) ? '' : 'none';
      });
    });
  }

}() );



// Animate rainbow portrait rings
mw.hook('wikipage.content').add(function() {
  document.querySelectorAll('[data-portrait-border="rainbow"]').forEach(function(el) {
    el.classList.add('pb-rainbow-ring');
  });
});