// VBB Netz Status - Changelog-Loader + Markdown-Parser // ========================================== // UPDATES VIEW - CHANGELOG LOADER // ========================================== // ========================================== // CHANGELOG LOADER - VERBESSERT // Fetcht CHANGELOG.md und konvertiert Markdown zu HTML // ========================================== let changelogState = 'idle'; // 'idle' | 'loading' | 'loaded' async function loadChangelog() { // Guard: verhindert parallele/mehrfache Ladungen if (changelogState !== 'idle') return; changelogState = 'loading'; const container = document.getElementById('changelogContent'); try { // Lade CHANGELOG.md const response = await fetch('CHANGELOG.md'); if (!response.ok) throw new Error('CHANGELOG.md nicht gefunden'); const markdown = await response.text(); // Konvertiere Markdown zu HTML const html = markdownToHtml(markdown); // Wrapper mit changelog-container Klasse container.innerHTML = `
⚠️ Changelog konnte nicht geladen werden
${escapeHtml(error.message)}
${escapeHtml(codeBlockContent)}`;
codeBlockContent = '';
continue;
}
}
// Innerhalb Code-Block
if (inCodeBlock) {
codeBlockContent += line + '\n';
continue;
}
// Leere Zeile - Schließe Listen
if (line.trim() === '') {
if (inList) {
html += '';
inList = false;
}
if (inOrderedList) {
html += '';
inOrderedList = false;
}
continue;
}
// Überschriften (# ## ### ####)
if (line.match(/^(#{1,6})\s+(.+)$/)) {
const match = line.match(/^(#{1,6})\s+(.+)$/);
const level = match[1].length;
const text = parseInline(match[2]);
if (inList) {
html += '';
inList = false;
}
if (inOrderedList) {
html += '';
inOrderedList = false;
}
html += `${text}`; continue; } // Normaler Paragraph if (line.trim() !== '') { if (inList) { html += ''; inList = false; } if (inOrderedList) { html += ''; inOrderedList = false; } const text = parseInline(line); html += `
${text}
`; } } // Schließe offene Listen am Ende if (inList) html += ''; if (inOrderedList) html += ''; return html; } // ========================================== // INLINE MARKDOWN PARSER // ========================================== function parseInline(text) { // Links [text](url) text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); // Inline Code `code` text = text.replace(/`([^`]+)`/g, '$1');
// Bold **text** oder __text__
text = text.replace(/\*\*([^*]+)\*\*/g, '$1');
text = text.replace(/__([^_]+)__/g, '$1');
// Italic *text* oder _text_ (aber nicht ** oder __)
text = text.replace(/(?$1');
text = text.replace(/(?$1');
// Strikethrough ~~text~~
text = text.replace(/~~([^~]+)~~/g, '