/** * MYP Platform - UI Debug & Diagnostic Tool * Diagnostiziert und behebt UI-Probleme in Echtzeit */ (function() { 'use strict'; console.log('🔍 UI-Debug-Tool wird geladen...'); // Debug-Konfiguration const DEBUG_CONFIG = { logClicks: true, logErrors: true, logNavigation: true, showVisualFeedback: true, autoFix: true }; /** * Hauptinitialisierung des Debug-Tools */ function initDebugTool() { console.log('🚀 UI-Debug-Tool gestartet'); // 1. Click-Tracking setupClickTracking(); // 2. Error-Tracking setupErrorTracking(); // 3. Navigation-Tracking setupNavigationTracking(); // 4. Element-Diagnostik diagnoseElements(); // 5. Auto-Fix aktivieren if (DEBUG_CONFIG.autoFix) { setupAutoFix(); } // 6. Debug-Panel erstellen createDebugPanel(); console.log('✅ UI-Debug-Tool vollständig initialisiert'); } /** * Click-Tracking einrichten */ function setupClickTracking() { if (!DEBUG_CONFIG.logClicks) return; document.addEventListener('click', function(event) { const target = event.target; const info = { element: target.tagName, id: target.id || 'keine ID', classes: target.className || 'keine Klassen', href: target.href || 'kein href', type: target.type || 'kein type', dataAction: target.getAttribute('data-action') || 'keine data-action', clickable: isElementClickable(target), hasEventListeners: hasEventListeners(target) }; console.log('👆 KLICK ERKANNT:', info); // Visuelles Feedback if (DEBUG_CONFIG.showVisualFeedback) { showClickFeedback(target); } // Auto-Fix für nicht-klickbare Elemente if (!info.clickable && DEBUG_CONFIG.autoFix) { makeElementClickable(target); } }, true); } /** * Error-Tracking einrichten */ function setupErrorTracking() { if (!DEBUG_CONFIG.logErrors) return; window.addEventListener('error', function(event) { console.error('🚨 JAVASCRIPT-FEHLER:', { message: event.message, filename: event.filename, lineno: event.lineno, colno: event.colno, error: event.error }); }); window.addEventListener('unhandledrejection', function(event) { console.error('🚨 UNHANDLED PROMISE REJECTION:', event.reason); }); } /** * Navigation-Tracking einrichten */ function setupNavigationTracking() { if (!DEBUG_CONFIG.logNavigation) return; // Link-Klicks verfolgen document.addEventListener('click', function(event) { const link = event.target.closest('a'); if (link) { console.log('🔗 NAVIGATION:', { href: link.href, text: link.textContent.trim(), target: link.target, internal: isInternalLink(link.href) }); } }); } /** * Element-Diagnostik durchführen */ function diagnoseElements() { console.log('🔍 Starte Element-Diagnostik...'); // Alle potentiell klickbaren Elemente finden const clickableSelectors = [ 'a', 'button', '[role="button"]', '[data-action]', '.btn', '.clickable', '.nav-item', '.menu-item' ]; clickableSelectors.forEach(selector => { const elements = document.querySelectorAll(selector); console.log(`📊 ${selector}: ${elements.length} Elemente gefunden`); elements.forEach((element, index) => { const diagnosis = diagnoseElement(element); if (diagnosis.issues.length > 0) { console.warn(`⚠️ ${selector}[${index}] hat Probleme:`, diagnosis); } }); }); } /** * Einzelnes Element diagnostizieren */ function diagnoseElement(element) { const issues = []; const info = { tag: element.tagName, id: element.id, classes: element.className, href: element.href, type: element.type, disabled: element.disabled, hidden: element.hidden || element.style.display === 'none', hasEventListeners: hasEventListeners(element), clickable: isElementClickable(element) }; // Probleme identifizieren if (element.tagName === 'A' && (!element.href || element.href === '#')) { issues.push('Link ohne gültiges href-Attribut'); } if (element.tagName === 'BUTTON' && element.disabled) { issues.push('Button ist deaktiviert'); } if (!info.hasEventListeners && !element.href && !element.onclick) { issues.push('Keine Event-Listener oder onclick-Handler gefunden'); } if (info.hidden) { issues.push('Element ist versteckt'); } return { info, issues }; } /** * Auto-Fix einrichten */ function setupAutoFix() { console.log('🔧 Auto-Fix aktiviert'); // Alle problematischen Elemente finden und reparieren const problematicElements = document.querySelectorAll('a[href="#"], button:disabled, [data-action]:not([onclick])'); problematicElements.forEach(element => { fixElement(element); }); // Mutation Observer für dynamisch hinzugefügte Elemente const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { mutation.addedNodes.forEach(function(node) { if (node.nodeType === Node.ELEMENT_NODE) { const problematic = node.querySelectorAll('a[href="#"], button:disabled, [data-action]:not([onclick])'); problematic.forEach(fixElement); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); } /** * Element reparieren */ function fixElement(element) { console.log('🔧 Repariere Element:', element); if (element.tagName === 'A' && (!element.href || element.href === '#')) { // Link ohne href reparieren element.style.cursor = 'pointer'; element.addEventListener('click', function(e) { e.preventDefault(); console.log('🔗 Reparierter Link geklickt:', this); }); } if (element.tagName === 'BUTTON' && element.disabled) { // Deaktivierten Button aktivieren (falls sicher) if (!element.hasAttribute('data-keep-disabled')) { element.disabled = false; console.log('🔘 Button aktiviert:', element); } } if (element.hasAttribute('data-action') && !hasEventListeners(element)) { // Data-Action-Element ohne Event-Listener reparieren element.addEventListener('click', function(e) { e.preventDefault(); const action = this.getAttribute('data-action'); console.log('⚡ Data-Action ausgeführt:', action); // Versuche globale Handler zu finden if (window.MYP_UI_FIXES && window.MYP_UI_FIXES[action]) { window.MYP_UI_FIXES[action](); } }); } } /** * Debug-Panel erstellen */ function createDebugPanel() { const panel = document.createElement('div'); panel.id = 'debug-panel'; panel.style.cssText = ` position: fixed; top: 10px; right: 10px; width: 300px; background: rgba(0, 0, 0, 0.9); color: white; padding: 10px; border-radius: 5px; font-family: monospace; font-size: 12px; z-index: 10000; max-height: 400px; overflow-y: auto; display: none; `; panel.innerHTML = `
🔍 UI Debug Panel
✅ Debug-Tool aktiv
👆 Klicks werden verfolgt
🔧 Auto-Fix aktiviert
`; document.body.appendChild(panel); // Toggle-Button für Debug-Panel const toggleButton = document.createElement('button'); toggleButton.textContent = '🔍'; toggleButton.style.cssText = ` position: fixed; bottom: 20px; right: 20px; width: 50px; height: 50px; border-radius: 50%; background: #007bff; color: white; border: none; font-size: 20px; cursor: pointer; z-index: 10001; box-shadow: 0 2px 10px rgba(0,0,0,0.3); `; toggleButton.addEventListener('click', function() { const panel = document.getElementById('debug-panel'); panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; }); document.body.appendChild(toggleButton); } /** * Hilfsfunktionen */ function isElementClickable(element) { const style = window.getComputedStyle(element); return style.pointerEvents !== 'none' && style.display !== 'none' && style.visibility !== 'hidden' && !element.disabled; } function hasEventListeners(element) { // Vereinfachte Prüfung - in der Realität schwer zu detektieren return element.onclick !== null || element.getAttribute('onclick') !== null || element.hasAttribute('data-action'); } function isInternalLink(href) { if (!href) return false; return href.startsWith('/') || href.startsWith('./') || href.startsWith('../') || href.includes(window.location.hostname); } function makeElementClickable(element) { if (!isElementClickable(element)) { element.style.cursor = 'pointer'; element.style.pointerEvents = 'auto'; if (!hasEventListeners(element)) { element.addEventListener('click', function(e) { console.log('🔧 Auto-Fix Klick auf:', this); }); } } } function showClickFeedback(element) { const feedback = document.createElement('div'); feedback.style.cssText = ` position: absolute; background: rgba(0, 255, 0, 0.3); border: 2px solid #00ff00; pointer-events: none; z-index: 9999; border-radius: 3px; `; const rect = element.getBoundingClientRect(); feedback.style.left = rect.left + 'px'; feedback.style.top = rect.top + 'px'; feedback.style.width = rect.width + 'px'; feedback.style.height = rect.height + 'px'; document.body.appendChild(feedback); setTimeout(() => { feedback.remove(); }, 500); } /** * Initialisierung */ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initDebugTool); } else { initDebugTool(); } // Globale Debug-Funktionen window.DEBUG_UI = { diagnose: diagnoseElements, fix: setupAutoFix, toggle: function() { const panel = document.getElementById('debug-panel'); if (panel) { panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; } } }; console.log('✅ UI-Debug-Tool geladen'); })();