Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
/**
 * Gadget-vereinform
 *
 * Formular zum Erzeugen des Grundgerüsts einer Vereinsseite.
 * Es wird NICHTS gespeichert oder angelegt - das Gadget gibt nur Wikicode aus,
 * den man kopiert und selbst auf die Seite einfügt.
 *
 * Aktiv auf der Seite "VereinForm".
 * Ankerpunkt (optional) auf dieser Seite:  <div id="verein-form-container"></div>
 */
( function () {
	'use strict';

	/* ------------------------------------------------------------------ *
	 * Konfiguration - hier und nur hier anpassen
	 * ------------------------------------------------------------------ */

	// Seite, auf der das Formular erscheint
	var TRIGGER_PAGE = 'VereinForm';

	// Kartenkategorie. Steuert BEIDES: data-filter im wikimap-div
	// UND das Feld "kategorie" im JSON-Block.
	// Muss exakt so in MediaWiki:WikiMap-Orte.json stehen.
	var KATEGORIE = 'Stockschießen';

	// Vorbelegung der Brotkrümel-Navigation
	var STD_RUBRIK    = 'Sport';          // Anker auf der Hauptseite
	var STD_OBERSEITE = 'Stockschießen';  // Seite eine Ebene darüber

	/* ------------------------------------------------------------------ */

	if ( mw.config.get( 'wgPageName' ) !== TRIGGER_PAGE ) {
		return;
	}

	/* --- Hilfsfunktionen ---------------------------------------------- */

	function v( val ) {
		return ( val || '' ).trim();
	}

	// Grad/Minuten/Sekunden -> Dezimalgrad
	function dms( g, m, s ) {
		var sign = g < 0 ? -1 : 1;
		return sign * ( Math.abs( g ) + ( m || 0 ) / 60 + ( s || 0 ) / 3600 );
	}

	/**
	 * Parst die gängigen Koordinatenformate:
	 *   47.69694, 16.00583      47.69694 16.00583      47,69694 16,00583
	 *   47.75N 16.08E           N 47.75 E 16.08
	 *   47°45'00.0"N 16°04'48.0"E        47°45.000'N 16°04.800'E
	 * Rückgabe { lat, lon } oder null.
	 */
	function parseKoordinaten( text ) {
		if ( !text ) {
			return null;
		}
		var s = String( text ).trim();

		// deutsche Dezimalkommas ("47,75 16,08") -> Punkte
		if ( /^-?\d+,\d+[\s;]+-?\d+,\d+/.test( s ) ) {
			s = s.replace( /,/g, '.' );
		}

		var hems = ( s.match( /[NSEWOnsewo]/g ) || [] ).map( function ( h ) {
			return h.toUpperCase();
		} );
		var nums = ( s.match( /-?\d+(?:\.\d+)?/g ) || [] ).map( parseFloat );

		if ( nums.length < 2 ) {
			return null;
		}

		var lat, lon;
		if ( nums.length >= 6 ) {           // Grad Minuten Sekunden
			lat = dms( nums[ 0 ], nums[ 1 ], nums[ 2 ] );
			lon = dms( nums[ 3 ], nums[ 4 ], nums[ 5 ] );
		} else if ( nums.length >= 4 ) {    // Grad Minuten
			lat = dms( nums[ 0 ], nums[ 1 ], 0 );
			lon = dms( nums[ 2 ], nums[ 3 ], 0 );
		} else {                            // Dezimalgrad
			lat = nums[ 0 ];
			lon = nums[ 1 ];
		}

		if ( hems.length >= 2 ) {
			if ( hems[ 0 ] === 'S' ) { lat = -Math.abs( lat ); }
			if ( hems[ 0 ] === 'N' ) { lat =  Math.abs( lat ); }
			if ( hems[ 1 ] === 'W' ) { lon = -Math.abs( lon ); }
			if ( hems[ 1 ] === 'E' || hems[ 1 ] === 'O' ) { lon = Math.abs( lon ); }
		}

		if ( !isFinite( lat ) || !isFinite( lon ) ) { return null; }
		if ( Math.abs( lat ) > 90 || Math.abs( lon ) > 180 ) { return null; }

		return { lat: lat, lon: lon };
	}

	// Zahl ohne überflüssige Nullen
	function fmt( n ) {
		return String( parseFloat( n.toFixed( 7 ) ) );
	}

	/* --- Formular aufbauen -------------------------------------------- */

	var felder = {};

	function feld( key, label, platzhalter, hinweis ) {
		var wrap  = document.createElement( 'div' );
		wrap.className = 'vf-feld';

		var lab   = document.createElement( 'label' );
		lab.textContent = label;

		var input = document.createElement( 'input' );
		input.type = 'text';
		input.placeholder = platzhalter || '';
		input.className = 'vf-input';

		lab.appendChild( input );
		wrap.appendChild( lab );

		if ( hinweis ) {
			var kl = document.createElement( 'div' );
			kl.className = 'vf-hinweis';
			kl.textContent = hinweis;
			wrap.appendChild( kl );
		}

		felder[ key ] = input;
		input.addEventListener( 'input', aktualisiere );
		return wrap;
	}

	function baueWikitext() {
		var name    = v( felder.name.value );
		var rubrik  = v( felder.rubrik.value )    || STD_RUBRIK;
		var ober    = v( felder.oberseite.value ) || STD_OBERSEITE;
		var website = v( felder.website.value );
		var adresse = v( felder.adresse.value );
		var koord   = parseKoordinaten( felder.koordinaten.value );

		var osm    = v( felder.osm.value );
		var comaps = v( felder.comaps.value );
		var gmaps  = v( felder.gmaps.value );

		var lat = koord ? fmt( koord.lat ) : '';
		var lon = koord ? fmt( koord.lon ) : '';

		// Automatische Links, wenn die Felder leer gelassen wurden
		if ( koord ) {
			if ( !osm ) {
				osm = 'https://www.openstreetmap.org/?mlat=' + lat + '&mlon=' + lon +
					'#map=17/' + lat + '/' + lon;
			}
			if ( !comaps ) {
				comaps = 'https://comaps.at/?lat=' + lat + '&lon=' + lon;
			}
			if ( !gmaps ) {
				gmaps = 'https://www.google.com/maps?q=' + lat + ',' + lon;
			}
		}

		var z = [];

		// Brotkrümel
		z.push( '[[Hauptseite]] > [[Hauptseite#' + rubrik + '|' + rubrik + ']] > [[' + ober + ']] </br>' );
		z.push( '</br>' );

		if ( website ) {
			z.push( '🌐 ' + website );
		}

		// Karte
		z.push( '<div class="wikimap" data-aktiv-ort="' + ( name || 'NAME' ) +
			'" data-filter="' + KATEGORIE + '"></div>' );

		// Ausschneide-Block für MediaWiki:WikiMap-Orte.json
		z.push( '' );
		z.push( '<!-- Eintrag für MediaWiki:WikiMap-Orte.json – dort einfügen, danach diesen Block hier löschen' );
		z.push( '\t\t{' );
		z.push( '\t\t\t"id": ' + JSON.stringify( name || 'NAME' ) + ',' );
		z.push( '\t\t\t"geo": "' + lat + ',' + lon + '",' );
		z.push( '\t\t\t"kategorie": ' + JSON.stringify( KATEGORIE ) );
		z.push( '\t\t},' );
		z.push( '-->' );
		z.push( '' );

		// Standortblock
		if ( adresse ) {
			z.push( '📍 ' + adresse );
		}
		if ( osm ) {
			z.push( '[[file:osm.png|24px|link=]] ' + osm );
		}
		if ( koord ) {
			z.push( '🧭 ' + lat + ', ' + lon );
		}
		if ( comaps ) {
			z.push( '[[file:CoMaps.png|24px|link=]] ' + comaps );
		}
		if ( gmaps ) {
			z.push( '[[file:GoogleMaps.png|24px|link=]] ' + gmaps );
		}

		return z.join( '\n' ) + '\n';
	}

	var ausgabe, status;

	function aktualisiere() {
		ausgabe.value = baueWikitext();

		var meldungen = [];
		if ( !v( felder.name.value ) ) {
			meldungen.push( 'Vereinsname fehlt' );
		}
		if ( v( felder.koordinaten.value ) && !parseKoordinaten( felder.koordinaten.value ) ) {
			meldungen.push( 'Koordinaten nicht erkannt' );
		} else if ( !v( felder.koordinaten.value ) ) {
			meldungen.push( 'ohne Koordinaten kein Kartenpin und keine Auto-Links' );
		}
		status.textContent = meldungen.length ? '⚠ ' + meldungen.join( ' · ' ) : '';
	}

	function init() {
		var ziel = document.getElementById( 'verein-form-container' ) ||
			document.getElementById( 'mw-content-text' );
		if ( !ziel ) {
			return;
		}

		var style = document.createElement( 'style' );
		style.textContent =
			'.vf-box{border:1px solid #a2a9b1;background:#f8f9fa;padding:1em;margin:1em 0;max-width:60em}' +
			'.vf-feld{margin:0 0 .7em}' +
			'.vf-feld label{display:block;font-weight:bold}' +
			'.vf-input{display:block;width:100%;box-sizing:border-box;padding:.3em;margin-top:.2em}' +
			'.vf-hinweis{font-size:.85em;color:#54595d;margin-top:.15em}' +
			'.vf-trenner{margin:1.2em 0 .6em;font-weight:bold;border-bottom:1px solid #c8ccd1}' +
			'.vf-ausgabe{width:100%;box-sizing:border-box;height:18em;font-family:monospace;font-size:.9em}' +
			'.vf-status{color:#b32424;margin:.4em 0;min-height:1.2em}';
		document.head.appendChild( style );

		var box = document.createElement( 'div' );
		box.className = 'vf-box';

		function trenner( text ) {
			var d = document.createElement( 'div' );
			d.className = 'vf-trenner';
			d.textContent = text;
			return d;
		}

		box.appendChild( trenner( 'Verein' ) );
		box.appendChild( feld( 'name', 'Vereinsname', '1. Neunkirchner ESK',
			'Wird zugleich Seitentitel und id auf der Karte – überall exakt gleich schreiben.' ) );
		box.appendChild( feld( 'rubrik', 'Navigation: Rubrik auf der Hauptseite', STD_RUBRIK ) );
		box.appendChild( feld( 'oberseite', 'Navigation: übergeordnete Seite', STD_OBERSEITE ) );
		box.appendChild( feld( 'website', '🌐 Website', 'https://…' ) );

		box.appendChild( trenner( 'Standort' ) );
		box.appendChild( feld( 'koordinaten', '🧭 Koordinaten',
			'47.72109887633516, 16.07317540344262',
			'Format egal – Dezimalgrad, Grad/Minuten/Sekunden, mit oder ohne N/E.' ) );
		box.appendChild( feld( 'adresse', '📍 Adresse', '2620 Neunkirchen, Musterstraße 1' ) );

		box.appendChild( trenner( 'Kartenlinks (leer lassen = aus Koordinaten erzeugen)' ) );
		box.appendChild( feld( 'osm', 'OpenStreetMap', 'leer = automatisch' ) );
		box.appendChild( feld( 'comaps', 'CoMaps', 'leer = automatisch' ) );
		box.appendChild( feld( 'gmaps', 'Google Maps', 'leer = automatisch' ) );

		box.appendChild( trenner( 'Wikicode' ) );

		status = document.createElement( 'div' );
		status.className = 'vf-status';
		box.appendChild( status );

		ausgabe = document.createElement( 'textarea' );
		ausgabe.className = 'vf-ausgabe';
		box.appendChild( ausgabe );

		var knopf = document.createElement( 'button' );
		knopf.type = 'button';
		knopf.textContent = 'In die Zwischenablage kopieren';
		knopf.style.marginTop = '.5em';
		knopf.addEventListener( 'click', function () {
			ausgabe.select();
			if ( navigator.clipboard && navigator.clipboard.writeText ) {
				navigator.clipboard.writeText( ausgabe.value );
			} else {
				document.execCommand( 'copy' );
			}
			knopf.textContent = 'kopiert ✓';
			setTimeout( function () {
				knopf.textContent = 'In die Zwischenablage kopieren';
			}, 1500 );
		} );
		box.appendChild( knopf );

		ziel.insertBefore( box, ziel.firstChild );
		aktualisiere();
	}

	if ( document.readyState === 'loading' ) {
		document.addEventListener( 'DOMContentLoaded', init );
	} else {
		init();
	}

}() );