MediaWiki:Common.js: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
Keine Bearbeitungszusammenfassung |
||
| Zeile 2: | Zeile 2: | ||
/* ==== Sidebar: klickbare Kopfzeile + Gruppen mit Auf/Zu (Vector-2022) ==== */ | /* ==== Sidebar: klickbare Kopfzeile + Gruppen mit Auf/Zu (Vector-2022) ==== */ | ||
(function () { | (function () { | ||
if (mw.config.get('skin') !== 'vector-2022') return; | if ( mw.config.get('skin') !== 'vector-2022' ) return; | ||
// --- Helpers -------------------------------------------------------------- | |||
function extractDirective(a) { | function extractDirective(a) { | ||
if (!a) return null; | if (!a) return null; | ||
var href = a.getAttribute('href') || ''; | var href = a.getAttribute('href') || ''; | ||
try { href = new URL(href, location.href).hash || ''; } catch (e) {} | try { href = new URL(href, location.href).hash || ''; } catch (e) {} | ||
var s = href.trim().toLowerCase(); | var s = (href || '').trim().toLowerCase(); | ||
if (s.indexOf('#group:') >= 0) return { kind: 'group', value: decodeURIComponent(s.split('#group:').pop()) }; | 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()) }; | if (s.indexOf('#link:') >= 0) return { kind: 'link', value: decodeURIComponent(s.split('#link:').pop()) }; | ||
return null; | return null; | ||
} | |||
// entfernt #link:… / #group:… aus einem <a> | |||
function stripDirectiveHash(a) { | |||
if (!a) return; | |||
var raw = a.getAttribute('href') || ''; | |||
a.setAttribute('href', raw.replace(/#(?:link|group):.*$/i, '')); | |||
} | } | ||
function makeHead(li, keepLink) { | function makeHead(li, keepLink) { | ||
// Kopf: [Pfeil] [Link | // Kopf: [Pfeil] [Link oder Text] | ||
var a = li.querySelector(':scope > a'); | var a = li.querySelector(':scope > a'); | ||
var head = document.createElement('div'); | var head = document.createElement('div'); | ||
head.className = 'kr-head'; | head.className = 'kr-head'; | ||
var btn = document.createElement('button'); | var btn = document.createElement('button'); | ||
btn.type = 'button'; | btn.type = 'button'; | ||
| Zeile 26: | Zeile 34: | ||
head.appendChild(btn); | head.appendChild(btn); | ||
if (keepLink) { | if (keepLink && a) { | ||
// | stripDirectiveHash(a); // <<< HIER: #link:… aus der URL entfernen | ||
head.appendChild(a); | head.appendChild(a); | ||
} else { | } else { | ||
var span = document.createElement('span'); | var span = document.createElement('span'); | ||
span.className = 'kr-title'; | span.className = 'kr-title'; | ||
span.textContent = (a && a.textContent) || ''; | span.textContent = (a && a.textContent) || ''; | ||
head.appendChild(span); | head.appendChild(span); | ||
if (a) a.remove(); // Link | if (a) a.remove(); // kein Link im Kopf behalten | ||
} | } | ||
| Zeile 51: | Zeile 58: | ||
if (d && d.kind === 'group') { | if (d && d.kind === 'group') { | ||
// Gruppen-Header (ohne Link) | // Gruppen-Header (ohne Link) | ||
li.classList.add('kr-group'); | li.classList.add('kr-group'); | ||
makeHead(li, false); | makeHead(li, false); | ||
// Unterliste | |||
var sub = document.createElement('ul'); | var sub = document.createElement('ul'); | ||
sub.className = 'kr-sub'; | sub.className = 'kr-sub'; | ||
li.appendChild(sub); | li.appendChild(sub); | ||
currentGroup = sub; | currentGroup = sub; | ||
// Direktiven-Link | |||
if (a) a. | // Direktiven-Link vollständig aus dem DOM entfernen | ||
if (a) a.remove(); | |||
return; | return; | ||
} | } | ||
// Normale | // Normale Einträge in die gerade offene Gruppe schieben | ||
if (currentGroup && !(d && (d.kind === 'group' || d.kind === 'link'))) { | if (currentGroup && !(d && (d.kind === 'group' || d.kind === 'link'))) { | ||
currentGroup.appendChild(li); | currentGroup.appendChild(li); | ||
| Zeile 69: | Zeile 79: | ||
}); | }); | ||
// Auf/Zu | // Auf/Zu | ||
ul.addEventListener('click', function (e) { | ul.addEventListener('click', function (e) { | ||
if (e.target.classList.contains('kr-arrow')) { | |||
var li = e.target.closest('li.kr-group, li.kr-top'); | |||
var li = | |||
if (li) { | if (li) { | ||
var collapsed = li.classList.toggle('is-collapsed'); | var collapsed = li.classList.toggle('is-collapsed'); | ||
e.target.setAttribute('aria-expanded', collapsed ? 'false' : 'true'); | |||
} | } | ||
} | } | ||
| Zeile 83: | Zeile 92: | ||
function buildPortlets(root) { | function buildPortlets(root) { | ||
var lists = root.querySelectorAll('#mw-panel .vector-menu-content-list'); | var lists = root.querySelectorAll('#mw-panel .vector-menu-content-list'); | ||
lists.forEach(function (ul) { | lists.forEach(function (ul) { | ||
var items = Array.from(ul.querySelectorAll(':scope > li.mw-list-item')); | var items = Array.from(ul.querySelectorAll(':scope > li.mw-list-item')); | ||
var topIdx = items.findIndex(function (li) { | var topIdx = items.findIndex(function (li) { | ||
| Zeile 97: | Zeile 105: | ||
var top = items[topIdx]; | var top = items[topIdx]; | ||
top.classList.add('kr-top'); | top.classList.add('kr-top'); | ||
makeHead(top, true); | makeHead(top, true); // Link bleibt – aber ohne #link:… | ||
// Unterliste | // Unterliste unter dem Kopf, Rest hinein | ||
var sub = document.createElement('ul'); | var sub = document.createElement('ul'); | ||
sub.className = 'kr-sub'; | sub.className = 'kr-sub'; | ||
top.appendChild(sub); | top.appendChild(sub); | ||
for (var i = topIdx + 1; i < items.length; i++) sub.appendChild(items[i]); | |||
buildGroups(sub); | buildGroups(sub); | ||
} else { | } else { | ||
buildGroups(ul); | buildGroups(ul); | ||
} | |||
// Sicherheit: alle verbleibenden Direktiven aus hrefs entfernen | |||
ul.querySelectorAll('a[href*="#link:"], a[href*="#group:"]').forEach(stripDirectiveHash); | |||
// Original-Portlet-Heading (H3) ENTFERNEN | |||
var portlet = ul.closest('.vector-menu'); | |||
if (portlet) { | |||
var heading = portlet.querySelector(':scope > .vector-menu-heading'); | |||
if (heading) heading.remove(); | |||
} | } | ||
}); | }); | ||
| Zeile 125: | Zeile 137: | ||
} | } | ||
mw.hook('wikipage.content').add(init); | mw.hook('wikipage.content').add(init); | ||
init(); | init(); | ||
})(); | })(); | ||
Version vom 10. Oktober 2025, 14:07 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;
// --- Helpers --------------------------------------------------------------
function extractDirective(a) {
if (!a) return null;
var href = a.getAttribute('href') || '';
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;
}
// entfernt #link:… / #group:… aus einem <a>
function stripDirectiveHash(a) {
if (!a) return;
var raw = a.getAttribute('href') || '';
a.setAttribute('href', raw.replace(/#(?:link|group):.*$/i, ''));
}
function makeHead(li, keepLink) {
// Kopf: [Pfeil] [Link oder Text]
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 && a) {
stripDirectiveHash(a); // <<< HIER: #link:… aus der URL entfernen
head.appendChild(a);
} else {
var span = document.createElement('span');
span.className = 'kr-title';
span.textContent = (a && a.textContent) || '';
head.appendChild(span);
if (a) a.remove(); // kein Link im Kopf behalten
}
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)
li.classList.add('kr-group');
makeHead(li, false);
// Unterliste
var sub = document.createElement('ul');
sub.className = 'kr-sub';
li.appendChild(sub);
currentGroup = sub;
// Direktiven-Link vollständig aus dem DOM entfernen
if (a) a.remove();
return;
}
// Normale Einträge in die gerade offene Gruppe schieben
if (currentGroup && !(d && (d.kind === 'group' || d.kind === 'link'))) {
currentGroup.appendChild(li);
}
});
// Auf/Zu
ul.addEventListener('click', function (e) {
if (e.target.classList.contains('kr-arrow')) {
var li = e.target.closest('li.kr-group, li.kr-top');
if (li) {
var collapsed = li.classList.toggle('is-collapsed');
e.target.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
}
}
});
}
function buildPortlets(root) {
var lists = root.querySelectorAll('#mw-panel .vector-menu-content-list');
lists.forEach(function (ul) {
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); // Link bleibt – aber ohne #link:…
// Unterliste unter dem Kopf, Rest hinein
var sub = document.createElement('ul');
sub.className = 'kr-sub';
top.appendChild(sub);
for (var i = topIdx + 1; i < items.length; i++) sub.appendChild(items[i]);
buildGroups(sub);
} else {
buildGroups(ul);
}
// Sicherheit: alle verbleibenden Direktiven aus hrefs entfernen
ul.querySelectorAll('a[href*="#link:"], a[href*="#group:"]').forEach(stripDirectiveHash);
// Original-Portlet-Heading (H3) ENTFERNEN
var portlet = ul.closest('.vector-menu');
if (portlet) {
var heading = portlet.querySelector(':scope > .vector-menu-heading');
if (heading) heading.remove();
}
});
}
function init() {
var panel = document.getElementById('mw-panel');
if (!panel) return;
panel.classList.add('kr-sb');
buildPortlets(panel);
}
mw.hook('wikipage.content').add(init);
init();
})();