courrier preview
This commit is contained in:
parent
149a49d6f3
commit
e9f104f40b
@ -18,7 +18,7 @@ interface RichEmailEditorProps {
|
|||||||
/**
|
/**
|
||||||
* Clean up problematic table structures that cause issues with quill-better-table
|
* Clean up problematic table structures that cause issues with quill-better-table
|
||||||
*/
|
*/
|
||||||
function cleanupTableStructures(htmlContent: string): string {
|
function cleanupTableStructures(htmlContent: string, isReplyOrForward: boolean = false): string {
|
||||||
if (!htmlContent) return htmlContent;
|
if (!htmlContent) return htmlContent;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -40,101 +40,103 @@ function cleanupTableStructures(htmlContent: string): string {
|
|||||||
htmlContent.includes('<blockquote') ||
|
htmlContent.includes('<blockquote') ||
|
||||||
htmlContent.includes('gmail_quote');
|
htmlContent.includes('gmail_quote');
|
||||||
|
|
||||||
// Check if content has complex tables that might cause issues
|
// For reply/forward content, force convert ALL tables to divs to avoid Quill errors
|
||||||
const hasComplexTables = tables.length > 0 &&
|
const shouldConvertAllTables = isReplyOrForward || isForwardedEmail || isReplyEmail;
|
||||||
(isForwardedEmail || isReplyEmail);
|
|
||||||
|
|
||||||
if (hasComplexTables) {
|
if (tables.length > 0) {
|
||||||
console.log(`Found ${tables.length} tables in complex email content`);
|
console.log(`Found ${tables.length} tables in ${shouldConvertAllTables ? 'reply/forward' : 'regular'} content`);
|
||||||
|
|
||||||
let convertedCount = 0;
|
let convertedCount = 0;
|
||||||
tables.forEach(table => {
|
tables.forEach(table => {
|
||||||
// Special handling for tables inside blockquotes (quoted content)
|
// In reply/forward mode, convert ALL tables to divs to avoid quill-better-table issues
|
||||||
if (table.closest('blockquote') ||
|
if (shouldConvertAllTables) {
|
||||||
(isReplyEmail && table.innerHTML.includes('wrote:'))) {
|
const replacementDiv = document.createElement('div');
|
||||||
console.log('Preserving table inside quoted content');
|
replacementDiv.className = 'converted-table';
|
||||||
|
replacementDiv.style.border = '1px solid #ddd';
|
||||||
|
replacementDiv.style.margin = '10px 0';
|
||||||
|
replacementDiv.style.padding = '10px';
|
||||||
|
|
||||||
// Add width attribute to all cells to prevent width calculation issues
|
// Preserve the original table structure visually
|
||||||
const cells = table.querySelectorAll('td, th');
|
// Create a simplified HTML representation of the table
|
||||||
cells.forEach(cell => {
|
let tableHtml = '';
|
||||||
if (cell instanceof HTMLTableCellElement) {
|
|
||||||
if (!cell.hasAttribute('width')) {
|
// Process each row
|
||||||
|
const rows = table.querySelectorAll('tr');
|
||||||
|
rows.forEach(row => {
|
||||||
|
const rowDiv = document.createElement('div');
|
||||||
|
rowDiv.style.display = 'flex';
|
||||||
|
rowDiv.style.flexWrap = 'wrap';
|
||||||
|
rowDiv.style.marginBottom = '5px';
|
||||||
|
|
||||||
|
// Process each cell in the row
|
||||||
|
const cells = row.querySelectorAll('td, th');
|
||||||
|
cells.forEach(cell => {
|
||||||
|
const cellDiv = document.createElement('div');
|
||||||
|
cellDiv.style.flex = '1';
|
||||||
|
cellDiv.style.padding = '5px';
|
||||||
|
cellDiv.style.borderBottom = '1px solid #eee';
|
||||||
|
cellDiv.innerHTML = cell.innerHTML;
|
||||||
|
rowDiv.appendChild(cellDiv);
|
||||||
|
});
|
||||||
|
|
||||||
|
replacementDiv.appendChild(rowDiv);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If no rows were processed, just use the table's inner HTML
|
||||||
|
if (rows.length === 0) {
|
||||||
|
replacementDiv.innerHTML = table.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the table with the div
|
||||||
|
if (table.parentNode) {
|
||||||
|
table.parentNode.replaceChild(replacementDiv, table);
|
||||||
|
convertedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For regular content, just add width attributes to make quill-better-table happy
|
||||||
|
else {
|
||||||
|
// 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('rowspan') && // No rowspan
|
||||||
|
!table.innerHTML.includes('colspan'); // No colspan
|
||||||
|
|
||||||
|
if (isSimpleTable) {
|
||||||
|
console.log('Preserving simple table structure');
|
||||||
|
// Add width attribute
|
||||||
|
table.setAttribute('width', '100%');
|
||||||
|
|
||||||
|
// Add width to cells
|
||||||
|
const cells = table.querySelectorAll('td, th');
|
||||||
|
cells.forEach(cell => {
|
||||||
|
if (cell instanceof HTMLTableCellElement && !cell.hasAttribute('width')) {
|
||||||
cell.setAttribute('width', '100');
|
cell.setAttribute('width', '100');
|
||||||
}
|
}
|
||||||
cell.style.padding = '4px';
|
});
|
||||||
cell.style.textAlign = 'left';
|
} else {
|
||||||
cell.style.verticalAlign = 'top';
|
// Convert complex tables to divs
|
||||||
|
const replacementDiv = document.createElement('div');
|
||||||
|
replacementDiv.className = 'converted-table';
|
||||||
|
replacementDiv.style.border = '1px solid #ddd';
|
||||||
|
replacementDiv.style.margin = '10px 0';
|
||||||
|
replacementDiv.style.padding = '10px';
|
||||||
|
|
||||||
|
// Copy the table's innerHTML
|
||||||
|
replacementDiv.innerHTML = table.innerHTML;
|
||||||
|
|
||||||
|
// Replace the table with the div
|
||||||
|
if (table.parentNode) {
|
||||||
|
table.parentNode.replaceChild(replacementDiv, table);
|
||||||
|
convertedCount++;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
// Apply minimal styling to ensure it renders correctly
|
|
||||||
table.setAttribute('style', 'border-collapse: collapse; width: 100%; max-width: 100%; margin: 8px 0;');
|
|
||||||
// Add explicit width attribute to the table
|
|
||||||
table.setAttribute('width', '100%');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;');
|
|
||||||
// Add explicit width attribute
|
|
||||||
table.setAttribute('width', '100%');
|
|
||||||
|
|
||||||
// Add width to cells
|
|
||||||
const cells = table.querySelectorAll('td, th');
|
|
||||||
cells.forEach(cell => {
|
|
||||||
if (cell instanceof HTMLTableCellElement && !cell.hasAttribute('width')) {
|
|
||||||
// First column (labels) narrower
|
|
||||||
if (cell.textContent?.includes(':')) {
|
|
||||||
cell.setAttribute('width', '80');
|
|
||||||
} else {
|
|
||||||
cell.setAttribute('width', '400');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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');
|
|
||||||
// Add width attribute
|
|
||||||
table.setAttribute('width', '100%');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert complex tables to divs
|
|
||||||
const replacementDiv = document.createElement('div');
|
|
||||||
replacementDiv.className = 'converted-table';
|
|
||||||
replacementDiv.style.border = '1px solid #ddd';
|
|
||||||
replacementDiv.style.margin = '10px 0';
|
|
||||||
replacementDiv.style.padding = '10px';
|
|
||||||
|
|
||||||
// Copy the table's innerHTML
|
|
||||||
replacementDiv.innerHTML = table.innerHTML;
|
|
||||||
|
|
||||||
// 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`);
|
console.log(`Converted ${convertedCount} tables to divs to prevent Quill errors`);
|
||||||
return tempDiv.innerHTML;
|
return tempDiv.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +159,7 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
const toolbarRef = useRef<HTMLDivElement>(null);
|
const toolbarRef = useRef<HTMLDivElement>(null);
|
||||||
const quillRef = useRef<any>(null);
|
const quillRef = useRef<any>(null);
|
||||||
const [isReady, setIsReady] = useState(false);
|
const [isReady, setIsReady] = useState(false);
|
||||||
|
const [isReplyOrForward, setIsReplyOrForward] = useState(false);
|
||||||
|
|
||||||
// Initialize Quill editor when component mounts
|
// Initialize Quill editor when component mounts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -164,23 +167,41 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
const initializeQuill = async () => {
|
const initializeQuill = async () => {
|
||||||
if (!editorRef.current || !toolbarRef.current) return;
|
if (!editorRef.current || !toolbarRef.current) return;
|
||||||
|
|
||||||
|
// First, detect if content is reply/forward to determine editor mode
|
||||||
|
const contentIsReplyOrForward = initialContent ? (
|
||||||
|
initialContent.includes('wrote:') ||
|
||||||
|
initialContent.includes('<blockquote') ||
|
||||||
|
initialContent.includes('Forwarded message') ||
|
||||||
|
initialContent.includes('---------- Forwarded message ----------')
|
||||||
|
) : false;
|
||||||
|
|
||||||
|
// Store this information for future reference
|
||||||
|
setIsReplyOrForward(contentIsReplyOrForward);
|
||||||
|
|
||||||
|
console.log('Initializing editor in', contentIsReplyOrForward ? 'reply/forward' : 'compose', 'mode');
|
||||||
|
|
||||||
const Quill = (await import('quill')).default;
|
const Quill = (await import('quill')).default;
|
||||||
|
|
||||||
// Import quill-better-table
|
// Import quill-better-table conditionally based on content type
|
||||||
let tableModule = null;
|
let tableModule = null;
|
||||||
try {
|
if (!contentIsReplyOrForward) {
|
||||||
const QuillBetterTable = await import('quill-better-table');
|
// Only try to load table module for regular content, not for replies/forwards
|
||||||
|
try {
|
||||||
|
const QuillBetterTable = await import('quill-better-table');
|
||||||
|
|
||||||
// Register the table module if available
|
// Register the table module if available and not in reply/forward mode
|
||||||
if (QuillBetterTable && QuillBetterTable.default) {
|
if (QuillBetterTable && QuillBetterTable.default) {
|
||||||
Quill.register({
|
Quill.register({
|
||||||
'modules/better-table': QuillBetterTable.default
|
'modules/better-table': QuillBetterTable.default
|
||||||
}, true);
|
}, true);
|
||||||
tableModule = QuillBetterTable.default;
|
tableModule = QuillBetterTable.default;
|
||||||
console.log('Better Table module registered successfully');
|
console.log('Better Table module registered successfully');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Table module not available:', err);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} else {
|
||||||
console.warn('Table module not available:', err);
|
console.log('Skipping better-table module for reply/forward content');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define custom formats/modules with table support
|
// Define custom formats/modules with table support
|
||||||
@ -208,8 +229,8 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
clipboard: {
|
clipboard: {
|
||||||
matchVisual: false // Disable clipboard matching for better HTML handling
|
matchVisual: false // Disable clipboard matching for better HTML handling
|
||||||
},
|
},
|
||||||
// Don't initialize better-table yet - we'll do it after content is loaded
|
// Only enable better-table for regular content, not for replies/forwards
|
||||||
'better-table': false,
|
'better-table': tableModule && !contentIsReplyOrForward ? true : false,
|
||||||
},
|
},
|
||||||
placeholder: placeholder,
|
placeholder: placeholder,
|
||||||
theme: 'snow',
|
theme: 'snow',
|
||||||
@ -226,17 +247,10 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
hasBlockquote: initialContent.includes('<blockquote')
|
hasBlockquote: initialContent.includes('<blockquote')
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if content is reply or forward to use special handling
|
|
||||||
const isReplyOrForward =
|
|
||||||
initialContent.includes('wrote:') ||
|
|
||||||
initialContent.includes('<blockquote') ||
|
|
||||||
initialContent.includes('Forwarded message') ||
|
|
||||||
initialContent.includes('---------- Forwarded message ----------');
|
|
||||||
|
|
||||||
// Process HTML content using centralized utility with special settings for replies/forwards
|
// Process HTML content using centralized utility with special settings for replies/forwards
|
||||||
const processed = processHtmlContent(initialContent, {
|
const processed = processHtmlContent(initialContent, {
|
||||||
sanitize: true,
|
sanitize: true,
|
||||||
preserveReplyFormat: isReplyOrForward
|
preserveReplyFormat: contentIsReplyOrForward
|
||||||
});
|
});
|
||||||
const sanitizedContent = processed.sanitizedContent;
|
const sanitizedContent = processed.sanitizedContent;
|
||||||
const direction = processed.direction; // Use direction from processed result
|
const direction = processed.direction; // Use direction from processed result
|
||||||
@ -250,7 +264,7 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
containsQuoteHeader: sanitizedContent.includes('wrote:'),
|
containsQuoteHeader: sanitizedContent.includes('wrote:'),
|
||||||
hasTable: sanitizedContent.includes('<table'),
|
hasTable: sanitizedContent.includes('<table'),
|
||||||
hasBlockquote: sanitizedContent.includes('<blockquote'),
|
hasBlockquote: sanitizedContent.includes('<blockquote'),
|
||||||
isReplyOrForward: isReplyOrForward,
|
isReplyOrForward: contentIsReplyOrForward,
|
||||||
firstNChars: sanitizedContent.substring(0, 100).replace(/\n/g, '\\n')
|
firstNChars: sanitizedContent.substring(0, 100).replace(/\n/g, '\\n')
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -271,17 +285,20 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Special handling for reply or forwarded content
|
// Special handling for reply or forwarded content
|
||||||
if (isReplyOrForward) {
|
if (contentIsReplyOrForward) {
|
||||||
console.log('Using special handling for reply/forward content');
|
console.log('Using special handling for reply/forward content');
|
||||||
|
|
||||||
// Clean up any problematic table structures, with special care for quoted content
|
// For reply/forward content, convert ALL tables to divs
|
||||||
const cleanedContent = cleanupTableStructures(sanitizedContent);
|
const cleanedContent = cleanupTableStructures(sanitizedContent, true);
|
||||||
|
|
||||||
// Use direct innerHTML setting with minimal processing for reply/forward content
|
// Use direct innerHTML setting with minimal processing for reply/forward content
|
||||||
quillRef.current.root.innerHTML = cleanedContent;
|
quillRef.current.root.innerHTML = cleanedContent;
|
||||||
} else {
|
} else {
|
||||||
|
// For regular content, use normal processing
|
||||||
|
const cleanedContent = cleanupTableStructures(sanitizedContent, false);
|
||||||
|
|
||||||
// Use direct innerHTML setting for regular content
|
// Use direct innerHTML setting for regular content
|
||||||
quillRef.current.root.innerHTML = sanitizedContent;
|
quillRef.current.root.innerHTML = cleanedContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the direction for the content
|
// Set the direction for the content
|
||||||
@ -353,43 +370,6 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
editorContainer.classList.add('email-editor-container');
|
editorContainer.classList.add('email-editor-container');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe initialization of better-table module if available
|
|
||||||
if (tableModule) {
|
|
||||||
try {
|
|
||||||
// Wait a small delay to ensure content is properly set before initializing table module
|
|
||||||
setTimeout(() => {
|
|
||||||
if (quillRef.current) {
|
|
||||||
// First check if content has tables and whether it's a reply/forward
|
|
||||||
const hasReplyForwardContent =
|
|
||||||
quillRef.current.root.innerHTML.includes('wrote:') ||
|
|
||||||
quillRef.current.root.innerHTML.includes('blockquote') ||
|
|
||||||
quillRef.current.root.innerHTML.includes('Forwarded message');
|
|
||||||
|
|
||||||
const hasTables = quillRef.current.root.innerHTML.includes('<table');
|
|
||||||
|
|
||||||
console.log('Checking if better-table should be enabled:', {
|
|
||||||
hasReplyForwardContent,
|
|
||||||
hasTables
|
|
||||||
});
|
|
||||||
|
|
||||||
// Only initialize table module for regular content, not for replies/forwards
|
|
||||||
if (!hasReplyForwardContent && hasTables) {
|
|
||||||
console.log('Initializing better-table module for regular content with tables');
|
|
||||||
quillRef.current.getModule('better-table').setTableSelection(true);
|
|
||||||
} else if (hasReplyForwardContent && hasTables) {
|
|
||||||
// For reply/forward content with tables, we'll use a more limited approach
|
|
||||||
console.log('Tables in reply/forward content detected - using limited table handling');
|
|
||||||
// Don't initialize selection tools to avoid errors
|
|
||||||
} else {
|
|
||||||
console.log('No tables detected or simple content - proceeding without table module');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 300);
|
|
||||||
} catch (err) {
|
|
||||||
console.warn('Error initializing better-table module:', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsReady(true);
|
setIsReady(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -425,16 +405,31 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Check if content is reply or forward to use special handling
|
// Check if content is reply or forward to use special handling
|
||||||
const isReplyOrForward =
|
const contentIsReplyOrForward =
|
||||||
initialContent.includes('wrote:') ||
|
initialContent.includes('wrote:') ||
|
||||||
initialContent.includes('<blockquote') ||
|
initialContent.includes('<blockquote') ||
|
||||||
initialContent.includes('Forwarded message') ||
|
initialContent.includes('Forwarded message') ||
|
||||||
initialContent.includes('---------- Forwarded message ----------');
|
initialContent.includes('---------- Forwarded message ----------');
|
||||||
|
|
||||||
|
// If content type changed (from reply to regular or vice versa), we need to reload
|
||||||
|
if (contentIsReplyOrForward !== isReplyOrForward) {
|
||||||
|
console.log('Content type changed from', isReplyOrForward ? 'reply/forward' : 'regular',
|
||||||
|
'to', contentIsReplyOrForward ? 'reply/forward' : 'regular',
|
||||||
|
'- reloading editor');
|
||||||
|
setIsReplyOrForward(contentIsReplyOrForward);
|
||||||
|
// Force a complete re-initialization of the editor by unmounting
|
||||||
|
if (quillRef.current) {
|
||||||
|
quillRef.current.off('text-change');
|
||||||
|
quillRef.current = null;
|
||||||
|
}
|
||||||
|
setIsReady(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Process HTML content using centralized utility
|
// Process HTML content using centralized utility
|
||||||
const processed = processHtmlContent(initialContent, {
|
const processed = processHtmlContent(initialContent, {
|
||||||
sanitize: true,
|
sanitize: true,
|
||||||
preserveReplyFormat: isReplyOrForward
|
preserveReplyFormat: contentIsReplyOrForward
|
||||||
});
|
});
|
||||||
const sanitizedContent = processed.sanitizedContent;
|
const sanitizedContent = processed.sanitizedContent;
|
||||||
const direction = processed.direction; // Use direction from processed result
|
const direction = processed.direction; // Use direction from processed result
|
||||||
@ -448,7 +443,7 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
containsQuoteHeader: sanitizedContent.includes('wrote:'),
|
containsQuoteHeader: sanitizedContent.includes('wrote:'),
|
||||||
hasTable: sanitizedContent.includes('<table'),
|
hasTable: sanitizedContent.includes('<table'),
|
||||||
hasBlockquote: sanitizedContent.includes('<blockquote'),
|
hasBlockquote: sanitizedContent.includes('<blockquote'),
|
||||||
isReplyOrForward: isReplyOrForward,
|
isReplyOrForward: contentIsReplyOrForward,
|
||||||
firstNChars: sanitizedContent.substring(0, 100).replace(/\n/g, '\\n')
|
firstNChars: sanitizedContent.substring(0, 100).replace(/\n/g, '\\n')
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -465,23 +460,16 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
quillRef.current.setText(textContent || 'No content available');
|
quillRef.current.setText(textContent || 'No content available');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Special handling for reply or forward content
|
// Process content based on type
|
||||||
let contentToSet = sanitizedContent;
|
if (contentIsReplyOrForward) {
|
||||||
|
|
||||||
if (isReplyOrForward) {
|
|
||||||
console.log('Using special handling for reply/forward content update');
|
console.log('Using special handling for reply/forward content update');
|
||||||
// Clean up tables with special care for quoted content
|
|
||||||
contentToSet = cleanupTableStructures(sanitizedContent);
|
|
||||||
|
|
||||||
// Set content directly to the root element
|
// For reply/forward content, convert ALL tables to divs
|
||||||
|
const cleanedContent = cleanupTableStructures(sanitizedContent, true);
|
||||||
|
|
||||||
|
// Set content without table handling
|
||||||
if (quillRef.current && quillRef.current.root) {
|
if (quillRef.current && quillRef.current.root) {
|
||||||
// Temporarily disable the better-table module if it's initialized
|
quillRef.current.root.innerHTML = cleanedContent;
|
||||||
if (quillRef.current.getModule('better-table')) {
|
|
||||||
quillRef.current.getModule('better-table').hideTableTools();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set content without table handling by the module
|
|
||||||
quillRef.current.root.innerHTML = contentToSet;
|
|
||||||
|
|
||||||
// Delay applying formatting to ensure Quill is fully ready
|
// Delay applying formatting to ensure Quill is fully ready
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -505,9 +493,11 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// For regular content, use Quill's normal process
|
// For regular content, use normal processing
|
||||||
|
const cleanedContent = cleanupTableStructures(sanitizedContent, false);
|
||||||
|
|
||||||
if (quillRef.current && quillRef.current.root) {
|
if (quillRef.current && quillRef.current.root) {
|
||||||
quillRef.current.root.innerHTML = contentToSet;
|
quillRef.current.root.innerHTML = cleanedContent;
|
||||||
|
|
||||||
// Safely apply formatting
|
// Safely apply formatting
|
||||||
try {
|
try {
|
||||||
@ -549,7 +539,7 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [initialContent, isReady]);
|
}, [initialContent, isReady, isReplyOrForward]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rich-email-editor-wrapper">
|
<div className="rich-email-editor-wrapper">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user