MediaWiki:Common.js: Unterschied zwischen den Versionen

Aus Stadtbahn-Wiki Bielefeld
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
Update Common.js v10 (GleisEditor)
 
Zeile 1: Zeile 1:
/* Das folgende JavaScript wird für alle Benutzer geladen. */
/* Das folgende JavaScript wird für alle Benutzer geladen. */
var monthsNames = ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];
(function () {
    var mw = window.mediaWiki || window.mw;
    var $ = window.jQuery;
    if (!mw || !$) return;


function addDatepickerHandler(event) {
    console.log('MediaWiki:Common.js (v9) aktiv');
var multidatepicker = event.target.parentNode.parentNode.parentNode.parentNode.getElementsByClassName('multidatepicker')[0];
addDatepicker(multidatepicker);


}
    /* LEAFLET INTERCEPTOR */
    (function interceptLeaflet() {
        if (window.L && window.L.map && !window.L.map._isIntercepted) {
            var originalLMap = window.L.map;
            window.L.map = function (id, options) {
                var map = originalLMap.apply(this, arguments);
                var el = (typeof id === 'string') ? document.getElementById(id) : id;
                if (el) {
                    $(el).data('captured-map', map);
                    console.log('GleisEditor: Map-Instanz abgefangen.');
                }
                return map;
            };
            window.L.map._isIntercepted = true;
            console.log('GleisEditor: Leaflet Interceptor bereit.');
        } else if (!window.L || !window.L.map) {
            setTimeout(interceptLeaflet, 50);
        }
    })();


function removeDatepickerHandler(event) {
    // --- Standard MediaWiki:Common.js Funktionen ---
    // (Vollständig erhalten aus Vorversionen)
    var monthsNames = ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];
    function addDatepickerHandler(event) { var multidatepicker = event.target.parentNode.parentNode.parentNode.parentNode.getElementsByClassName('multidatepicker')[0]; addDatepicker(multidatepicker); }
    function removeDatepickerHandler(event) { event.target.parentNode.parentNode.parentNode.removeChild(event.target.parentNode.parentNode); parseInputsToStrings(); }
    function initMultiDatepickers() {
        var multidatepickers = document.getElementsByClassName('multidatepicker');
        for (var i = 0; i < multidatepickers.length; i++) {
            var addButtonRow = document.createElement('tr'); var addButtonFirstTD = document.createElement('td'); addButtonRow.appendChild(addButtonFirstTD); var addButtonSecondTD = document.createElement('td');
            var addButtonWrapperSpan = document.createElement('span'); addButtonWrapperSpan.className = 'oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-flaggedElement-primary oo-ui-flaggedElement-progressive oo-ui-buttonInputWidget';
            var addAnotherButton = document.createElement('button'); addAnotherButton.className = 'oo-ui-inputWidget-input oo-ui-buttonElement-button'; addAnotherButton.innerHTML = '+'; addAnotherButton.type = 'button';
            addButtonWrapperSpan.appendChild(addAnotherButton); addButtonSecondTD.appendChild(addButtonWrapperSpan); addButtonRow.appendChild(addButtonSecondTD); addAnotherButton.onclick = addDatepickerHandler;
            multidatepickers[i].parentNode.parentNode.appendChild(addButtonRow);
            var stringValues = multidatepickers[i].value.split(',');
            for (var j = 0; j < stringValues.length; j++) { var datepicker = makeDatepickerRow(stringValues[j]); multidatepickers[i].parentNode.parentNode.appendChild(datepicker); }
            multidatepickers[i].type = 'hidden';
        }
    }
    function addDatepicker(multidatepicker) { var datepicker = makeDatepickerRow(''); multidatepicker.parentNode.parentNode.appendChild(datepicker); }
    function parseInputsToStrings() {
        var multidatepickers = document.getElementsByClassName('multidatepicker');
        for (var i = 0; i < multidatepickers.length; i++) {
            multidatepickers[i].value = ''; var datepickers = multidatepickers[i].parentNode.parentNode.getElementsByClassName('dateInput'); var finalStringValue = '';
            for (var j = 0; j < datepickers.length; j++) {
                var yearInputValue = datepickers[j].getElementsByClassName('yearInput')[0].value; var monthInputValue = datepickers[j].getElementsByClassName('monthInput')[0].value; var dayInputValue = datepickers[j].getElementsByClassName('dayInput')[0].value;
                var stringValue = yearInputValue; if (monthInputValue != '') { stringValue = stringValue + '/' + monthInputValue; if (dayInputValue != '') { stringValue = stringValue + '/' + dayInputValue; } }
                finalStringValue = finalStringValue + ',' + stringValue;
            }
            multidatepickers[i].value = finalStringValue.substr(1);
        }
    }
    function makeDatepickerRow(stringValue) {
        var year = ''; var month = ''; var day = ''; if (stringValue != null && stringValue != '') { var splitString = stringValue.split('/'); if (stringValue.length == 4) year = stringValue; if (stringValue.length == 7) { year = splitString[0]; month = splitString[1]; } if (stringValue.length == 10) { year = splitString[0]; month = splitString[1]; day = splitString[2]; } }
        var multiDateContainer = document.createElement('span'); multiDateContainer.className = 'dateInput'; var dayField = document.createElement('input'); dayField.size = 2; dayField.className = 'dayInput'; dayField.value = day; dayField.oninput = parseInputsToStrings; multiDateContainer.appendChild(dayField);
        var monthField = document.createElement('select'); monthField.className = 'monthInput'; var noMonthOption = document.createElement('option'); monthField.appendChild(noMonthOption);
        for (var i = 1; i < 13; i++) { var monthOption = document.createElement('option'); var monthString = String(i).padStart(2, '0'); monthOption.value = monthString; monthOption.innerText = monthsNames[i - 1]; if (month == monthString) monthOption.setAttribute('selected', 'selected'); monthField.appendChild(monthOption); }
        monthField.oninput = parseInputsToStrings; multiDateContainer.appendChild(monthField);
        var yearField = document.createElement('input'); yearField.size = 4; yearField.value = year; yearField.className = 'yearInput'; yearField.oninput = parseInputsToStrings; multiDateContainer.appendChild(yearField);
        var wrapperTR = document.createElement('tr'); var wrapperFirstTD = document.createElement('td'); var wrapperSecondTD = document.createElement('td'); wrapperTR.appendChild(wrapperFirstTD);
        var deleteButtonWrapper = document.createElement('span'); deleteButtonWrapper.className = 'oo-ui-buttonElement-button oo-ui-buttonElement-frameless'; var deleteButton = document.createElement('a'); deleteButton.className = 'oo-ui-iconElement-icon oo-ui-icon-trash oo-ui-image-destructive'; deleteButton.onclick = removeDatepickerHandler; deleteButtonWrapper.appendChild(deleteButton);
        wrapperSecondTD.appendChild(multiDateContainer); wrapperSecondTD.appendChild(deleteButtonWrapper); wrapperTR.appendChild(wrapperSecondTD); return wrapperTR;
    }
    function initColorpickers() { var colorpickers = document.getElementsByClassName('colorpicker'); for (var i = 0; i < colorpickers.length; i++) { colorpickers[i].setAttribute('type', 'color'); colorpickers[i].value = '#' + colorpickers[i].value; } }
    function initCoordsPasteHook() {
        var inputs = document.getElementsByClassName('pfCoordsInput');
        for (var i = 0; i < inputs.length; i++) {
            inputs[i].addEventListener('paste', function (e) {
                var paste = (e.clipboardData || window.clipboardData).getData('text');
                if (paste.startsWith('https://maps.apple.com/place?/&ll=')) { e.preventDefault(); e.target.value = decodeURIComponent(paste.substring(34)); }
            });
        }
    }
    $(function () { initMultiDatepickers(); initColorpickers(); initCoordsPasteHook(); });


event.target.parentNode.parentNode.parentNode.removeChild(event.target.parentNode.parentNode);
    /* GleisEditor Logic v9 */
parseInputsToStrings();
    function setupGleisEditor() {
}
        const $mapCanvas = $('.pfMapCanvas');
        if (!$mapCanvas.length) return;


        let attempts = 0;
        const checkLeaflet = setInterval(function () {
            attempts++;
            const mapContainer = $mapCanvas[0];
            let map = mapContainer._leaflet_map || $(mapContainer).data('captured-map') || $(mapContainer).data('leaflet');


function initMultiDatepickers() {
            if (map) {
                console.log('GleisEditor: Map gefunden.');
                clearInterval(checkLeaflet);


var multidatepickers = document.getElementsByClassName('multidatepicker');
                // PF-Koordinaten-Input des Map-Dummy-Feldes ausblenden
                $mapCanvas.parent().find('.pfCoordsInput').hide();
                $mapCanvas.parent().find('.pfCoordsInputHelpers').hide();


for (var i=0; i<multidatepickers.length; i++) {
                initGleisEditor(map);
            } else if (attempts > 60) {
                clearInterval(checkLeaflet);
            }
        }, 500);
    }


// Add button
    function initGleisEditor(map) {
var addButtonRow = document.createElement('tr');
        if (map._gleisEditorInitialized) return;
var addButtonFirstTD = document.createElement('td');
        map._gleisEditorInitialized = true;
addButtonRow.appendChild(addButtonFirstTD);
var addButtonSecondTD = document.createElement('td');


var addButtonWrapperSpan = document.createElement('span');
        console.log('GleisEditor: Initialisiere Polyline-Modus v10...');
addButtonWrapperSpan.className = 'oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-flaggedElement-primary oo-ui-flaggedElement-progressive oo-ui-buttonInputWidget';
        map.off('click');


        let markerLayer = L.layerGroup().addTo(map);
        let polyline = L.polyline([], { color: 'black', weight: 4, opacity: 0.8 }).addTo(map);
        let markers = [];


var addAnotherButton = document.createElement('button');
        function updatePolyline() { polyline.setLatLngs(markers.map(m => m.getLatLng())); }
addAnotherButton.className = 'oo-ui-inputWidget-input oo-ui-buttonElement-button';
addAnotherButton.innerHTML = '+';
addAnotherButton.type = 'button';


addButtonWrapperSpan.appendChild(addAnotherButton);
        function updateAllFields() {
            const coords = markers.map(m => {
                const ll = m.getLatLng();
                return ll.lat.toFixed(6) + ',' + ll.lng.toFixed(6);
            }).join(';');


addButtonSecondTD.appendChild(addButtonWrapperSpan);
            // Aggressives Targetting: Alle Elemente mit Name 'Gleis[Koordinaten]' finden.
            // PageForms erstellt oft ein sichtbares und ein verstecktes Feld.
            const $targets = $('[name="Gleis[Koordinaten]"]');
            $targets.val(coords).trigger('change');


addButtonRow.appendChild(addButtonSecondTD);
            console.log('GleisEditor: ' + $targets.length + ' Datenfelder aktualisiert:', coords);
        }


addAnotherButton.onclick = addDatepickerHandler;
        function addMarker(lat, lng) {
            const marker = L.marker([lat, lng], { draggable: true }).addTo(markerLayer);
            marker.on('drag', function () { updatePolyline(); updateAllFields(); });
            marker.on('contextmenu', function (e) {
                if (e.originalEvent) e.originalEvent.preventDefault();
                markerLayer.removeLayer(marker);
                markers = markers.filter(m => m !== marker);
                updatePolyline(); updateAllFields();
                return false;
            });
            markers.push(marker);
            return marker;
        }


multidatepickers[i].parentNode.parentNode.appendChild(addButtonRow);
        // Vorhandene Daten aus dem ersten gefundenen Koordinaten-Feld laden
        const initialVal = $('[name="Gleis[Koordinaten]"]').first().val();
        if (initialVal && initialVal.includes(',')) {
            initialVal.split(';').forEach(pair => {
                const p = pair.trim().split(',').map(Number);
                if (p.length === 2 && !isNaN(p[0])) addMarker(p[0], p[1]);
            });
            updatePolyline();
        }


        map.on('click', function (e) {
            addMarker(e.latlng.lat, e.latlng.lng);
            updatePolyline();
            updateAllFields();
        });


        console.log('GleisEditor: BEREIT (v9).');
    }


var stringValues = multidatepickers[i].value.split(',');
    $(setupGleisEditor);
for (j=0; j<stringValues.length; j++) {
    mw.hook('wikipage.content').add(setupGleisEditor);
var datepicker = makeDatepickerRow(stringValues[j]);


multidatepickers[i].parentNode.parentNode.appendChild(datepicker);
})();
 
}
multidatepickers[i].type='hidden';
}
 
}
 
function addDatepicker(multidatepicker) {
var datepicker = makeDatepickerRow('');
multidatepicker.parentNode.parentNode.appendChild(datepicker);
 
}
 
 
function parseInputsToStrings() {
console.log('parsing');
var multidatepickers = document.getElementsByClassName('multidatepicker');
console.log('got ' + multidatepickers.length + ' multidatepickers');
for (var i=0; i<multidatepickers.length; i++) {
multidatepickers[i].value = '';
 
var datepickers = multidatepickers[i].parentNode.parentNode.getElementsByClassName('dateInput');
console.log(i + 'th multidatepicker has ' + datepickers.length + ' values');
var finalStringValue = '';
for (var j=0; j < datepickers.length;j++) {
var yearInputValue = datepickers[j].getElementsByClassName('yearInput')[0].value;
var monthInputValue = datepickers[j].getElementsByClassName('monthInput')[0].value;
var dayInputValue = datepickers[j].getElementsByClassName('dayInput')[0].value;
 
var stringValue = yearInputValue;
if (monthInputValue != '') {
stringValue = stringValue + '/' + monthInputValue;
if (dayInputValue != '') {
stringValue = stringValue + '/' + dayInputValue;
}
}
 
finalStringValue = finalStringValue + ',' + stringValue;
}
console.log('setting value ' + finalStringValue);
multidatepickers[i].value = finalStringValue.substr(1);
 
}
}
function makeDatepickerRow(stringValue) {
var year = '';
var month = '';
var day = '';
if (stringValue != null && stringValue != undefined && stringValue != '') {
var splitString = stringValue.split('/');
 
if (stringValue.length == 4) {
year = stringValue;
}
if (stringValue.length == 7) {
year = splitString[0];
month = splitString[1];
}
if (stringValue.length == 10) {
year = splitString[0];
month = splitString[1];
day = splitString[2];
}
}
var multiDateContainer = document.createElement('span');
multiDateContainer.className = 'dateInput';
 
var dayField = document.createElement('input');
dayField.name = 'day';
dayField.type='text';
dayField.size=2;
dayField.className = 'dayInput';
 
dayField.value = day;
dayField.oninput = parseInputsToStrings;
 
multiDateContainer.appendChild(dayField);
 
var monthField = document.createElement('select');
monthField.className = 'monthInput';
var noMonthOption = document.createElement('option');
monthField.appendChild(noMonthOption);
for (var i=1; i<13; i++) {
var monthOption = document.createElement('option');
var monthString = String(i).padStart(2, '0');
monthOption.value = monthString;
monthOption.innerText = monthsNames[i-1];
if (month == monthString) {
monthOption.setAttribute('selected', 'selected');
}
monthField.appendChild(monthOption);
}
monthField.oninput = parseInputsToStrings;
 
multiDateContainer.appendChild(monthField);
 
var yearField = document.createElement('input');
yearField.name = 'year';
yearField.size = 4;
yearField.value = year;
yearField.className = 'yearInput';
yearField.oninput = parseInputsToStrings;
 
multiDateContainer.appendChild(yearField);
 
 
var wrapperTR = document.createElement('tr');
var wrapperFirstTD = document.createElement('td');
var wrapperSecondTD = document.createElement('td');
 
wrapperTR.appendChild(wrapperFirstTD);
 
var deleteButtonWrapper = document.createElement('span');
deleteButtonWrapper.className = 'oo-ui-buttonElement-button oo-ui-buttonElement-frameless';
 
var deleteButton = document.createElement('a');
deleteButton.type = 'button';
deleteButton.className = 'oo-ui-iconElement-icon oo-ui-icon-trash oo-ui-image-destructive';
deleteButton.onclick = removeDatepickerHandler;
 
deleteButtonWrapper.appendChild(deleteButton);
wrapperSecondTD.appendChild(multiDateContainer);
wrapperSecondTD.appendChild(deleteButtonWrapper);
wrapperTR.appendChild(wrapperSecondTD);
 
return wrapperTR;
 
}
 
function initColorpickers() {
var colorpickers = document.getElementsByClassName('colorpicker');
for (var i=0; i<colorpickers.length; i++) {
colorpickers[i].setAttribute('type', 'color');
colorpickers[i].value = '#' + colorpickers[i].value;
}
}
 
 
function initCoordsPasteHook() {
var inputs = document.getElementsByClassName('pfCoordsInput');
for (var i=0; i<inputs.length; i++) {
inputs[i].addEventListener('paste', function (e) {
    var paste = (event.clipboardData || window.clipboardData).getData('text');
 
var elem = e.target;
console.log('onPaste coords');
if (paste.startsWith('https://maps.apple.com/place?/&ll=')) {
e.preventDefault();
// is Apple maps
console.log('apple maps paste');
var coords = decodeURIComponent(paste.substring(34));
elem.value = coords;
}
 
});
 
}
}
 
 
initMultiDatepickers();
initColorpickers();
initCoordsPasteHook();

Aktuelle Version vom 4. März 2026, 13:10 Uhr

/* Das folgende JavaScript wird für alle Benutzer geladen. */
(function () {
    var mw = window.mediaWiki || window.mw;
    var $ = window.jQuery;
    if (!mw || !$) return;

    console.log('MediaWiki:Common.js (v9) aktiv');

    /* LEAFLET INTERCEPTOR */
    (function interceptLeaflet() {
        if (window.L && window.L.map && !window.L.map._isIntercepted) {
            var originalLMap = window.L.map;
            window.L.map = function (id, options) {
                var map = originalLMap.apply(this, arguments);
                var el = (typeof id === 'string') ? document.getElementById(id) : id;
                if (el) {
                    $(el).data('captured-map', map);
                    console.log('GleisEditor: Map-Instanz abgefangen.');
                }
                return map;
            };
            window.L.map._isIntercepted = true;
            console.log('GleisEditor: Leaflet Interceptor bereit.');
        } else if (!window.L || !window.L.map) {
            setTimeout(interceptLeaflet, 50);
        }
    })();

    // --- Standard MediaWiki:Common.js Funktionen ---
    // (Vollständig erhalten aus Vorversionen)
    var monthsNames = ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];
    function addDatepickerHandler(event) { var multidatepicker = event.target.parentNode.parentNode.parentNode.parentNode.getElementsByClassName('multidatepicker')[0]; addDatepicker(multidatepicker); }
    function removeDatepickerHandler(event) { event.target.parentNode.parentNode.parentNode.removeChild(event.target.parentNode.parentNode); parseInputsToStrings(); }
    function initMultiDatepickers() {
        var multidatepickers = document.getElementsByClassName('multidatepicker');
        for (var i = 0; i < multidatepickers.length; i++) {
            var addButtonRow = document.createElement('tr'); var addButtonFirstTD = document.createElement('td'); addButtonRow.appendChild(addButtonFirstTD); var addButtonSecondTD = document.createElement('td');
            var addButtonWrapperSpan = document.createElement('span'); addButtonWrapperSpan.className = 'oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-flaggedElement-primary oo-ui-flaggedElement-progressive oo-ui-buttonInputWidget';
            var addAnotherButton = document.createElement('button'); addAnotherButton.className = 'oo-ui-inputWidget-input oo-ui-buttonElement-button'; addAnotherButton.innerHTML = '+'; addAnotherButton.type = 'button';
            addButtonWrapperSpan.appendChild(addAnotherButton); addButtonSecondTD.appendChild(addButtonWrapperSpan); addButtonRow.appendChild(addButtonSecondTD); addAnotherButton.onclick = addDatepickerHandler;
            multidatepickers[i].parentNode.parentNode.appendChild(addButtonRow);
            var stringValues = multidatepickers[i].value.split(',');
            for (var j = 0; j < stringValues.length; j++) { var datepicker = makeDatepickerRow(stringValues[j]); multidatepickers[i].parentNode.parentNode.appendChild(datepicker); }
            multidatepickers[i].type = 'hidden';
        }
    }
    function addDatepicker(multidatepicker) { var datepicker = makeDatepickerRow(''); multidatepicker.parentNode.parentNode.appendChild(datepicker); }
    function parseInputsToStrings() {
        var multidatepickers = document.getElementsByClassName('multidatepicker');
        for (var i = 0; i < multidatepickers.length; i++) {
            multidatepickers[i].value = ''; var datepickers = multidatepickers[i].parentNode.parentNode.getElementsByClassName('dateInput'); var finalStringValue = '';
            for (var j = 0; j < datepickers.length; j++) {
                var yearInputValue = datepickers[j].getElementsByClassName('yearInput')[0].value; var monthInputValue = datepickers[j].getElementsByClassName('monthInput')[0].value; var dayInputValue = datepickers[j].getElementsByClassName('dayInput')[0].value;
                var stringValue = yearInputValue; if (monthInputValue != '') { stringValue = stringValue + '/' + monthInputValue; if (dayInputValue != '') { stringValue = stringValue + '/' + dayInputValue; } }
                finalStringValue = finalStringValue + ',' + stringValue;
            }
            multidatepickers[i].value = finalStringValue.substr(1);
        }
    }
    function makeDatepickerRow(stringValue) {
        var year = ''; var month = ''; var day = ''; if (stringValue != null && stringValue != '') { var splitString = stringValue.split('/'); if (stringValue.length == 4) year = stringValue; if (stringValue.length == 7) { year = splitString[0]; month = splitString[1]; } if (stringValue.length == 10) { year = splitString[0]; month = splitString[1]; day = splitString[2]; } }
        var multiDateContainer = document.createElement('span'); multiDateContainer.className = 'dateInput'; var dayField = document.createElement('input'); dayField.size = 2; dayField.className = 'dayInput'; dayField.value = day; dayField.oninput = parseInputsToStrings; multiDateContainer.appendChild(dayField);
        var monthField = document.createElement('select'); monthField.className = 'monthInput'; var noMonthOption = document.createElement('option'); monthField.appendChild(noMonthOption);
        for (var i = 1; i < 13; i++) { var monthOption = document.createElement('option'); var monthString = String(i).padStart(2, '0'); monthOption.value = monthString; monthOption.innerText = monthsNames[i - 1]; if (month == monthString) monthOption.setAttribute('selected', 'selected'); monthField.appendChild(monthOption); }
        monthField.oninput = parseInputsToStrings; multiDateContainer.appendChild(monthField);
        var yearField = document.createElement('input'); yearField.size = 4; yearField.value = year; yearField.className = 'yearInput'; yearField.oninput = parseInputsToStrings; multiDateContainer.appendChild(yearField);
        var wrapperTR = document.createElement('tr'); var wrapperFirstTD = document.createElement('td'); var wrapperSecondTD = document.createElement('td'); wrapperTR.appendChild(wrapperFirstTD);
        var deleteButtonWrapper = document.createElement('span'); deleteButtonWrapper.className = 'oo-ui-buttonElement-button oo-ui-buttonElement-frameless'; var deleteButton = document.createElement('a'); deleteButton.className = 'oo-ui-iconElement-icon oo-ui-icon-trash oo-ui-image-destructive'; deleteButton.onclick = removeDatepickerHandler; deleteButtonWrapper.appendChild(deleteButton);
        wrapperSecondTD.appendChild(multiDateContainer); wrapperSecondTD.appendChild(deleteButtonWrapper); wrapperTR.appendChild(wrapperSecondTD); return wrapperTR;
    }
    function initColorpickers() { var colorpickers = document.getElementsByClassName('colorpicker'); for (var i = 0; i < colorpickers.length; i++) { colorpickers[i].setAttribute('type', 'color'); colorpickers[i].value = '#' + colorpickers[i].value; } }
    function initCoordsPasteHook() {
        var inputs = document.getElementsByClassName('pfCoordsInput');
        for (var i = 0; i < inputs.length; i++) {
            inputs[i].addEventListener('paste', function (e) {
                var paste = (e.clipboardData || window.clipboardData).getData('text');
                if (paste.startsWith('https://maps.apple.com/place?/&ll=')) { e.preventDefault(); e.target.value = decodeURIComponent(paste.substring(34)); }
            });
        }
    }
    $(function () { initMultiDatepickers(); initColorpickers(); initCoordsPasteHook(); });

    /* GleisEditor Logic v9 */
    function setupGleisEditor() {
        const $mapCanvas = $('.pfMapCanvas');
        if (!$mapCanvas.length) return;

        let attempts = 0;
        const checkLeaflet = setInterval(function () {
            attempts++;
            const mapContainer = $mapCanvas[0];
            let map = mapContainer._leaflet_map || $(mapContainer).data('captured-map') || $(mapContainer).data('leaflet');

            if (map) {
                console.log('GleisEditor: Map gefunden.');
                clearInterval(checkLeaflet);

                // PF-Koordinaten-Input des Map-Dummy-Feldes ausblenden
                $mapCanvas.parent().find('.pfCoordsInput').hide();
                $mapCanvas.parent().find('.pfCoordsInputHelpers').hide();

                initGleisEditor(map);
            } else if (attempts > 60) {
                clearInterval(checkLeaflet);
            }
        }, 500);
    }

    function initGleisEditor(map) {
        if (map._gleisEditorInitialized) return;
        map._gleisEditorInitialized = true;

        console.log('GleisEditor: Initialisiere Polyline-Modus v10...');
        map.off('click');

        let markerLayer = L.layerGroup().addTo(map);
        let polyline = L.polyline([], { color: 'black', weight: 4, opacity: 0.8 }).addTo(map);
        let markers = [];

        function updatePolyline() { polyline.setLatLngs(markers.map(m => m.getLatLng())); }

        function updateAllFields() {
            const coords = markers.map(m => {
                const ll = m.getLatLng();
                return ll.lat.toFixed(6) + ',' + ll.lng.toFixed(6);
            }).join(';');

            // Aggressives Targetting: Alle Elemente mit Name 'Gleis[Koordinaten]' finden.
            // PageForms erstellt oft ein sichtbares und ein verstecktes Feld.
            const $targets = $('[name="Gleis[Koordinaten]"]');
            $targets.val(coords).trigger('change');

            console.log('GleisEditor: ' + $targets.length + ' Datenfelder aktualisiert:', coords);
        }

        function addMarker(lat, lng) {
            const marker = L.marker([lat, lng], { draggable: true }).addTo(markerLayer);
            marker.on('drag', function () { updatePolyline(); updateAllFields(); });
            marker.on('contextmenu', function (e) {
                if (e.originalEvent) e.originalEvent.preventDefault();
                markerLayer.removeLayer(marker);
                markers = markers.filter(m => m !== marker);
                updatePolyline(); updateAllFields();
                return false;
            });
            markers.push(marker);
            return marker;
        }

        // Vorhandene Daten aus dem ersten gefundenen Koordinaten-Feld laden
        const initialVal = $('[name="Gleis[Koordinaten]"]').first().val();
        if (initialVal && initialVal.includes(',')) {
            initialVal.split(';').forEach(pair => {
                const p = pair.trim().split(',').map(Number);
                if (p.length === 2 && !isNaN(p[0])) addMarker(p[0], p[1]);
            });
            updatePolyline();
        }

        map.on('click', function (e) {
            addMarker(e.latlng.lat, e.latlng.lng);
            updatePolyline();
            updateAllFields();
        });

        console.log('GleisEditor: BEREIT (v9).');
    }

    $(setupGleisEditor);
    mw.hook('wikipage.content').add(setupGleisEditor);

})();