Zum Inhalt springen

MediaWiki:Minerva.js: Unterschied zwischen den Versionen

Aus ADOS Wiki
Keine Bearbeitungszusammenfassung
Markierungen: Mobile Bearbeitung Mobile Web-Bearbeitung Erweiterte mobile Bearbeitung
Keine Bearbeitungszusammenfassung
Markierungen: Mobile Bearbeitung Mobile Web-Bearbeitung Erweiterte mobile Bearbeitung
Zeile 5: Zeile 5:
   if (mw.config.get('skin') !== 'minerva') return;
   if (mw.config.get('skin') !== 'minerva') return;


   // ---- KONFIG: Links als [Label, Seitentitel] ----
   // --- KONFIG: Label + Seitentitel (werden mit mw.util.getUrl() sicher verlinkt)
   const LINKS = [
   const LINKS = [
     ['Hauptkategorien', null], // Header/Toggle, kein Link
     ['Hauptkategorien', null], // Header/Toggle, kein Link
Zeile 36: Zeile 36:
     const host = findMenuList();
     const host = findMenuList();
     if (!host) return false;
     if (!host) return false;
     if (document.getElementById(BLOCK_ID)) return true; // schon vorhanden
     if (document.getElementById(BLOCK_ID)) return true; // schon eingebaut


     const ul = document.createElement('ul');
    // äußerer Block
     ul.id = BLOCK_ID;
     const outer = document.createElement('ul');
     ul.className = 'toggle-list__list';
     outer.id = BLOCK_ID;
     outer.className = 'toggle-list__list';


     // Header/Toggle
     // Header mit Icon + Toggle
     const [headerLabel] = LINKS[0];
     const [headerLabel] = LINKS[0];
     const headerLi = document.createElement('li');
     const headerLi = document.createElement('li');
     headerLi.className = 'toggle-list-item';
     headerLi.className = 'toggle-list-item';
     const headerBtn = document.createElement('button');
     const headerBtn = document.createElement('button');
     headerBtn.type = 'button';
     headerBtn.type = 'button';
Zeile 53: Zeile 55:
       '<span class="minerva-icon minerva-icon--listBullet"></span>' +
       '<span class="minerva-icon minerva-icon--listBullet"></span>' +
       `<span class="toggle-list-item__label">${headerLabel}</span>`;
       `<span class="toggle-list-item__label">${headerLabel}</span>`;
     headerLi.appendChild(headerBtn);
     headerLi.appendChild(headerBtn);
     ul.appendChild(headerLi);
     outer.appendChild(headerLi);


     // Container für die eigentlichen Links (collapsible)
     // Unterpunkte-Liste (ohne Icons)
     const innerUl = document.createElement('ul');
     const inner = document.createElement('ul');
     innerUl.className = 'toggle-list__list';
     inner.className = 'toggle-list__list';
     innerUl.style.marginLeft = '12px';
     inner.style.marginLeft = '10px';


     for (let i = 1; i < LINKS.length; i++) {
     for (let i = 1; i < LINKS.length; i++) {
Zeile 69: Zeile 72:
       a.className = 'toggle-list-item__anchor';
       a.className = 'toggle-list-item__anchor';
       a.textContent = label;
       a.textContent = label;
      a.href = title ? mw.util.getUrl(title) : '#';


       if (title) {
       // KEIN Icon bei Unterpunkten
        // sichere URL auf Basis des Seitentitels (Sonderzeichen/Leerzeichen ok)
        a.href = mw.util.getUrl(title);
      } else {
        a.href = '#';
        a.setAttribute('role', 'button');
      }
 
if (i === 1) { // beim ersten Unterpunkt noch kein Icon
  const icon = document.createElement('span');
  icon.className = 'minerva-icon minerva-icon--article';
  a.prepend(icon);
}
 
       li.appendChild(a);
       li.appendChild(a);
       innerUl.appendChild(li);
       inner.appendChild(li);
     }
     }
    outer.appendChild(inner);


    ul.appendChild(innerUl);
     // Toggle-Logik
 
     // Toggle-Verhalten für Header
     headerBtn.addEventListener('click', function () {
     headerBtn.addEventListener('click', function () {
       const expanded = this.getAttribute('aria-expanded') === 'true';
       const expanded = this.getAttribute('aria-expanded') === 'true';
       this.setAttribute('aria-expanded', String(!expanded));
       this.setAttribute('aria-expanded', String(!expanded));
       innerUl.style.display = expanded ? 'none' : '';
       inner.style.display = expanded ? 'none' : '';
       try { localStorage.setItem(BLOCK_ID + ':collapsed', expanded ? '1' : '0'); } catch (e) {}
       try { localStorage.setItem(BLOCK_ID + ':collapsed', expanded ? '1' : '0'); } catch (e) {}
     });
     });
Zeile 102: Zeile 92:
       if (localStorage.getItem(BLOCK_ID + ':collapsed') === '1') {
       if (localStorage.getItem(BLOCK_ID + ':collapsed') === '1') {
         headerBtn.setAttribute('aria-expanded', 'false');
         headerBtn.setAttribute('aria-expanded', 'false');
         innerUl.style.display = 'none';
         inner.style.display = 'none';
       }
       }
     } catch (e) {}
     } catch (e) {}


     // Nach der ersten UL einfügen
     // nach der ersten vorhandenen UL einfügen (direkt unter Start/Zufällige Seite)
     const firstUl = host.querySelector('ul') || host;
     const firstUl = host.querySelector('ul') || host;
     (firstUl.parentNode || host).insertBefore(ul, firstUl.nextSibling);
     (firstUl.parentNode || host).insertBefore(outer, firstUl.nextSibling);


     return true;
     return true;
   }
   }


   // Beim Laden versuchen
   // beim Laden probieren …
   document.addEventListener('DOMContentLoaded', () => setTimeout(build, 0));
   document.addEventListener('DOMContentLoaded', () => setTimeout(build, 0));
 
   // … und wenn das Burger-Menü dynamisch aufgebaut wird, nochmal
   // Wenn das Menü erst beim Öffnen gebaut wird – nachklinken
   document.addEventListener('click', (e) => {
   document.addEventListener('click', (e) => {
     const btn = e.target.closest('button, a');
     const btn = e.target.closest('button, a');
Zeile 125: Zeile 114:
     }
     }
   });
   });
 
   // Fallback: Observer für lazy DOM
   // Fallback: Menü taucht asynchron auf
   const obs = new MutationObserver(() => { if (build()) obs.disconnect(); });
   const obs = new MutationObserver(() => { if (build()) obs.disconnect(); });
   obs.observe(document.documentElement, { childList: true, subtree: true });
   obs.observe(document.documentElement, { childList: true, subtree: true });
})();
})();

Version vom 18. Oktober 2025, 11:49 Uhr

/* All JavaScript here will be loaded for users of the MinervaNeue skin */

/* Weitere Menüs für MobileFrontend & MinervaNeue (Mobile Ansicht) */
(function () {
  if (mw.config.get('skin') !== 'minerva') return;

  // --- KONFIG: Label + Seitentitel (werden mit mw.util.getUrl() sicher verlinkt)
  const LINKS = [
    ['Hauptkategorien', null], // Header/Toggle, kein Link
    ['Alle A Dream of Scotland Abfüllungen', 'Kategorie:Alle A Dream of Scotland Abfüllungen'],
    ['Alle A Dream of Ireland Abfüllungen',  'Kategorie:Alle A Dream of Ireland Abfüllungen'],
    ['Alle A Dream of... – Der Rest der Welt', 'Kategorie:Alle A Dream of... – Der Rest der Welt Abfüllungen'],
    ['Cigar Malt Übersicht', 'Kategorie:Cigar Malt Übersicht'],
    ['Alle Rumbastic Abfüllungen', 'Kategorie:Alle Rumbastic Abfüllungen'],
    ['The Tasteful 8', 'Kategorie:The Tasteful 8'],
    ['Còmhlan Abfüllungen', 'Kategorie:Còmhlan Abfüllungen'],
    ['Friendly Mr. Z Whiskytainment Abfüllungen', 'Kategorie:Friendly Mr. Z Whiskytainment Abfüllungen'],
    ['Die Whisky Elfen Abfüllungen', 'Kategorie:Die Whisky Elfen Abfüllungen'],
    ['The Fine Art of Whisky Abfüllungen', 'Kategorie:The Fine Art of Whisky Abfüllungen'],
    ['The Forbidden Kingdom', 'Kategorie:The Forbidden Kingdom']
  ];

  const BLOCK_ID = 'ados-custom-links';

  function findMenuList() {
    return (
      document.querySelector('#mw-mf-main-menu nav ul') ||
      document.querySelector('#mw-mf-main-menu ul') ||
      document.querySelector('.minerva-main-menu .menu__list') ||
      document.querySelector('.menu__list') ||
      document.querySelector('.menu')
    );
  }

  function build() {
    const host = findMenuList();
    if (!host) return false;
    if (document.getElementById(BLOCK_ID)) return true; // schon eingebaut

    // äußerer Block
    const outer = document.createElement('ul');
    outer.id = BLOCK_ID;
    outer.className = 'toggle-list__list';

    // Header mit Icon + Toggle
    const [headerLabel] = LINKS[0];
    const headerLi = document.createElement('li');
    headerLi.className = 'toggle-list-item';

    const headerBtn = document.createElement('button');
    headerBtn.type = 'button';
    headerBtn.className = 'toggle-list-item__anchor';
    headerBtn.setAttribute('aria-expanded', 'true');
    headerBtn.innerHTML =
      '<span class="minerva-icon minerva-icon--listBullet"></span>' +
      `<span class="toggle-list-item__label">${headerLabel}</span>`;

    headerLi.appendChild(headerBtn);
    outer.appendChild(headerLi);

    // Unterpunkte-Liste (ohne Icons)
    const inner = document.createElement('ul');
    inner.className = 'toggle-list__list';
    inner.style.marginLeft = '10px';

    for (let i = 1; i < LINKS.length; i++) {
      const [label, title] = LINKS[i];
      const li = document.createElement('li');
      li.className = 'toggle-list-item';

      const a = document.createElement('a');
      a.className = 'toggle-list-item__anchor';
      a.textContent = label;
      a.href = title ? mw.util.getUrl(title) : '#';

      // KEIN Icon bei Unterpunkten
      li.appendChild(a);
      inner.appendChild(li);
    }
    outer.appendChild(inner);

    // Toggle-Logik
    headerBtn.addEventListener('click', function () {
      const expanded = this.getAttribute('aria-expanded') === 'true';
      this.setAttribute('aria-expanded', String(!expanded));
      inner.style.display = expanded ? 'none' : '';
      try { localStorage.setItem(BLOCK_ID + ':collapsed', expanded ? '1' : '0'); } catch (e) {}
    });

    // Zustand wiederherstellen
    try {
      if (localStorage.getItem(BLOCK_ID + ':collapsed') === '1') {
        headerBtn.setAttribute('aria-expanded', 'false');
        inner.style.display = 'none';
      }
    } catch (e) {}

    // nach der ersten vorhandenen UL einfügen (direkt unter Start/Zufällige Seite)
    const firstUl = host.querySelector('ul') || host;
    (firstUl.parentNode || host).insertBefore(outer, firstUl.nextSibling);

    return true;
  }

  // beim Laden probieren …
  document.addEventListener('DOMContentLoaded', () => setTimeout(build, 0));
  // … und wenn das Burger-Menü dynamisch aufgebaut wird, nochmal
  document.addEventListener('click', (e) => {
    const btn = e.target.closest('button, a');
    if (!btn) return;
    const s = (btn.className + ' ' + btn.id).toLowerCase();
    if (s.includes('menu') || s.includes('hamburger') || s.includes('main-menu')) {
      setTimeout(build, 250);
    }
  });
  // Fallback: Observer für lazy DOM
  const obs = new MutationObserver(() => { if (build()) obs.disconnect(); });
  obs.observe(document.documentElement, { childList: true, subtree: true });
})();