Files
emailtemplate.it/public/assets/js/bridge/categorization-cleanup.js
2026-01-16 01:24:53 +01:00

266 lines
12 KiB
JavaScript

/* /assets/js/bridge/categorization-cleanup.js (FINAL & LOG-KONTROLLIERT) */
(function(B){
if (!B || typeof grapesjs === 'undefined') return;
// 🛑 NEUER NAME: Dies wird das Plugin in GrapesJS registrieren
const PluginName = 'bridge-categorization-cleanup';
// ----------------------------------------------------------------------
// 🎯 NEU: LOKALE LOG-KONFIGURATION UND WRAPPER
// ----------------------------------------------------------------------
// Setzen Sie dies auf 'false' in der config.js oder hier, um alle Logs NUR für dieses Plugin zu deaktivieren.
if (B.LOG_CONFIG && B.LOG_CONFIG.PLUGINS) {
B.LOG_CONFIG.PLUGINS[PluginName] = false; // <-- HIER IST IHR SCHALTER
}
// NEUER LOKALER WRAPPER, der die zentrale B.log Funktion verwendet:
const log = (type, message, color = '#228B22', logType = 'info', force = false) => {
// Wir verwenden B.log, das die B.LOG_CONFIG.PLUGINS[PluginName] prüft
if (typeof B.log === 'function') {
B.log(PluginName, `[${type}] ${message}`, color, logType, force);
} else if (logType === 'error') {
// Fallback für kritische Fehler, wenn B.log fehlt (sollte nicht passieren)
console.error(`%c[${PluginName} - ${type}] %c${message}`, `color:red; font-weight:bold;`, 'color:inherit;');
}
};
// ----------------------------------------------------------------------
// 🛑 WICHTIG: Liste aller unerwünschten IDs/Labels
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. Enthält NICHT mehr 'Bibliothek'.
const ALL_FORBIDDEN_CAT_IDS = [UNWANTED_UNCATEGORIZED_ID, ...PRESET_UNWANTED_IDS];
const UNWANTED_BLOCK_ID = 'gjs-lbr-block-disabled';
const UNWANTED_BLOCK_LABEL = 'Bibliothek-disabled';
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.BlockManager.getContainer();
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üft, ob der Titel eine der unerwünschten IDs ist (z.B. 'Basic')
if (ALL_FORBIDDEN_CAT_IDS.includes(catTitle)) {
catEl.remove();
removedCount++;
}
}
});
if (removedCount > 0) {
log('DOM FIX', `${removedCount} unerwünschte Kategorie-DOM-Elemente entfernt.`, 'orange', 'warn');
}
}
};
// ----------------------------------------------------------------------
// Hilfsfunktion: Erzwingt das Neu-Rendern der Block-View
// ----------------------------------------------------------------------
const renderBlocks = (editor) => {
zapUnwantedCategoryDom(editor);
log('RENDER', 'DOM-Cleanup ausgeführt.', 'green');
};
// ----------------------------------------------------------------------
// 1. Funktion zum Ausblenden/Normalisieren der Kategorien (Kernlogik)
// ----------------------------------------------------------------------
const normalizeCategories = (editor) => {
if (normalizationIsRunning || normalizationRunCount >= maxNormalizationRuns) {
if (normalizationRunCount >= maxNormalizationRuns) {
log('SKIP', `normalizeCategories übersprungen: Maximale Läufe (${maxNormalizationRuns}) erreicht.`, 'red', 'warn');
} else {
log('SKIP', 'normalizeCategories übersprungen: Läuft bereits.', 'red', 'warn');
}
return;
}
normalizationIsRunning = true;
normalizationRunCount++;
// Nur das Start-Log kann eine Gruppen-Markierung sein
log('START', `Starte normalizeCategories Run #${normalizationRunCount}`, '#191970');
const bm = editor.BlockManager;
const config = B.CATEGORY_CONFIG || {};
const configuredCategoryIds = Object.keys(config);
log('CONFIG', `Konfigurierte Kategorie-IDs: ${configuredCategoryIds.join(', ')}`, '#555555');
// --- A. Explizites Erstellen der Kategorien (Sicherheits-Fallback) ---
const catsToEnsure = new Set(configuredCategoryIds);
catsToEnsure.forEach(catId => {
const catConf = config[catId];
if (!catConf) return;
if (!bm.getCategories().get(catId)) {
bm.getCategories().add({
id: catId,
label: catConf.label,
open: catConf.open !== false,
order: catConf.ord || 999
});
log('CAT FALLBACK', `Kategorie '${catId}' fehlte und wurde JETZT erstellt!`, 'red', 'error');
}
});
// --- B. 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;
}
// 1. Lösche unerwünschten hartnäckigen Block (DEAKTIVIERT)
if (id === UNWANTED_BLOCK_ID || label === UNWANTED_BLOCK_LABEL) {
// ... (Block removal logic commented out)
// log('BLOCK REMOVE', `Lösche unerwünschten Block: ${id}`, 'red', 'warn');
// bm.remove(id);
}
// 2. Setze Blöcke ohne oder mit unerwünschter/unbekannter Kategorie auf den Fallback (mysnips)
const isUnconfiguredOrForbidden = !catId || !configuredCategoryIds.includes(catId) || ALL_FORBIDDEN_CAT_IDS.includes(catId);
if (isUnconfiguredOrForbidden) {
if (id) {
log('BLOCK FIX', `Block '${id}' ('${label}') verschoben nach '${FALLBACK_CATEGORY_ID}' (Ursprüngliche Kat ID: ${catId || 'keine/leer'}).`, 'orange', 'warn');
block.set('category', FALLBACK_CATEGORY_ID);
}
} else {
log('BLOCK OK', `Block '${id}' ('${label}') bleibt in Kategorie '${catId}'.`, 'green');
}
// 3. Custom Blocks schützen
if (CUSTOM_BLOCK_IDS.includes(id) && catId !== 'bausteine') {
log('BLOCK FIX', `Custom Block '${id}' auf 'bausteine' korrigiert.`, 'orange', 'warn');
block.set('category', 'bausteine');
}
});
// --- C. Kategorien erzwingen, Label korrigieren und Löschen von Modellen ---
const categories = bm.getCategories().models || bm.getCategories();
let visibleCategories = [];
categories.forEach(catModel => {
const catId = catModel.get('id');
const catConf = config[catId];
// 1. Aggressives Löschen von unerwünschten Preset-Kategorien
if (ALL_FORBIDDEN_CAT_IDS.includes(catId)) {
log('CAT REMOVE', `Lösche unerwünschtes Category Model: ${catId} (Da in ALL_FORBIDDEN_CAT_IDS).`, 'red', 'error');
bm.getCategories().remove(catModel);
return;
}
const activeConf = catConf;
// 2. Finde eine existierende, aber nicht konfigurierte Kategorie, und blende sie aus
if (!activeConf && catId) {
log('CAT HIDE', `Kategorie '${catId}' existiert, ist aber nicht in CATEGORY_CONFIG. Wird ausgeblendet.`, 'orange', 'warn');
catModel.set('visible', false);
catModel.set('open', false);
return;
}
// 3. Korrigiere Label, Sortierung und Sichtbarkeit (Konfigurierte Kategorien)
if (activeConf) {
const oldLabel = catModel.get('label');
const newLabel = activeConf.label;
const visibility = true;
if (oldLabel !== newLabel) {
log('CAT UPDATE', `Korrigiere Label von '${catId}' von '${oldLabel}' auf '${newLabel}'.`, '#00BFFF');
catModel.set('label', newLabel, { silent: true });
}
catModel.set('visible', visibility);
catModel.set('open', activeConf.open !== false);
catModel.set('order', activeConf.ord || 999);
visibleCategories.push(catId);
log('CAT FINAL', `Kategorie '${catId}' auf Visible: ${visibility}, Order: ${catModel.get('order')}.`, 'green');
}
});
// --- D. Cleanup und Neu-Sortierung erzwingen ---
categories.sort((a, b) => (a.get('order') || 999) - (b.get('order') || 999));
B.sortBlocksByPrefixAndLabel && B.sortBlocksByPrefixAndLabel(bm.getAll().models);
// DOM Cleanup wird über renderBlocks aufgerufen
renderBlocks(editor);
log('END', `Kategorisierung abgeschlossen. Sichtbare Kategorien (Modelle): ${visibleCategories.sort().join(', ')}.`, 'green', 'info');
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', () => {
setTimeout(() => {
log('FINAL RUN', `Starte finalen Normalisierungslauf nach 2500ms.`, 'orange', 'warn');
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
if (ALL_FORBIDDEN_CAT_IDS.includes(catId)) {
log('WATCHDOG-ADD', `Unerwünschte Kategorie '${catId}' wurde hinzugefügt! Starte Sofort-Korrektur.`, 'red', 'error');
bm.getCategories().remove(categoryModel);
setTimeout(() => normalizeCategories(editor), 1);
}
// WATCHDOG-LABEL
if (expectedLabel && newLabel !== expectedLabel) {
log('WATCHDOG-CHANGE', `Externe Label-Manipulation von '${catId}' erkannt: Korrigiere von '${newLabel}' auf '${expectedLabel}'.`, 'orange', 'warn');
categoryModel.set('label', expectedLabel, { silent: true });
setTimeout(() => normalizeCategories(editor), 1);
}
});
// Exporte beibehalten, falls sie in bridge-core.js verwendet werden
B.normalizeCategories = normalizeCategories;
B.renderBlocks = renderBlocks;
log('INIT', 'Master-Koordinator registriert.', '#008080');
});
})(window.BridgeParts || (window.BridgeParts = {}));