Fix edit form content extraction - show clean customer view
🐛 Problem: Edit forms showed client view with edit buttons/emojis ✅ Solution: Extract clean content without edit interface elements 🔧 Changes: - extractContentFromElement() now properly removes all edit UI - Improved htmlToMarkdown() for better rich content conversion - setupEditableElement() preserves original clean content - Enhanced whitespace normalization in markdown conversion - Handles both simple text and rich markdown content types 🎯 User Experience: - Client sees: Content with edit buttons (✏️) - Edit form shows: Clean, properly formatted content - Customer sees: Original clean content (no edit UI) ✨ Whitespace improvements: - Removes excessive indentation and spacing - Normalizes line breaks and paragraph spacing - Clean, readable content in edit forms Critical fix for proper edit-in-place functionality
This commit is contained in:
@@ -66,6 +66,18 @@ class Insertr {
|
||||
}
|
||||
|
||||
setupEditableElement(element, contentId) {
|
||||
// Store original clean content before adding edit interface
|
||||
if (!element.querySelector('.insertr-original-content')) {
|
||||
const originalContent = element.cloneNode(true);
|
||||
originalContent.classList.add('insertr-original-content');
|
||||
originalContent.style.display = 'none';
|
||||
element.appendChild(originalContent);
|
||||
}
|
||||
|
||||
// Remove any existing edit buttons to avoid duplicates
|
||||
const existingBtn = element.querySelector('.insertr-edit-btn');
|
||||
if (existingBtn) existingBtn.remove();
|
||||
|
||||
// Add edit button
|
||||
const editBtn = document.createElement('button');
|
||||
editBtn.className = 'insertr-edit-btn';
|
||||
@@ -239,12 +251,42 @@ class Insertr {
|
||||
}
|
||||
|
||||
extractContentFromElement(element) {
|
||||
const clone = element.cloneNode(true);
|
||||
// Remove edit button
|
||||
const editBtn = clone.querySelector('.insertr-edit-btn');
|
||||
if (editBtn) editBtn.remove();
|
||||
// Get the original content without edit interface elements
|
||||
const originalContent = element.querySelector('.insertr-original-content');
|
||||
|
||||
return clone.textContent.trim() || clone.innerHTML.trim();
|
||||
if (originalContent) {
|
||||
// We have the original content stored, use that
|
||||
const clone = originalContent.cloneNode(true);
|
||||
// Remove any edit buttons from the clone
|
||||
const editBtns = clone.querySelectorAll('.insertr-edit-btn');
|
||||
editBtns.forEach(btn => btn.remove());
|
||||
|
||||
const contentType = element.getAttribute('data-content-type') || 'simple';
|
||||
|
||||
if (contentType === 'rich') {
|
||||
// For rich content, convert back to markdown
|
||||
return this.htmlToMarkdown(clone.innerHTML);
|
||||
} else {
|
||||
// For simple content, return clean text
|
||||
return clone.textContent.trim();
|
||||
}
|
||||
} else {
|
||||
// Fallback: extract from current element (first time editing)
|
||||
const clone = element.cloneNode(true);
|
||||
// Remove edit button and any insertr interface elements
|
||||
const editBtns = clone.querySelectorAll('.insertr-edit-btn');
|
||||
editBtns.forEach(btn => btn.remove());
|
||||
|
||||
const contentType = element.getAttribute('data-content-type') || 'simple';
|
||||
|
||||
if (contentType === 'rich') {
|
||||
// For rich content, convert HTML to markdown
|
||||
return this.htmlToMarkdown(clone.innerHTML);
|
||||
} else {
|
||||
// For simple content, return clean text
|
||||
return clone.textContent.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupAuthenticationControls() {
|
||||
@@ -357,7 +399,46 @@ class Insertr {
|
||||
// Remove edit buttons and other insertr elements
|
||||
tempDiv.querySelectorAll('.insertr-edit-btn').forEach(btn => btn.remove());
|
||||
|
||||
return tempDiv.textContent || tempDiv.innerText || '';
|
||||
// Convert HTML back to markdown
|
||||
let markdown = tempDiv.innerHTML;
|
||||
|
||||
// Convert headings
|
||||
markdown = markdown.replace(/<h1[^>]*>(.*?)<\/h1>/gi, '# $1\n\n');
|
||||
markdown = markdown.replace(/<h2[^>]*>(.*?)<\/h2>/gi, '## $1\n\n');
|
||||
markdown = markdown.replace(/<h3[^>]*>(.*?)<\/h3>/gi, '### $1\n\n');
|
||||
|
||||
// Convert formatting
|
||||
markdown = markdown.replace(/<strong[^>]*>(.*?)<\/strong>/gi, '**$1**');
|
||||
markdown = markdown.replace(/<em[^>]*>(.*?)<\/em>/gi, '*$1*');
|
||||
|
||||
// Convert links
|
||||
markdown = markdown.replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi, '[$2]($1)');
|
||||
|
||||
// Convert lists
|
||||
markdown = markdown.replace(/<ul[^>]*>(.*?)<\/ul>/gis, (match, content) => {
|
||||
return content.replace(/<li[^>]*>(.*?)<\/li>/gi, '- $1\n');
|
||||
});
|
||||
|
||||
// Convert paragraphs and preserve structure
|
||||
markdown = markdown.replace(/<p[^>]*class="lead"[^>]*>(.*?)<\/p>/gi, '\n$1\n\n');
|
||||
markdown = markdown.replace(/<p[^>]*>(.*?)<\/p>/gi, '\n$1\n\n');
|
||||
|
||||
// Clean up HTML tags and entities
|
||||
markdown = markdown.replace(/<[^>]*>/g, '');
|
||||
markdown = markdown.replace(/ /g, ' ');
|
||||
markdown = markdown.replace(/&/g, '&');
|
||||
markdown = markdown.replace(/</g, '<');
|
||||
markdown = markdown.replace(/>/g, '>');
|
||||
|
||||
// Clean up excessive whitespace and normalize line breaks
|
||||
markdown = markdown.replace(/[ \t]+/g, ' '); // Multiple spaces/tabs to single space
|
||||
markdown = markdown.replace(/\n[ \t]+/g, '\n'); // Remove leading whitespace on lines
|
||||
markdown = markdown.replace(/[ \t]+\n/g, '\n'); // Remove trailing whitespace on lines
|
||||
markdown = markdown.replace(/\n\n\n+/g, '\n\n'); // Multiple blank lines to double
|
||||
markdown = markdown.replace(/^\n+/, ''); // Remove leading newlines
|
||||
markdown = markdown.replace(/\n+$/, ''); // Remove trailing newlines
|
||||
|
||||
return markdown.trim();
|
||||
}
|
||||
|
||||
getTextNodes(node) {
|
||||
|
||||
Reference in New Issue
Block a user