MediaWiki:Timeless.js

From Game Wiki - VortanMU
Revision as of 05:57, 16 January 2026 by Admin (talk | contribs)

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.
/* ==============================
   VortanMU - Timeless sidebar fix
   Purpose:
   1) Remove legacy "MEGAMENU" DOM mutations (ul.submenu + display:none on original lists)
   2) Make left portlets collapsible (modern button-like headers)

   Paste this into: MediaWiki:Timeless.js
   ============================== */

(function () {
  'use strict';

  function qsa(root, sel) {
    return Array.prototype.slice.call((root || document).querySelectorAll(sel));
  }

  function removeLegacySubmenus(portlet) {
    // remove any injected submenu lists
    qsa(portlet, 'ul.submenu').forEach(function (ul) { ul.remove(); });

    // re-show the original list if a legacy script hid it
    var body = portlet.querySelector('.mw-portlet-body');
    if (!body) return;

    var ul = body.querySelector('ul');
    if (!ul) return;

    // clear inline styles like: style="display:none"
    ul.style.display = '';
    ul.hidden = false;
  }

  function ensureHeaderIsToggle(portlet) {
    var header = portlet.querySelector('h3');
    var body = portlet.querySelector('.mw-portlet-body');
    if (!header || !body) return;

    if (!header.classList.contains('vm-portlet__header')) {
      header.classList.add('vm-portlet__header');
      header.setAttribute('tabindex', '0');
      header.setAttribute('role', 'button');
      header.setAttribute('aria-expanded', 'false');

      var onToggle = function () {
        var isOpen = portlet.classList.toggle('is-open');
        header.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
      };

      header.addEventListener('click', onToggle);
      header.addEventListener('keydown', function (e) {
        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          onToggle();
        }
      });
    }
  }

  function normalizeLeftSidebar() {
    var nav = document.getElementById('mw-site-navigation');
    if (!nav) return;

    nav.classList.add('vm-nav');

    var portlets = qsa(nav, '.sidebar-inner .mw-portlet[role="navigation"]');
    portlets.forEach(function (p, idx) {
      p.classList.add('vm-portlet');
      removeLegacySubmenus(p);
      ensureHeaderIsToggle(p);

      // default: open first group only (can change to open all)
      if (idx === 0) p.classList.add('is-open');
    });

    // if some other script tries to inject mega-menu again after load, kill it
    var inner = nav.querySelector('.sidebar-inner');
    if (!inner) return;

    if (!inner.__vmObserver) {
      var obs = new MutationObserver(function () {
        var injected = inner.querySelector('ul.submenu');
        if (injected) {
          qsa(inner, '.mw-portlet').forEach(function (p) {
            removeLegacySubmenus(p);
          });
        }
      });
      obs.observe(inner, { childList: true, subtree: true });
      inner.__vmObserver = obs;
    }
  }

  function runSoon() {
    normalizeLeftSidebar();
    setTimeout(normalizeLeftSidebar, 250);
    setTimeout(normalizeLeftSidebar, 1000);
  }

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