/* /assets/js/bridge/categorization-master.js (FINALE KORREKTUR V3: Entfernt aggressives bm.render()) */ (function(B){ if (!B || typeof grapesjs === 'undefined') return; const PluginName = 'bridge-categorization-master'; // 🛑 WICHTIG: Liste aller unerwünschten IDs/Labels const UNWANTED_CATEGORY_ID = 'Bibliothek'; const UNWANTED_UNCATEGORIZED_ID = 'Uncategorized'; // Fügen Sie die gängigen IDs des gjs-preset-newsletter hinzu const PRESET_UNWANTED_IDS = ['Basic', 'Layout', 'Extra', 'Components', 'Forms']; // Alle IDs, die gelöscht werden müssen const ALL_FORBIDDEN_CAT_IDS = [UNWANTED_CATEGORY_ID, UNWANTED_UNCATEGORIZED_ID, ...PRESET_UNWANTED_IDS]; const UNWANTED_BLOCK_ID = 'gjs-lbr-block'; const UNWANTED_BLOCK_LABEL = 'Bibliothek'; const FALLBACK_CATEGORY_ID = 'mysnips'; const CUSTOM_BLOCK_IDS = (window.BridgeBlocksCustom && window.BridgeBlocksCustom.IDS) || []; let normalizationRunCount = 0; let normalizationIsRunning = false; let maxNormalizationRuns = 5; // ---------------------------------------------------------------------- // HILFSFUNKTION: Entfernt hartnäckige Kategorie-DOM-Elemente // ---------------------------------------------------------------------- const zapUnwantedCategoryDom = (editor) => { const blocksPanelEl = editor.Panels.getPanel('blocks')?.get('el'); if (blocksPanelEl) { let removedCount = 0; blocksPanelEl.querySelectorAll('.gjs-block-cat').forEach(catEl => { const catTitleEl = catEl.querySelector('.gjs-title'); if (catTitleEl) { const catTitle = catTitleEl.textContent.trim(); // Prüfe auf unerwünschte Titel (sowohl Standard als auch Presets) if (ALL_FORBIDDEN_CAT_IDS.includes(catTitle) || catTitle === UNWANTED_UNCATEGORIZED_ID || catTitle === UNWANTED_CATEGORY_ID) { catEl.remove(); removedCount++; } } }); if (removedCount > 0) { console.warn(`[${PluginName}][DOM Fix] ${removedCount} unerwünschte Kategorie-DOM-Elemente entfernt.`); } } }; // ---------------------------------------------------------------------- // Hilfsfunktion: Erzwingt das Neu-Rendern der Block-View (NUR DOM-CLEANUP) // ---------------------------------------------------------------------- const renderBlocks = (editor) => { // 🛑 KRITISCHE KORREKTUR: Entferne bm.render() – nur DOM-Cleanup ist hier nötig, // da das Setzen der Model-Eigenschaften (label, visible) das Rendering übernehmen sollte. zapUnwantedCategoryDom(editor); console.log(`[${PluginName}][Render] DOM-Cleanup ausgeführt.`); }; // ---------------------------------------------------------------------- // 1. Funktion zum Ausblenden/Normalisieren der Kategorien (Kernlogik) // ---------------------------------------------------------------------- const normalizeCategories = (editor) => { if (normalizationIsRunning || normalizationRunCount >= maxNormalizationRuns) { if (normalizationRunCount >= maxNormalizationRuns) { console.warn(`[${PluginName}] normalizeCategories übersprungen: Maximale Läufe (${maxNormalizationRuns}) erreicht.`); } else { console.warn(`[${PluginName}] normalizeCategories übersprungen: Läuft bereits.`); } return; } normalizationIsRunning = true; normalizationRunCount++; console.group(`[${PluginName}] normalizeCategories Run #${normalizationRunCount}`); const bm = editor.BlockManager; const config = B.CATEGORY_CONFIG || {}; const configuredCategoryIds = Object.keys(config); // 🛑 NEUER FALLBACK-FIX: Stellen Sie sicher, dass alle konfigurierten Kategorien existieren, // bevor Blöcke zugewiesen werden. configuredCategoryIds.forEach(catId => { const catConf = config[catId]; if (!bm.getCategories().get(catId)) { bm.getCategories().add({ id: catId, label: catConf.label, open: catConf.open !== false, order: catConf.ord || 999 }); // Nur als Warnung, da dies bei 'mysnips' oft passiert, wenn es leer ist. console.warn(`[${PluginName}][Cat Fallback] Kategorie '${catId}' wurde nachträglich erstellt.`); } }); // --- A. Zwangszuweisung der Blöcke und Bereinigung von Blöcken --- bm.getAll().each(block => { const id = block.get('id'); const label = block.get('label'); let catId = block.get('category'); if (typeof catId === 'object' && catId.id) { catId = catId.id; // Behandle Category-Objekte } // 1. Lösche unerwünschten hartnäckigen Block (z.B. gjs-lbr-block) if (id === UNWANTED_BLOCK_ID || label === UNWANTED_BLOCK_LABEL) { console.log(`[${PluginName}][Block Fix] Unerwünschter Block '${id}' ('${label}') entfernt.`); bm.remove(id); return; } // 2. Setze Blöcke ohne oder mit unerwünschter/unbekannter Kategorie auf den Fallback (mysnips) // HINWEIS: 'custom' ist in configuredCategoryIds, falls es noch keine Blöcke von der API hat. if (!catId || !configuredCategoryIds.includes(catId) || ALL_FORBIDDEN_CAT_IDS.includes(catId)) { // Nur wenn der Block nicht leer ist if (id) { console.log(`[${PluginName}][Block Fix] Block '${id}' ('${label}') verschoben nach '${FALLBACK_CATEGORY_ID}' (von Kat: ${catId || 'keine'}).`); block.set('category', FALLBACK_CATEGORY_ID); } } // 3. Custom Blocks schützen if (CUSTOM_BLOCK_IDS.includes(id) && catId !== 'bausteine') { block.set('category', 'bausteine'); } }); // --- B. Kategorien erzwingen, Label korrigieren und Löschen von Modellen --- const categories = bm.getCategories().models || bm.getCategories(); let visibleCategories = []; // Gehe alle Category Models durch categories.forEach(catModel => { const catId = catModel.get('id'); const catConf = config[catId]; // Aggressives Löschen von unerwünschten Preset-Kategorien if (ALL_FORBIDDEN_CAT_IDS.includes(catId)) { console.warn(`[${PluginName}][Cat Fix] Lösche unerwünschtes Category Model: ${catId}`); bm.getCategories().remove(catModel); return; } // Finde eine existierende, aber nicht konfigurierte Kategorie, und blende sie aus // WICHTIG: mysnips ist der FALLBACK_CATEGORY_ID, hier darf es NICHT ausgeblendet werden. if (!catConf && catId && catId !== FALLBACK_CATEGORY_ID) { catModel.set('visible', false); catModel.set('open', false); return; } // Korrigiere Label, Sortierung und Sichtbarkeit der konfigurierten Kategorien if (catConf) { // 🛑 KRITISCHER FIX: Garantiertes Setzen des korrekten Labels (LÖST KLEINSCHREIBUNGS-PROBLEM) if (catModel.get('label') !== catConf.label) { console.log(`[${PluginName}][Cat Fix] Korrigiere Label von '${catId}' auf '${catConf.label}'.`); catModel.set('label', catConf.label); } // ** Das Setzen von 'visible' und 'open' sollte die UI-Aktualisierung (Kategorie anzeigen) auslösen. ** catModel.set('visible', true); catModel.set('open', catConf.open !== false); catModel.set('order', catConf.ord || 999); visibleCategories.push(catId); } }); // --- C. Cleanup und Neu-Rendern erzwingen --- categories.sort((a, b) => (a.get('order') || 999) - (b.get('order') || 999)); B.sortBlocksByPrefixAndLabel && B.sortBlocksByPrefixAndLabel(bm.getAll().models); // 🛑 KRITISCH: Rendering WIRD NICHT mehr erzwungen – nur DOM Cleanup. renderBlocks(editor); console.log(`Kategorisierung abgeschlossen. Sichtbare Kategorien: ${visibleCategories.sort().join(', ')}.`); console.groupEnd(); normalizationIsRunning = false; }; // ---------------------------------------------------------------------- // GrapesJS Plugin Registrierung // ---------------------------------------------------------------------- grapesjs.plugins.add(PluginName, (editor, opts = {}) => { const bm = editor.BlockManager; // 1. Initialer, verspäteter Lauf bei Ladevorgang editor.on('load', () => { // FINALER LAUF: Läuft, wenn ALLE Standard-Plugins fertig sind setTimeout(() => { console.warn(`[${PluginName}][FINAL RUN] Starte finalen Normalisierungslauf nach 2500ms.`); normalizeCategories(editor); }, 2500); }); // 2. WATCHDOG gegen Label-Überschreibung oder unerwünschte Adds bm.getCategories().on('add change:label', (categoryModel) => { const catId = categoryModel.get('id'); const newLabel = categoryModel.get('label'); const expectedLabel = B.CATEGORY_CONFIG?.[catId]?.label; // WATCHDOG-ADD: Entfernt unerwünschte Kategorien sofort, falls sie erstellt werden if (ALL_FORBIDDEN_CAT_IDS.includes(catId)) { console.error(`[${PluginName}][WATCHDOG-ADD] Unerwünschte Kategorie '${catId}' wurde hinzugefügt! Starte Sofort-Korrektur.`); bm.getCategories().remove(categoryModel); setTimeout(() => normalizeCategories(editor), 1); } // WATCHDOG-LABEL: Korrigiert falsche Labels (z.B. "bausteine" -> "🧱 Bausteine") if (expectedLabel && newLabel !== expectedLabel) { console.warn(`[${PluginName}][WATCHDOG-CHANGE] Externe Label-Manipulation von '${catId}' erkannt: Korrigiere von '${newLabel}' auf '${expectedLabel}'.`); // Sofortiges Zurücksetzen des Labels auf den korrekten Wert categoryModel.set('label', expectedLabel, { silent: true }); // Triggere einen Normalize-Lauf, damit die UI die Korrektur sieht und die Sortierung passt. setTimeout(() => normalizeCategories(editor), 1); } }); B.normalizeCategories = normalizeCategories; B.renderBlocks = renderBlocks; console.log(`[${PluginName}] Master-Koordinator registriert.`); }); })(window.BridgeParts || (window.BridgeParts = {}));