MediaWiki:Minerva.js: Unterschied zwischen den Versionen
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung Markierung: Zurückgesetzt |
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
| (2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 3: | Zeile 3: | ||
/* Weitere Menüs für MobileFrontend & MinervaNeue (Mobile Ansicht) */ | /* Weitere Menüs für MobileFrontend & MinervaNeue (Mobile Ansicht) */ | ||
(function () { | (function () { | ||
// Nur Mobile-Skin (Minerva) | |||
if (mw.config.get('skin') !== 'minerva') return; | if (mw.config.get('skin') !== 'minerva') return; | ||
const BLOCK_ID = 'ados-custom-links'; | |||
// --- KONFIG: Label + Seitentitel (werden mit mw.util.getUrl() sicher verlinkt) | // --- KONFIG: Label + Seitentitel (werden mit mw.util.getUrl() sicher verlinkt) | ||
// Header/Sektionen haben title = null | |||
// WICHTIG: "📊 Diagramm / Statistik" steht ganz oben | |||
const LINKS = [ | |||
['📊 Diagramm / Statistik', null], | |||
[ | ['Abfüllungen pro Jahr', 'Abfüllungen_pro_Jahr'], | ||
// optional: | |||
// ['Top 5 – Community', 'Top_5'], | |||
['Hauptkategorien', null], | |||
['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'], | |||
['Sonderabfüllungen', 'Kategorie:Sonderabfüllungen'] | |||
]; | |||
function findMenuList() { | function findMenuList() { | ||
| Zeile 38: | Zeile 40: | ||
document.querySelector('.menu') | document.querySelector('.menu') | ||
); | ); | ||
} | |||
function buildSectionsFromLinks(links) { | |||
const sections = []; | |||
let current = null; | |||
for (const [label, title] of links) { | |||
if (title === null) { | |||
current = { header: label, items: [] }; | |||
sections.push(current); | |||
} else if (current) { | |||
current.items.push({ label, title }); | |||
} | |||
} | |||
return sections; | |||
} | } | ||
| Zeile 43: | Zeile 60: | ||
const host = findMenuList(); | const host = findMenuList(); | ||
if (!host) return false; | if (!host) return false; | ||
// | // schon eingebaut? | ||
if (document.getElementById(BLOCK_ID)) return true; | |||
const sections = buildSectionsFromLinks(LINKS); | |||
const | if (!sections.length) return false; | ||
const | // Container für alle Sektionen | ||
const container = document.createElement('div'); | |||
container.id = BLOCK_ID; | |||
sections.forEach((sec, idx) => { | |||
const secId = `${BLOCK_ID}-sec-${idx}`; | |||
// äußerer Block je Sektion | |||
const outer = document.createElement('ul'); | |||
outer.className = 'toggle-list__list'; | |||
// Header mit Icon + Toggle | |||
const | const headerLi = document.createElement('li'); | ||
headerLi.className = 'toggle-list-item'; | |||
const | 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">${sec.header}</span>`; | |||
// | headerLi.appendChild(headerBtn); | ||
li.appendChild(a); | outer.appendChild(headerLi); | ||
// Unterpunkte-Liste (ohne Icons) | |||
const inner = document.createElement('ul'); | |||
inner.className = 'toggle-list__list'; | |||
inner.style.marginLeft = '10px'; | |||
sec.items.forEach(({ label, title }) => { | |||
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 = mw.util.getUrl(title); | |||
li.appendChild(a); | |||
inner.appendChild(li); | |||
}); | |||
outer.appendChild(inner); | |||
// Toggle-Logik pro Sektion | |||
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(secId + ':collapsed', expanded ? '1' : '0'); } catch (e) {} | |||
}); | |||
// Zustand wiederherstellen | |||
try { | |||
if (localStorage.getItem(secId + ':collapsed') === '1') { | |||
headerBtn.setAttribute('aria-expanded', 'false'); | |||
inner.style.display = 'none'; | |||
} | |||
} catch (e) {} | |||
container.appendChild(outer); | |||
}); | }); | ||
// nach der ersten vorhandenen UL einfügen (direkt unter Start/Zufällige Seite) | // 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( | (firstUl.parentNode || host).insertBefore(container, firstUl.nextSibling); | ||
return true; | return true; | ||
| Zeile 112: | Zeile 141: | ||
// beim Laden probieren … | // beim Laden probieren … | ||
document.addEventListener('DOMContentLoaded', () => setTimeout(build, 0)); | document.addEventListener('DOMContentLoaded', () => setTimeout(build, 0)); | ||
// … und wenn das Burger-Menü dynamisch aufgebaut wird, nochmal | // … und wenn das Burger-Menü dynamisch aufgebaut wird, nochmal | ||
document.addEventListener('click', (e) => { | document.addEventListener('click', (e) => { | ||
| Zeile 121: | Zeile 151: | ||
} | } | ||
}); | }); | ||
// Fallback: Observer für lazy DOM | // Fallback: Observer für lazy DOM | ||
const obs = new MutationObserver(() => { if (build()) obs.disconnect(); }); | const obs = new MutationObserver(() => { if (build()) obs.disconnect(); }); | ||