MediaWiki:Common.js: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Cezary (Diskussion | Beiträge) Nachtmodus (Testphase): Schalter per Testlink ?nachtmodus=test (im Browser gemerkt), ?nachtmodus=aus schaltet ab; beim Bearbeiten bleibt die Seite hell. Für Besucher ohne Testlink ändert sich nichts. Markierungen: Mobile Bearbeitung Mobile Web-Bearbeitung |
Cezary (Diskussion | Beiträge) Nachtmodus (Test): Schalter auch nach dem Ausschalten aus der Adresszeile entfernen |
||
| Zeile 8: | Zeile 8: | ||
var wert = null; | var wert = null; | ||
try { wert = new URLSearchParams( location.search ).get( 'nachtmodus' ); } catch ( e ) {} | try { wert = new URLSearchParams( location.search ).get( 'nachtmodus' ); } catch ( e ) {} | ||
// Den Schalter nicht in der Adresszeile stehen lassen (sonst wird er beim Weitergeben eines Links mitgeschickt) | // Den Schalter nicht in der Adresszeile stehen lassen (sonst wird er beim Weitergeben eines Links mitgeschickt) | ||
if ( wert !== null && window.history && history.replaceState ) { | if ( wert !== null && window.history && history.replaceState ) { | ||
| Zeile 21: | Zeile 16: | ||
} catch ( e ) {} | } catch ( e ) {} | ||
} | } | ||
try { | |||
if ( wert === 'test' || wert === 'an' ) { localStorage.setItem( SCHLUESSEL, '1' ); } | |||
if ( wert === 'aus' ) { localStorage.removeItem( SCHLUESSEL ); } | |||
if ( localStorage.getItem( SCHLUESSEL ) !== '1' ) { return; } | |||
} catch ( e ) { return; } | |||
if ( [ 'edit', 'submit' ].indexOf( mw.config.get( 'wgAction' ) ) !== -1 ) { return; } | if ( [ 'edit', 'submit' ].indexOf( mw.config.get( 'wgAction' ) ) !== -1 ) { return; } | ||
document.documentElement.classList.add( 'ckw-nacht' ); | document.documentElement.classList.add( 'ckw-nacht' ); | ||
Version vom 25. September 2026, 14:41 Uhr
/* CK-Wissen (seit 25.09.2026): Nachtmodus – Testphase.
Aktiv nur in Browsern, die einmal den Testlink …?title=Hauptseite&nachtmodus=test geöffnet haben (bleibt im Browser gemerkt);
&nachtmodus=aus schaltet ihn wieder ab. Beim Bearbeiten bleibt die Seite hell.
Farben: Block „Nachtmodus“ am Ende von MediaWiki:Common.css. */
( function () {
'use strict';
var SCHLUESSEL = 'ckw-nachtmodus-test';
var wert = null;
try { wert = new URLSearchParams( location.search ).get( 'nachtmodus' ); } catch ( e ) {}
// Den Schalter nicht in der Adresszeile stehen lassen (sonst wird er beim Weitergeben eines Links mitgeschickt)
if ( wert !== null && window.history && history.replaceState ) {
try {
var sauber = new URL( location.href );
sauber.searchParams.delete( 'nachtmodus' );
history.replaceState( history.state, '', sauber.toString() );
} catch ( e ) {}
}
try {
if ( wert === 'test' || wert === 'an' ) { localStorage.setItem( SCHLUESSEL, '1' ); }
if ( wert === 'aus' ) { localStorage.removeItem( SCHLUESSEL ); }
if ( localStorage.getItem( SCHLUESSEL ) !== '1' ) { return; }
} catch ( e ) { return; }
if ( [ 'edit', 'submit' ].indexOf( mw.config.get( 'wgAction' ) ) !== -1 ) { return; }
document.documentElement.classList.add( 'ckw-nacht' );
$( function () {
var aus = new URL( location.href );
aus.searchParams.set( 'nachtmodus', 'aus' );
var hinweis = document.createElement( 'a' );
hinweis.className = 'ckw-nacht-hinweis';
hinweis.href = aus.toString();
hinweis.textContent = 'Nachtmodus (Test) ausschalten';
document.body.appendChild( hinweis );
} );
}() );
/* CK-Wissen (seit 24.09.2026): linke Leiste zum Aufklappen, „Auf dieser Seite“ rechts neben dem Text,
Kleinigkeiten für die Lesespalte. Gestaltung dazu am Ende von MediaWiki:Common.css.
Ohne Skript bleibt alles sichtbar (die Leiste geht nach 4 Sekunden von selbst auf). */
( function () {
'use strict';
var each = function ( liste, fn ) { Array.prototype.forEach.call( liste, fn ); };
function titelAus( href ) {
if ( !href ) { return null; }
// nur einfache Seitenlinks (ohne &action=…, &oldid=… usw.)
var m = href.match( /^[^?#]*\?title=([^&#]+)$/ ) || href.match( /\/index\.php\/([^?#]+)$/ );
if ( !m ) { return null; }
try { return decodeURIComponent( m[ 1 ] ).replace( / /g, '_' ); } catch ( e ) { return null; }
}
/* ---------- Linke Leiste ---------- */
function leiste() {
var panel = document.getElementById( 'mw-panel' );
if ( !panel ) { return; }
var hier = mw.config.get( 'wgPageName' );
var SPEICHER = 'ckw-leiste';
var gemerkt = {};
try { gemerkt = JSON.parse( localStorage.getItem( SPEICHER ) || '{}' ) || {}; } catch ( e ) { gemerkt = {}; }
var immerOffen = { 'p-navigation': true, 'p-Gegen_die_Attacke': true };
each( panel.querySelectorAll( '.vector-menu-portal' ), function ( portal ) {
var hatHier = false;
each( portal.querySelectorAll( 'li > a' ), function ( a ) {
if ( titelAus( a.getAttribute( 'href' ) ) === hier ) {
a.parentNode.classList.add( 'ckw-hier' );
a.setAttribute( 'aria-current', 'page' );
hatHier = true;
}
} );
if ( immerOffen[ portal.id ] ) { return; }
var kopf = portal.querySelector( '.vector-menu-heading' );
var inhalt = portal.querySelector( '.vector-menu-content' );
if ( !kopf || !inhalt ) { return; }
var anzahl = inhalt.querySelectorAll( 'li' ).length;
if ( !inhalt.id ) { inhalt.id = portal.id + '-inhalt'; }
var knopf = document.createElement( 'button' );
knopf.type = 'button';
knopf.className = 'ckw-klapp';
knopf.setAttribute( 'aria-controls', inhalt.id );
var text = document.createElement( 'span' );
text.className = 'ckw-klapp-text';
text.textContent = kopf.textContent.trim();
var zahl = document.createElement( 'span' );
zahl.className = 'ckw-klapp-zahl';
zahl.textContent = String( anzahl );
zahl.setAttribute( 'aria-hidden', 'true' );
knopf.appendChild( text );
knopf.appendChild( zahl );
kopf.textContent = '';
kopf.appendChild( knopf );
var setze = function ( offen ) {
knopf.setAttribute( 'aria-expanded', offen ? 'true' : 'false' );
knopf.title = ( offen ? 'Zuklappen' : 'Aufklappen' ) + ' (' + anzahl + ' Seiten)';
portal.classList.toggle( 'ckw-zu', !offen );
};
setze( hatHier || gemerkt[ portal.id ] === true );
knopf.addEventListener( 'click', function () {
var offen = knopf.getAttribute( 'aria-expanded' ) !== 'true';
setze( offen );
gemerkt[ portal.id ] = offen;
try { localStorage.setItem( SPEICHER, JSON.stringify( gemerkt ) ); } catch ( e ) {}
} );
} );
document.documentElement.classList.add( 'ckw-leiste-bereit' );
}
/* ---------- Lesespalte ---------- */
function istLeseseite() {
return mw.config.get( 'skin' ) === 'vector' &&
mw.config.get( 'wgAction' ) === 'view' &&
!mw.config.get( 'wgIsMainPage' ) &&
[ 0, 1, 4, 5, 12 ].indexOf( mw.config.get( 'wgNamespaceNumber' ) ) !== -1;
}
function lesespalte( spalte ) {
// Einleitung: erster Absatz vor der ersten Zwischenüberschrift, wenn er nicht zu lang ist
var ersterAbsatz = null, kind = spalte.firstElementChild;
while ( kind && kind.tagName !== 'H2' ) {
if ( kind.tagName === 'P' && kind.textContent.trim().length > 40 ) { ersterAbsatz = kind; break; }
kind = kind.nextElementSibling;
}
if ( ersterAbsatz && ersterAbsatz.textContent.length <= 650 ) { ersterAbsatz.classList.add( 'ckw-einleitung' ); }
// Zu breite Tabellen seitlich schiebbar machen (nicht bei umflossenen Tabellen)
each( spalte.querySelectorAll( 'table.wikitable' ), function ( t ) {
if ( t.parentNode.classList.contains( 'ckw-tabelle' ) ) { return; }
if ( window.getComputedStyle( t ).cssFloat !== 'none' ) { return; }
var huelle = document.createElement( 'div' );
huelle.className = 'ckw-tabelle';
t.parentNode.insertBefore( huelle, t );
huelle.appendChild( t );
} );
}
/* ---------- „Auf dieser Seite“ ---------- */
function seitennav( spalte ) {
var toc = document.getElementById( 'toc' );
var inhalt = document.getElementById( 'mw-content-text' );
if ( !toc || !inhalt || !toc.querySelector( 'li.toclevel-1' ) ) { return; }
var eintraege = [];
var baue = function ( ul, ebene ) {
var ol = document.createElement( 'ol' );
each( ul.children, function ( li ) {
var a = li.querySelector( ':scope > a' );
if ( !a ) { return; }
var neuLi = document.createElement( 'li' );
var neuA = document.createElement( 'a' );
neuA.href = a.getAttribute( 'href' );
var t = a.querySelector( '.toctext' );
neuA.textContent = ( t || a ).textContent;
neuLi.appendChild( neuA );
var ziel = null;
try { ziel = document.getElementById( decodeURIComponent( neuA.hash.slice( 1 ) ) ); } catch ( e ) {}
if ( ziel ) { eintraege.push( { a: neuA, li: neuLi, ziel: ziel.closest( 'h2, h3, h4' ) || ziel, ebene: ebene } ); }
var unter = li.querySelector( ':scope > ul' );
if ( unter && ebene < 2 ) { neuLi.appendChild( baue( unter, ebene + 1 ) ); }
ol.appendChild( neuLi );
} );
return ol;
};
var nav = document.createElement( 'nav' );
nav.className = 'ckw-seitennav';
nav.setAttribute( 'aria-label', 'Auf dieser Seite' );
var titel = document.createElement( 'div' );
titel.className = 'ckw-seitennav-titel';
titel.textContent = 'Auf dieser Seite';
nav.appendChild( titel );
nav.appendChild( baue( toc.querySelector( 'ul' ), 1 ) );
var hoch = document.createElement( 'a' );
hoch.href = '#top';
hoch.className = 'ckw-nach-oben';
hoch.textContent = 'Nach oben';
nav.appendChild( hoch );
inhalt.appendChild( nav );
document.body.classList.add( 'ckw-mit-seitennav' );
// Mitlaufende Markierung: welcher Abschnitt ist gerade zu sehen?
var aktiv = null, geplant = false;
var markiere = function () {
geplant = false;
if ( window.getComputedStyle( nav ).display === 'none' ) { return; }
var neu = null;
for ( var i = 0; i < eintraege.length; i++ ) {
if ( eintraege[ i ].ziel.getBoundingClientRect().top <= 120 ) { neu = eintraege[ i ]; } else { break; }
}
if ( neu === aktiv ) { return; }
each( nav.querySelectorAll( '.ckw-aktiv' ), function ( x ) { x.classList.remove( 'ckw-aktiv' ); } );
each( nav.querySelectorAll( '.ckw-offen' ), function ( x ) { x.classList.remove( 'ckw-offen' ); } );
aktiv = neu;
if ( !neu ) { return; }
neu.a.classList.add( 'ckw-aktiv' );
var li = neu.li;
while ( li && li !== nav ) {
if ( li.tagName === 'LI' ) { li.classList.add( 'ckw-offen' ); }
li = li.parentNode;
}
// Markierten Eintrag in der Liste sichtbar halten, ohne die Seite zu verschieben
var oben = neu.a.offsetTop, unten = oben + neu.a.offsetHeight;
if ( oben < nav.scrollTop + 40 ) { nav.scrollTop = Math.max( 0, oben - 60 ); }
else if ( unten > nav.scrollTop + nav.clientHeight - 40 ) { nav.scrollTop = unten - nav.clientHeight + 60; }
};
var plane = function () {
if ( !geplant ) { geplant = true; window.requestAnimationFrame( markiere ); }
};
window.addEventListener( 'scroll', plane, { passive: true } );
window.addEventListener( 'resize', plane );
markiere();
}
$( function () {
// Themen der Leiste für „Weiter im Thema“ melden (vor dem Umbau der Überschriften)
try {
var panel = document.getElementById( 'mw-panel' ), gruppen = [];
each( panel ? panel.querySelectorAll( '.vector-menu-portal' ) : [], function ( p ) {
if ( p.id === 'p-tb' ) { return; }
var kopf = p.querySelector( '.vector-menu-heading' ), links = [];
each( p.querySelectorAll( 'li > a' ), function ( a ) {
var text = a.textContent.trim(), href = a.getAttribute( 'href' );
if ( text && href ) { links.push( [ text, href ] ); }
} );
if ( links.length ) { gruppen.push( { id: p.id, label: kopf ? kopf.textContent.trim() : '', links: links } ); }
} );
if ( gruppen.length ) { mw.hook( 'ckw.themen' ).fire( gruppen ); }
} catch ( e ) { mw.log.warn( 'CK-Wissen Themen:', e ); }
try { leiste(); } catch ( e ) {
document.documentElement.classList.add( 'ckw-leiste-offen' );
mw.log.warn( 'CK-Wissen Leiste:', e );
}
if ( !istLeseseite() ) { return; }
var spalte = document.querySelector( '#mw-content-text > .mw-parser-output' );
if ( !spalte ) { return; }
try { lesespalte( spalte ); } catch ( e ) { mw.log.warn( 'CK-Wissen Lesespalte:', e ); }
try { seitennav( spalte ); } catch ( e ) { mw.log.warn( 'CK-Wissen Seitennavigation:', e ); }
} );
}() );
/* CK-Wissen (seit 24.09.2026): Handy-Ansicht – alle Themen der linken Leiste im Menü (☰) und unten auf jeder Seite,
„Gegen die Attacke“ dort aufgeklappt gleich nach „Start“. Oben auf den Seiten steht seit 25.09.2026 kein
Akut-Kasten mehr: In einer Attacke kann man kaum lesen, oben soll zuerst der Text der Seite kommen.
Die Themen kommen automatisch aus MediaWiki:Sidebar: Das Skript liest die Desktop-Leiste einer
leeren Seite und merkt sie sich im Browser für 12 Stunden. Gestaltung am Ende von MediaWiki:Common.css. */
( function () {
'use strict';
if ( mw.config.get( 'skin' ) !== 'minerva' ) { return; }
var SPEICHER = 'ckw-themen-v2'; // v2 seit 25.09.2026: neue Gruppennamen der Leiste sofort zeigen
try { localStorage.removeItem( 'ckw-themen-v1' ); } catch ( e ) {}
var HALTBAR = 12 * 60 * 60 * 1000;
var skript = mw.config.get( 'wgScript' );
var hier = mw.config.get( 'wgPageName' );
var istInhalt = mw.config.get( 'wgAction' ) === 'view' &&
mw.config.get( 'wgNamespaceNumber' ) >= 0 &&
!mw.config.get( 'wgIsMainPage' );
function titelAus( href ) {
if ( !href ) { return null; }
var m = href.match( /^[^?#]*\?title=([^&#]+)$/ ) || href.match( /\/index\.php\/([^?#]+)$/ );
if ( !m ) { return null; }
try { return decodeURIComponent( m[ 1 ] ).replace( / /g, '_' ); } catch ( e ) { return null; }
}
function el( tag, klasse, text ) {
var e = document.createElement( tag );
if ( klasse ) { e.className = klasse; }
if ( text ) { e.textContent = text; }
return e;
}
function verweis( paar ) {
var a = el( 'a', null, paar[ 0 ] );
a.href = paar[ 1 ];
if ( titelAus( paar[ 1 ] ) === hier ) {
a.className = 'ckw-hier';
a.setAttribute( 'aria-current', 'page' );
}
return a;
}
function gruppenBlock( gruppen, klasse ) {
var box = el( 'div', klasse );
gruppen.forEach( function ( g ) {
var liste = el( 'ul' ), hatHier = false;
g.links.forEach( function ( paar ) {
var li = el( 'li' );
var a = verweis( paar );
if ( a.className === 'ckw-hier' ) { hatHier = true; }
li.appendChild( a );
liste.appendChild( li );
} );
if ( g.id === 'p-navigation' ) {
var start = el( 'div', 'ckw-gruppe ckw-gruppe-start' );
start.appendChild( liste );
box.appendChild( start );
return;
}
var akut = g.id === 'p-Gegen_die_Attacke';
var d = el( 'details', 'ckw-gruppe' + ( akut ? ' ckw-gruppe-akut' : '' ) );
d.open = akut || hatHier;
var s = el( 'summary' );
s.appendChild( el( 'span', 'ckw-gruppe-name', g.label ) );
var zahl = el( 'span', 'ckw-gruppe-zahl', String( g.links.length ) );
zahl.setAttribute( 'aria-hidden', 'true' );
s.appendChild( zahl );
d.appendChild( s );
d.appendChild( liste );
box.appendChild( d );
} );
return box;
}
function zeigen( gruppen ) {
// Menü (☰): Themen nach „Start“ und „Zufällige Seite“
var menue = document.getElementById( 'mw-mf-page-left' );
if ( menue ) {
var altM = menue.querySelector( '.ckw-menue-themen' );
if ( altM ) { altM.parentNode.removeChild( altM ); }
var themenM = gruppenBlock( gruppen.filter( function ( g ) { return g.id !== 'p-navigation'; } ), 'ckw-menue-themen' );
var nav = menue.querySelector( '#p-navigation' );
if ( nav ) { nav.parentNode.insertBefore( themenM, nav.nextSibling ); } else { menue.appendChild( themenM ); }
}
// Unten auf der Seite: alle Themen
var haupt = document.getElementById( 'content' );
if ( istInhalt && haupt ) {
var altU = document.querySelector( '.ckw-mobil-themen' );
if ( altU ) { altU.parentNode.removeChild( altU ); }
var unten = el( 'nav', 'ckw-mobil-themen' );
unten.setAttribute( 'aria-labelledby', 'ckw-mobil-themen-titel' );
var h = el( 'h2', 'ckw-mobil-themen-titel', 'Themen' );
h.id = 'ckw-mobil-themen-titel';
unten.appendChild( h );
unten.appendChild( gruppenBlock( gruppen, 'ckw-mobil-themen-liste' ) );
haupt.appendChild( unten );
}
mw.hook( 'ckw.themen' ).fire( gruppen );
}
function ausLeiste( html ) {
var doc = new DOMParser().parseFromString( html, 'text/html' );
var gruppen = [];
Array.prototype.forEach.call( doc.querySelectorAll( '#mw-panel .vector-menu-portal' ), function ( p ) {
if ( p.id === 'p-tb' ) { return; }
var kopf = p.querySelector( '.vector-menu-heading' );
var links = [];
Array.prototype.forEach.call( p.querySelectorAll( 'li > a' ), function ( a ) {
var text = a.textContent.trim(), href = a.getAttribute( 'href' );
if ( text && href ) { links.push( [ text, href ] ); }
} );
if ( links.length ) { gruppen.push( { id: p.id, label: kopf ? kopf.textContent.trim() : '', links: links } ); }
} );
return gruppen;
}
$( function () {
try {
var gemerkt = null;
try { gemerkt = JSON.parse( localStorage.getItem( SPEICHER ) || 'null' ); } catch ( e ) {}
if ( gemerkt && gemerkt.gruppen && Date.now() - gemerkt.zeit < HALTBAR ) {
zeigen( gemerkt.gruppen );
return;
}
fetch( skript + '?title=Special:BlankPage&useskin=vector&useformat=desktop', { credentials: 'omit' } )
.then( function ( r ) { return r.ok ? r.text() : Promise.reject( r.status ); } )
.then( function ( html ) {
var gruppen = ausLeiste( html );
if ( !gruppen.length ) { return; }
try { localStorage.setItem( SPEICHER, JSON.stringify( { zeit: Date.now(), gruppen: gruppen } ) ); } catch ( e ) {}
zeigen( gruppen );
} )
.catch( function () {
if ( gemerkt && gemerkt.gruppen ) { zeigen( gemerkt.gruppen ); }
} );
} catch ( e ) {
mw.log.warn( 'CK-Wissen Handy-Navigation:', e );
}
} );
}() );
/* CK-Wissen (seit 25.09.2026): „Weiter im Thema“ am Ende jedes Artikels – vorherige und nächste Seite
aus derselben Gruppe der linken Leiste (MediaWiki:Sidebar), am Rechner und auf dem Handy.
Steht vor „Siehe auch“, „Literatur“, „Weblinks“ bzw. „Einzelnachweise“, sonst am Ende des Textes. */
( function () {
'use strict';
var ENDE = /^(Siehe auch|Literatur|Weblinks|Externe Links|Einzelnachweise|Quellen|Belege|Referenzen|Fußnoten|Anmerkungen)\b/i;
function titelAus( href ) {
if ( !href ) { return null; }
var m = href.match( /^[^?#]*\?title=([^&#]+)$/ ) || href.match( /\/index\.php\/([^?#]+)$/ );
if ( !m ) { return null; }
try { return decodeURIComponent( m[ 1 ] ).replace( / /g, '_' ); } catch ( e ) { return null; }
}
function el( tag, klasse, text ) {
var e = document.createElement( tag );
if ( klasse ) { e.className = klasse; }
if ( text ) { e.textContent = text; }
return e;
}
function karte( paar, richtung, klasse ) {
var a = el( 'a', 'ckw-weiter-karte ' + klasse );
a.href = paar[ 1 ];
a.appendChild( el( 'span', 'ckw-weiter-richtung', richtung ) );
a.appendChild( el( 'span', 'ckw-weiter-titel', paar[ 0 ] ) );
return a;
}
function weiter( gruppen ) {
if ( mw.config.get( 'wgAction' ) !== 'view' || mw.config.get( 'wgIsMainPage' ) ||
mw.config.get( 'wgNamespaceNumber' ) < 0 ||
mw.config.get( 'wgRevisionId' ) !== mw.config.get( 'wgCurRevisionId' ) ) { return; }
var namen = [ mw.config.get( 'wgPageName' ) ];
if ( mw.config.get( 'wgRedirectedFrom' ) ) { namen.push( String( mw.config.get( 'wgRedirectedFrom' ) ).replace( / /g, '_' ) ); }
var spalte = document.querySelector( '#mw-content-text > .mw-parser-output' );
if ( !spalte ) { return; }
var gruppe = null, liste = null, stelle = -1;
gruppen.some( function ( g ) {
if ( g.id === 'p-navigation' ) { return false; }
var seiten = g.links.filter( function ( p ) {
var t = titelAus( p[ 1 ] );
return t && !/^(Spezial|Special):/.test( t );
} );
for ( var i = 0; i < seiten.length; i++ ) {
if ( namen.indexOf( titelAus( seiten[ i ][ 1 ] ) ) !== -1 ) { gruppe = g; liste = seiten; stelle = i; return true; }
}
return false;
} );
if ( !gruppe || liste.length < 2 ) { return; }
var alt = spalte.querySelector( '.ckw-weiter' );
if ( alt ) { alt.parentNode.removeChild( alt ); }
var nav = el( 'nav', 'ckw-weiter' );
nav.setAttribute( 'aria-label', 'Weiter im Thema ' + gruppe.label );
var kopf = el( 'div', 'ckw-weiter-kopf', 'Weiter im Thema ' );
kopf.appendChild( el( 'b', null, gruppe.label ) );
kopf.appendChild( document.createTextNode( ' ' ) );
kopf.appendChild( el( 'span', 'ckw-weiter-stelle', '· Seite ' + ( stelle + 1 ) + ' von ' + liste.length ) );
nav.appendChild( kopf );
var karten = el( 'div', 'ckw-weiter-karten' );
if ( stelle > 0 ) { karten.appendChild( karte( liste[ stelle - 1 ], '← Zurück', 'ckw-weiter-zurueck' ) ); }
if ( stelle < liste.length - 1 ) { karten.appendChild( karte( liste[ stelle + 1 ], 'Weiter →', 'ckw-weiter-vor' ) ); }
else if ( stelle >= 2 ) { karten.appendChild( karte( liste[ 0 ], 'Zum Anfang des Themas ↺', 'ckw-weiter-vor' ) ); }
nav.appendChild( karten );
// Vor „Siehe auch“, „Literatur“, „Einzelnachweise“ … einsetzen, sonst ans Ende
var ziel = null;
Array.prototype.some.call( spalte.querySelectorAll( 'h2' ), function ( h ) {
if ( h.parentNode !== spalte ) { return false; }
var t = ( h.querySelector( '.mw-headline' ) || h ).textContent.trim();
if ( ENDE.test( t ) ) { ziel = h; return true; }
return false;
} );
if ( ziel ) { spalte.insertBefore( nav, ziel ); } else { spalte.appendChild( nav ); }
}
mw.hook( 'ckw.themen' ).add( function ( gruppen ) {
try { weiter( gruppen ); } catch ( e ) { mw.log.warn( 'CK-Wissen Weiter im Thema:', e ); }
} );
}() );
/* CK-Wissen (seit 25.09.2026): Tabellen, die nicht in die Seitenbreite passen, werden als Karten gezeigt.
Jede Zeile wird eine Karte, die Spaltenüberschriften stehen als kleine Beschriftung über jedem Wert.
Passt die Tabelle in die Breite, bleibt sie eine Tabelle. Gilt am Rechner und am Handy und prüft neu,
wenn sich die Breite ändert oder ein zugeklappter Abschnitt aufgeht. Nur für einfache Tabellen mit
Kopfzeile und ohne zusammengefasste Zellen (Zwischenüberschriften über die ganze Breite gehen). Abschalten für eine Tabelle: class="wikitable ckw-nie-karten".
Die Gestaltung steht in MediaWiki:Common.css unter „Zu breite Tabellen als Karten“. */
( function () {
'use strict';
if ( mw.config.get( 'wgAction' ) !== 'view' ) { return; }
function geeignet( t ) {
if ( t.classList.contains( 'ckw-nie-karten' ) || t.classList.contains( 'ckw-karten-bereit' ) ) { return false; }
if ( t.querySelector( 'table' ) || ( t.parentElement && t.parentElement.closest( 'table' ) ) ) { return false; }
var zeilen = t.rows;
if ( zeilen.length < 2 ) { return false; }
var kopf = zeilen[ 0 ].cells;
if ( kopf.length < 2 ) { return false; }
for ( var i = 0; i < kopf.length; i++ ) {
if ( kopf[ i ].tagName !== 'TH' || kopf[ i ].colSpan > 1 || kopf[ i ].rowSpan > 1 ) { return false; }
}
for ( var z = 1; z < zeilen.length; z++ ) {
var zellen = zeilen[ z ].cells;
// Zwischenüberschrift über die ganze Breite: wird in der Kartenansicht zur Überschrift
if ( zellen.length === 1 && zellen[ 0 ].colSpan === kopf.length && zellen[ 0 ].rowSpan === 1 ) { continue; }
if ( zellen.length !== kopf.length ) { return false; }
for ( var k = 0; k < zellen.length; k++ ) {
if ( zellen[ k ].colSpan > 1 || zellen[ k ].rowSpan > 1 ) { return false; }
}
}
return true;
}
function beschrifte( t ) {
var kopf = t.rows[ 0 ].cells;
t.rows[ 0 ].classList.add( 'ckw-karten-kopf' );
for ( var z = 1; z < t.rows.length; z++ ) {
var zellen = t.rows[ z ].cells;
if ( zellen.length === 1 && zellen[ 0 ].colSpan > 1 ) { t.rows[ z ].classList.add( 'ckw-karten-gruppe' ); continue; }
for ( var k = 0; k < zellen.length; k++ ) {
var name = kopf[ k ].textContent.replace( /\[\d+\]/g, '' ).replace( /\s+/g, ' ' ).trim();
zellen[ k ].setAttribute( 'data-ckw-spalte', name );
if ( !zellen[ k ].textContent.trim() && !zellen[ k ].querySelector( 'img' ) ) { zellen[ k ].classList.add( 'ckw-karten-leer' ); }
}
}
t.classList.add( 'ckw-karten-bereit' );
}
function pruefe( t ) {
var huelle = t.parentElement;
if ( !huelle ) { return; }
var platz = huelle.clientWidth;
if ( !platz ) { return; } // unsichtbar, etwa in einem zugeklappten Abschnitt
var war = t.classList.contains( 'ckw-karten' );
if ( war ) { t.classList.remove( 'ckw-karten' ); }
var zuBreit = t.scrollWidth > platz + 2;
if ( zuBreit ) { t.classList.add( 'ckw-karten' ); }
if ( huelle.classList.contains( 'ckw-tabelle' ) ) { huelle.classList.toggle( 'ckw-tabelle-karten', zuBreit ); }
}
function einrichten( wurzel ) {
var tabellen = [];
var liste = wurzel.querySelectorAll( '.mw-parser-output table.wikitable' );
for ( var i = 0; i < liste.length; i++ ) {
if ( geeignet( liste[ i ] ) ) { beschrifte( liste[ i ] ); tabellen.push( liste[ i ] ); }
}
if ( !tabellen.length ) { return; }
var alle = function () { tabellen.forEach( pruefe ); };
alle();
if ( window.ResizeObserver ) {
var breiten = new Map();
var ro = new ResizeObserver( function ( eintraege ) {
eintraege.forEach( function ( e ) {
var b = Math.round( e.contentRect.width );
if ( breiten.get( e.target ) === b ) { return; }
breiten.set( e.target, b );
tabellen.forEach( function ( t ) { if ( t.parentElement === e.target ) { pruefe( t ); } } );
} );
} );
tabellen.forEach( function ( t ) { if ( t.parentElement ) { ro.observe( t.parentElement ); } } );
} else {
var warte;
window.addEventListener( 'resize', function () { clearTimeout( warte ); warte = setTimeout( alle, 200 ); } );
}
}
window.ckwTabellenAlsKarten = einrichten;
// Immer die ganze Seite prüfen: Andere Skripte melden über denselben Haken auch kleine eingefügte Teile,
// und ein später angemeldeter Empfänger bekommt nur die letzte Meldung. Bereits erledigte Tabellen werden übersprungen.
var spaeter = function () { setTimeout( function () { einrichten( document ); }, 0 ); };
mw.hook( 'wikipage.content' ).add( spaeter );
$( spaeter );
}() );