Zum Inhalt springen


MediaWiki:Common.js: Unterschied zwischen den Versionen

Aus Firestone Idle RPG Wiki
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 1: Zeile 1:
/* Das folgende JavaScript wird für alle Benutzer geladen. */
/* Das folgende JavaScript wird für alle Benutzer geladen. */
/*
/* ==== Sidebar: klickbare Kopfzeile + Gruppen mit Auf/Zu (Vector-2022) ==== */
/* Sidebar: Heading als Link + Untermenüs (#group:) – Vector 2022 */
(function () {
mw.loader.using( ['mediawiki.util'] ).then(function () {
   if (mw.config.get('skin') !== 'vector-2022') return;
   if ( mw.config.get('skin') !== 'vector-2022' ) return;


   var panel = document.getElementById('mw-panel');
   function extractDirective(a) {
  if (!panel) return;
    if (!a) return null;
    var href = a.getAttribute('href') || '';
    // Hash robust ermitteln (funktioniert auch bei /wiki/…#group:…)
    try { href = new URL(href, location.href).hash || ''; } catch (e) {}
    var s = href.trim().toLowerCase();
    if (s.indexOf('#group:') >= 0) return { kind: 'group', value: decodeURIComponent(s.split('#group:').pop()) };
    if (s.indexOf('#link:')  >= 0) return { kind: 'link',  value: decodeURIComponent(s.split('#link:').pop()) };
    return null;
  }


function getDirective(a, key) {
  function makeHead(li, keepLink) {
  if (!a) return null;
    // Kopf: [Pfeil] [Link- oder Textlabel]
  var want = '#' + key.toLowerCase() + ':'; // z.B. "#group:" oder "#link:"
    var a = li.querySelector(':scope > a');
  var href = a.getAttribute('href') || '';
    var head = document.createElement('div');
    head.className = 'kr-head';
    var btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'kr-arrow';
    btn.setAttribute('aria-expanded', 'true');
    head.appendChild(btn);


  // 1) Normales href – Hash sauber auslesen (funktioniert auch bei /wiki/…#group:…)
    if (keepLink) {
  try {
      // klickbarer Link als Titel
    var u = new URL(href, location.href);
      head.appendChild(a);
    var hash = (u.hash || '').toLowerCase(); // inkl. führendem '#'
    } else {
    if (hash.indexOf(want) === 0) return u.hash;                             // "#group:Mana"
      // Nur Text (kein Link)
    var pos = hash.indexOf(want);
      var span = document.createElement('span');
    if (pos > 0) return u.hash.slice(pos);                                   // "...#group:Mana"
      span.className = 'kr-title';
  } catch (e) {
      span.textContent = (a && a.textContent) || '';
    // Falls es keine gültige URL ist, fallback auf einfache Stringsuche
      head.appendChild(span);
     var low = href.toLowerCase();
      if (a) a.remove(); // Link entfernen
    if (low.indexOf(want) === 0) return href;
    }
    var pos2 = low.indexOf(want);
 
     if (pos2 > 0) return href.slice(pos2);
     li.insertBefore(head, li.firstChild);
     return head;
   }
   }


   // 2) data-href oder title tragen manchmal die Direktive
   function buildGroups(ul) {
  var dh = (a.getAttribute('data-href') || '').toLowerCase();
    var lis = Array.from(ul.querySelectorAll(':scope > li.mw-list-item'));
  if (dh.indexOf(want) === 0) return a.getAttribute('data-href');
    var currentGroup = null;


  var tt = (a.getAttribute('title') || '').toLowerCase();
    lis.forEach(function (li) {
  if (tt.indexOf(want) === 0) return a.getAttribute('title');
      var a = li.querySelector(':scope > a');
      var d = extractDirective(a);


  // 3) Notfalls steht die Direktive als sichtbarer Text im Link
      if (d && d.kind === 'group') {
  var tx = (a.textContent || '').trim();
        // Gruppen-Header (ohne Link), eigener Container + Unterliste
  if (tx.toLowerCase().indexOf(want) === 0) return tx;
        li.classList.add('kr-group');
        makeHead(li, false);
        var sub = document.createElement('ul');
        sub.className = 'kr-sub';
        li.appendChild(sub);
        currentGroup = sub;
        // Direktiven-Link ausblenden (falls noch da)
        if (a) a.removeAttribute('href');
        return;
      }


  return null;
      // Normale Elemente wandern in die aktuelle Gruppe (falls vorhanden)
}
      if (currentGroup && !(d && (d.kind === 'group' || d.kind === 'link'))) {
        currentGroup.appendChild(li);
      }
    });


  function directiveTarget(directiveValue) {
     // Auf/Zu: Delegation auf den UL
     // extrahiert den Teil nach "link:" bzw. "group:"
     ul.addEventListener('click', function (e) {
     var v = decodeURIComponent(directiveValue.replace(/^.*?(#|%23)(link|group):/, ''));
      var t = e.target;
    return v.replace(/^\s+|\s+$/g, '');
      if (t.classList.contains('kr-arrow')) {
  }
        var li = t.closest('li.kr-group, li.kr-top');
  function wikiHref(title) { return mw.util.getUrl(title); }
        if (li) {
 
          var collapsed = li.classList.toggle('is-collapsed');
  function makeToggleBtn(expanded) {
          t.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
    var b = document.createElement('button');
        }
    b.type = 'button';
      }
    b.className = 'kr-sb-toggle';
    b.setAttribute('aria-expanded', expanded ? 'true' : 'false');
    b.setAttribute('title', expanded ? 'Zuklappen' : 'Aufklappen');
    b.addEventListener('click', function (e) {
      e.preventDefault();
      var wrap = b.closest('.kr-sb-wrap, .kr-sb-group');
      var isCollapsed = wrap.classList.toggle('is-collapsed');
      b.setAttribute('aria-expanded', isCollapsed ? 'false' : 'true');
     });
     });
    return b;
   }
   }


   panel.querySelectorAll('.vector-menu-portal').forEach(function (portlet) {
   function buildPortlets(root) {
    var heading = portlet.querySelector('.vector-menu-heading');
    // Alle Portlet-Listen (Vector 2022)
    var list    = portlet.querySelector('.vector-menu-content-list');
    var lists = root.querySelectorAll('#mw-panel .vector-menu-content-list');
    if (!heading || !list) return;
    lists.forEach(function (ul) {
      // 1. Kopf-Link (#link:...) als „Top“-Kopf mit Auf/Zu über den Rest
      var items = Array.from(ul.querySelectorAll(':scope > li.mw-list-item'));
      var topIdx = items.findIndex(function (li) {
        var a = li.querySelector(':scope > a');
        var d = extractDirective(a);
        return d && d.kind === 'link';
      });


    // 1) #link:… → Überschrift klickbar machen
       if (topIdx >= 0) {
    var linkDirectiveAnchor = Array.from(list.querySelectorAll('li > a')).find(function (a) {
        var top = items[topIdx];
       return !!getDirective(a, 'link');
        top.classList.add('kr-top');
    });
        makeHead(top, true);
    if (linkDirectiveAnchor) {
      var dir = getDirective(linkDirectiveAnchor, 'link');
      var target = directiveTarget(dir) || 'Hauptseite';
      var labelEl = heading.querySelector('.vector-menu-heading-label') || heading;
      var labelText = labelEl.textContent.trim() || target;
      var link = document.createElement('a');
      link.className = 'kr-sb-heading-link';
      link.href = wikiHref(target);
      link.textContent = labelText;
      labelEl.textContent = '';
      labelEl.appendChild(link);
      // Direktive entfernen
      linkDirectiveAnchor.closest('li').remove();
    }


    // 2) Portlet-Toggle hinzufügen (Heading bleibt Link, Pfeil klappt)
        // Unterliste unterhalb der Kopfzeile, alle nachfolgenden Elemente rein
    if (!portlet.classList.contains('kr-sb-wrap')) {
        var sub = document.createElement('ul');
      portlet.classList.add('kr-sb-wrap');
        sub.className = 'kr-sub';
      heading.appendChild( makeToggleBtn(true) );
        top.appendChild(sub);
    }


    // 3) #group:… → Untermenüs bauen
        // Alle Listeneinträge NACH dem Top-Link in die Unterliste verschieben
    var items = Array.from(list.children); // <li>…
        for (var i = topIdx + 1; i < items.length; i++) {
    for (var i = 0; i < items.length; i++) {
          sub.appendChild(items[i]);
      var li = items[i];
        }
      if (!li) continue;
      var a  = li.querySelector('a');
      if (!a) continue;
      var gdir = getDirective(a, 'group');
      if (!gdir) continue;


      var groupLabel = a.textContent.trim() || directiveTarget(gdir) || 'Gruppe';
        // Innerhalb der Unterliste Gruppen (#group:...) bauen
       li.textContent = '';
        buildGroups(sub);
       li.classList.add('kr-sb-group');
       } else {
        // Kein #link: – wir bauen Gruppen direkt in der Wurzel
        buildGroups(ul);
       }
    });
  }


      var header = document.createElement('div');
  function init() {
      header.className = 'kr-sb-group-header';
    var panel = document.getElementById('mw-panel');
      var titleSpan = document.createElement('span');
    if (!panel) return;
      titleSpan.className = 'kr-sb-group-title';
    panel.classList.add('kr-sb');
      titleSpan.textContent = groupLabel;
    buildPortlets(panel);
      var btn = makeToggleBtn(true);
  }
      header.appendChild(titleSpan);
      header.appendChild(btn);
      li.appendChild(header);


      var sub = document.createElement('ul');
  // Sofort & bei Ajax-Nachladungen
      sub.className = 'kr-sb-sub';
  mw.hook('wikipage.content').add(init);
      while (items[i+1] && !getDirective((items[i+1].querySelector('a')||{}), 'group')) {
  init();
        sub.appendChild(items[i+1]);
})();
        items[i+1] = null; // verbraucht
        i++;
      }
      li.appendChild(sub);
    }
  });
});

Version vom 10. Oktober 2025, 13:29 Uhr

/* Das folgende JavaScript wird für alle Benutzer geladen. */
/* ==== Sidebar: klickbare Kopfzeile + Gruppen mit Auf/Zu (Vector-2022) ==== */
(function () {
  if (mw.config.get('skin') !== 'vector-2022') return;

  function extractDirective(a) {
    if (!a) return null;
    var href = a.getAttribute('href') || '';
    // Hash robust ermitteln (funktioniert auch bei /wiki/…#group:…)
    try { href = new URL(href, location.href).hash || ''; } catch (e) {}
    var s = href.trim().toLowerCase();
    if (s.indexOf('#group:') >= 0) return { kind: 'group', value: decodeURIComponent(s.split('#group:').pop()) };
    if (s.indexOf('#link:')  >= 0) return { kind: 'link',  value: decodeURIComponent(s.split('#link:').pop())  };
    return null;
  }

  function makeHead(li, keepLink) {
    // Kopf: [Pfeil] [Link- oder Textlabel]
    var a = li.querySelector(':scope > a');
    var head = document.createElement('div');
    head.className = 'kr-head';
    var btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'kr-arrow';
    btn.setAttribute('aria-expanded', 'true');
    head.appendChild(btn);

    if (keepLink) {
      // klickbarer Link als Titel
      head.appendChild(a);
    } else {
      // Nur Text (kein Link)
      var span = document.createElement('span');
      span.className = 'kr-title';
      span.textContent = (a && a.textContent) || '';
      head.appendChild(span);
      if (a) a.remove(); // Link entfernen
    }

    li.insertBefore(head, li.firstChild);
    return head;
  }

  function buildGroups(ul) {
    var lis = Array.from(ul.querySelectorAll(':scope > li.mw-list-item'));
    var currentGroup = null;

    lis.forEach(function (li) {
      var a = li.querySelector(':scope > a');
      var d = extractDirective(a);

      if (d && d.kind === 'group') {
        // Gruppen-Header (ohne Link), eigener Container + Unterliste
        li.classList.add('kr-group');
        makeHead(li, false);
        var sub = document.createElement('ul');
        sub.className = 'kr-sub';
        li.appendChild(sub);
        currentGroup = sub;
        // Direktiven-Link ausblenden (falls noch da)
        if (a) a.removeAttribute('href');
        return;
      }

      // Normale Elemente wandern in die aktuelle Gruppe (falls vorhanden)
      if (currentGroup && !(d && (d.kind === 'group' || d.kind === 'link'))) {
        currentGroup.appendChild(li);
      }
    });

    // Auf/Zu: Delegation auf den UL
    ul.addEventListener('click', function (e) {
      var t = e.target;
      if (t.classList.contains('kr-arrow')) {
        var li = t.closest('li.kr-group, li.kr-top');
        if (li) {
          var collapsed = li.classList.toggle('is-collapsed');
          t.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
        }
      }
    });
  }

  function buildPortlets(root) {
    // Alle Portlet-Listen (Vector 2022)
    var lists = root.querySelectorAll('#mw-panel .vector-menu-content-list');
    lists.forEach(function (ul) {
      // 1. Kopf-Link (#link:...) als „Top“-Kopf mit Auf/Zu über den Rest
      var items = Array.from(ul.querySelectorAll(':scope > li.mw-list-item'));
      var topIdx = items.findIndex(function (li) {
        var a = li.querySelector(':scope > a');
        var d = extractDirective(a);
        return d && d.kind === 'link';
      });

      if (topIdx >= 0) {
        var top = items[topIdx];
        top.classList.add('kr-top');
        makeHead(top, true);

        // Unterliste unterhalb der Kopfzeile, alle nachfolgenden Elemente rein
        var sub = document.createElement('ul');
        sub.className = 'kr-sub';
        top.appendChild(sub);

        // Alle Listeneinträge NACH dem Top-Link in die Unterliste verschieben
        for (var i = topIdx + 1; i < items.length; i++) {
          sub.appendChild(items[i]);
        }

        // Innerhalb der Unterliste Gruppen (#group:...) bauen
        buildGroups(sub);
      } else {
        // Kein #link: – wir bauen Gruppen direkt in der Wurzel
        buildGroups(ul);
      }
    });
  }

  function init() {
    var panel = document.getElementById('mw-panel');
    if (!panel) return;
    panel.classList.add('kr-sb');
    buildPortlets(panel);
  }

  // Sofort & bei Ajax-Nachladungen
  mw.hook('wikipage.content').add(init);
  init();
})();