diff --git a/apps/api/src/services/EmailService.ts b/apps/api/src/services/EmailService.ts index bc40a38..b5f3ebc 100644 --- a/apps/api/src/services/EmailService.ts +++ b/apps/api/src/services/EmailService.ts @@ -650,6 +650,378 @@ export class EmailService { } } + /** + * Detects if HTML contains custom patterns that indicate it was written in the HTML editor + * rather than the visual editor. Mirrors the same logic in EmailPreviewModal.tsx. + */ + private static detectCustomHtmlPatterns(html: string): boolean { + if (!html || html.trim() === '') return false; + + const hasInlineStyles = /<[^>]+style\s*=\s*["'][^"']*["']/i.test(html); + + const classMatches = html.matchAll(/class\s*=\s*["']([^"']*)["']/gi); + let hasCustomClasses = false; + for (const match of classMatches) { + const classValue = match[1]; + if (!classValue) continue; + const classes = classValue.split(/\s+/).filter((c: string) => c.length > 0); + const allowedPrefixes = ['prose', 'variable-', 'email-image', 'ProseMirror', 'resizable-image', 'selected', 'resize-handle']; + const hasDisallowedClass = classes.some((cls: string) => !allowedPrefixes.some((prefix: string) => cls.startsWith(prefix))); + if (hasDisallowedClass) { + hasCustomClasses = true; + break; + } + } + + const hasCustomAttributes = /<[^>]+(?:data-|aria-|role=|id=)/i.test(html); + const hasComplexTables = /