feat: Implement HTML-first style preservation system
- Add StyleContext class for extracting and applying HTML attributes/styles - Enhance MarkdownConverter with style-aware conversion methods - Switch backend storage from markdown to HTML with 'html' content type - Update editor workflow to preserve CSS classes, IDs, and attributes - Maintain markdown editing UX while storing HTML for style preservation - Support complex attributes like rel, data-*, aria-*, etc. This enables editing styled content like <a class="fancy" rel="me">text</a> while preserving all styling attributes through the markdown editing process.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { InsertrFormRenderer } from '../ui/form-renderer.js';
|
||||
import { markdownConverter } from '../utils/markdown.js';
|
||||
|
||||
/**
|
||||
* InsertrEditor - Content editing workflow and business logic
|
||||
@@ -114,16 +115,35 @@ export class InsertrEditor {
|
||||
|
||||
try {
|
||||
// Extract content value based on type
|
||||
let contentValue;
|
||||
let markdownContent;
|
||||
if (meta.element.tagName.toLowerCase() === 'a') {
|
||||
// For links, save the text content (URL is handled separately if needed)
|
||||
contentValue = formData.text || formData;
|
||||
markdownContent = formData.text || formData;
|
||||
} else {
|
||||
contentValue = formData.text || formData;
|
||||
markdownContent = formData.text || formData;
|
||||
}
|
||||
|
||||
// Convert markdown to HTML with style preservation
|
||||
let contentValue;
|
||||
const contentType = this.determineContentType(meta.element);
|
||||
|
||||
if (contentType === 'html') {
|
||||
// Extract style context from original element and convert markdown to HTML
|
||||
const { markdown, styleContext } = markdownConverter.htmlToMarkdownWithContext(meta.element.innerHTML, meta.element);
|
||||
|
||||
if (styleContext && styleContext.hasPreservableContent) {
|
||||
// Convert markdown back to HTML with style preservation
|
||||
contentValue = markdownConverter.markdownToHtmlWithStyles(markdownContent, styleContext);
|
||||
} else {
|
||||
// No styles to preserve, simple conversion
|
||||
contentValue = markdownConverter.markdownToHtml(markdownContent);
|
||||
}
|
||||
} else {
|
||||
// For other content types (text, link), use markdown as-is
|
||||
contentValue = markdownContent;
|
||||
}
|
||||
|
||||
// Universal upsert - server handles ID extraction/generation from markup
|
||||
const contentType = this.determineContentType(meta.element);
|
||||
const result = await this.apiClient.createContent(
|
||||
contentValue,
|
||||
contentType,
|
||||
@@ -155,8 +175,8 @@ export class InsertrEditor {
|
||||
return 'link';
|
||||
}
|
||||
|
||||
// ALL text elements use markdown for consistent editing experience
|
||||
return 'markdown';
|
||||
// ALL text elements use HTML storage with markdown editing interface
|
||||
return 'html';
|
||||
}
|
||||
|
||||
handleCancel(meta) {
|
||||
|
||||
Reference in New Issue
Block a user