/** * HTML Compatibility Layer * Handles HTML entities and formatting from WordPress exports */ export function processHTML(html: string | null | undefined): string { if (!html) return ''; // Replace common HTML entities let processed = html; const entities: Record = { '\u00A0': ' ', // Non-breaking space '&': '&', '<': '<', '>': '>', '"': '"', "'": "'", '¢': '¢', '£': '£', '¥': '¥', '€': '€', '©': '©', '®': '®', '™': '™', '°': '°', '±': '±', '×': '×', '÷': '÷', 'µ': 'µ', '¶': '¶', '§': '§', 'á': 'á', 'é': 'é', 'í': 'í', 'ó': 'ó', 'ú': 'ú', 'Á': 'Á', 'É': 'É', 'Í': 'Í', 'Ó': 'Ó', 'Ú': 'Ú', 'ñ': 'ñ', 'Ñ': 'Ñ', 'ü': 'ü', 'Ü': 'Ü', 'ö': 'ö', 'Ö': 'Ö', 'ä': 'ä', 'Ä': 'Ä', 'ß': 'ß', '—': '—', '–': '–', '…': '…', '«': '«', '»': '»', '‘': "'", '’': "'", '“': '"', '”': '"', '•': '•', '·': '·' }; // Replace entities for (const [entity, char] of Object.entries(entities)) { processed = processed.replace(new RegExp(entity.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), char); } // Remove script tags processed = processed.replace(/)<[^<]*)*<\/script>/gi, ''); // Remove style tags processed = processed.replace(/)<[^<]*)*<\/style>/gi, ''); // Remove inline event handlers processed = processed.replace(/\s+on\w+\s*=\s*["'][^"']*["']/gi, ''); // Remove dangerous attributes processed = processed.replace(/\s+(href|src)\s*=\s*["']\s*javascript:/gi, ''); // Remove any remaining WordPress shortcode-like content (e.g., [vc_row...]) processed = processed.replace(/\[[^\]]*\]/g, ''); // Keep HTML structure from processed data - allow divs with our classes // Allow:

,
, , , , , ,