courrier preview

This commit is contained in:
alma 2025-05-01 16:45:23 +02:00
parent 0db546ad79
commit 5160967c75
4 changed files with 51 additions and 7 deletions

View File

@ -41,15 +41,37 @@ function cleanupTableStructures(htmlContent: string): string {
htmlContent.includes('blockquote') || htmlContent.includes('wrote:'));
if (hasComplexTables) {
console.log(`Converting ${tables.length} tables in complex email content to prevent Quill errors`);
console.log(`Found ${tables.length} tables in complex email content`);
let convertedCount = 0;
tables.forEach(table => {
// Skip simple tables that are likely to work fine with Quill
if (table.rows.length <= 1 && table.querySelectorAll('td, th').length <= 3) {
// Preserve the main forwarded email header table
if (isForwardedEmail &&
table.innerHTML.includes('From:') &&
table.innerHTML.includes('Date:') &&
table.innerHTML.includes('Subject:')) {
console.log('Preserving forwarded email header table');
// Ensure the table has proper styling
table.setAttribute('style', 'margin: 10px 0; border-collapse: collapse; font-size: 13px; color: #333;');
return;
}
// Create a replacement div
// Skip simple tables that are likely to work fine with Quill
// Check more conditions to identify simple tables
const isSimpleTable =
table.rows.length <= 3 &&
table.querySelectorAll('td, th').length <= 6 &&
!table.querySelector('table') && // No nested tables
!table.innerHTML.includes('style=') && // No complex styling
!table.innerHTML.includes('rowspan') && // No rowspan
!table.innerHTML.includes('colspan'); // No colspan
if (isSimpleTable) {
console.log('Preserving simple table structure');
return;
}
// Convert complex tables to divs
const replacementDiv = document.createElement('div');
replacementDiv.className = 'converted-table';
replacementDiv.style.border = '1px solid #ddd';
@ -62,9 +84,11 @@ function cleanupTableStructures(htmlContent: string): string {
// Replace the table with the div
if (table.parentNode) {
table.parentNode.replaceChild(replacementDiv, table);
convertedCount++;
}
});
console.log(`Converted ${convertedCount} complex tables to divs to prevent Quill errors`);
return tempDiv.innerHTML;
}

View File

@ -39,7 +39,11 @@ export function configureDOMPurify() {
// Blockquote attributes
'cite', 'datetime',
// Form elements attributes (read-only)
'readonly', 'disabled', 'selected', 'checked', 'multiple', 'wrap'
'readonly', 'disabled', 'selected', 'checked', 'multiple', 'wrap',
// Additional attributes for forwarded emails
'style', 'class', 'id', 'dir', 'lang', 'title',
// Table attributes commonly used in email clients
'background', 'bordercolor', 'width', 'height'
],
FORBID_TAGS: [
// Remove dangerous tags

View File

@ -301,7 +301,9 @@ export function processHtmlContent(
sanitizedContent = sanitizedContent
// Preserve table styling for email headers
.replace(/<table([^>]*)>/g, '<table$1 style="margin: 10px 0; border-collapse: collapse; font-size: 13px; color: #333;">')
.replace(/<td([^>]*)>/g, '<td$1 style="padding: 3px 5px; vertical-align: top;">');
.replace(/<td([^>]*)>/g, '<td$1 style="padding: 3px 5px; vertical-align: top;">')
// Ensure blockquote styling is preserved
.replace(/<blockquote([^>]*)>/g, '<blockquote$1 style="margin: 0; padding-left: 10px; border-left: 3px solid #ddd; color: #505050; background-color: #f9f9f9; padding: 10px;">');
}
// Fix common email client quirks without breaking cid: URLs
@ -318,6 +320,19 @@ export function processHtmlContent(
// Remove excessive whitespace from the HTML string itself
.replace(/>\s+</g, '> <');
// Additional processing for quoted content in replies/forwards
if (sanitizedContent.includes('blockquote')) {
console.log('Enhancing blockquote styling');
sanitizedContent = sanitizedContent
// Ensure blockquotes have proper styling
.replace(/<blockquote([^>]*)>/g, (match, attrs) => {
if (match.includes('style=')) {
return match; // Already has style
}
return `<blockquote${attrs} style="margin: 0; padding-left: 10px; border-left: 3px solid #ddd; color: #505050; background-color: #f9f9f9; padding: 10px;">`;
});
}
return {
sanitizedContent,
hasImages: sanitizedContent.includes('<img'),

View File

@ -600,7 +600,8 @@ export function formatForwardedEmail(originalEmail: EmailMessage | LegacyEmailMe
console.log('Final forward HTML content length:', htmlContent.length,
'contains table:', htmlContent.includes('<table'),
'contains forwarded message:', htmlContent.includes('---------- Forwarded message ----------'));
'contains forwarded message:', htmlContent.includes('---------- Forwarded message ----------'),
'contains sanitized content:', htmlContent.includes(sanitizedOriginalContent.substring(0, 30)));
}
// Format the plain text version