diff --git a/demo-site/insertr/insertr.js b/demo-site/insertr/insertr.js index 37d0d84..4552615 100644 --- a/demo-site/insertr/insertr.js +++ b/demo-site/insertr/insertr.js @@ -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>/gi, '# $1\n\n'); + markdown = markdown.replace(/]*>(.*?)<\/h2>/gi, '## $1\n\n'); + markdown = markdown.replace(/]*>(.*?)<\/h3>/gi, '### $1\n\n'); + + // Convert formatting + markdown = markdown.replace(/]*>(.*?)<\/strong>/gi, '**$1**'); + markdown = markdown.replace(/]*>(.*?)<\/em>/gi, '*$1*'); + + // Convert links + markdown = markdown.replace(/]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi, '[$2]($1)'); + + // Convert lists + markdown = markdown.replace(/]*>(.*?)<\/ul>/gis, (match, content) => { + return content.replace(/]*>(.*?)<\/li>/gi, '- $1\n'); + }); + + // Convert paragraphs and preserve structure + markdown = markdown.replace(/]*class="lead"[^>]*>(.*?)<\/p>/gi, '\n$1\n\n'); + markdown = markdown.replace(/]*>(.*?)<\/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) {