fix: button/card syntax mismatch between blocksToMarkdown and markdownToBlocks
ROOT CAUSE: Complete flow trace revealed syntax mismatch:
- blocksToMarkdown outputs NEW syntax: [card:type], [button:style](url)Text[/button]
- markdownToBlocks ONLY parsed OLD syntax: [card type="..."], [button url="..."]
This caused buttons/cards to be lost when:
1. User adds button in Visual mode
2. blocksToMarkdown converts to [button:solid]({url})Text[/button]
3. handleBlocksChange stores this in markdownContent
4. When switching tabs/previewing, markdownToBlocks runs
5. It FAILED to parse new syntax, buttons disappear!
FIX: Added handlers for NEW syntax in markdownToBlocks (converter.ts):
- [card:type]...[/card] pattern (before old syntax)
- [button:style](url)Text[/button] pattern (before old syntax)
Now both syntaxes work correctly in round-trip conversion.
This commit is contained in:
@@ -320,7 +320,24 @@ export function markdownToBlocks(markdown: string): EmailBlock[] {
|
|||||||
|
|
||||||
const id = `block-${Date.now()}-${blockId++}`;
|
const id = `block-${Date.now()}-${blockId++}`;
|
||||||
|
|
||||||
// Check for [card] blocks - match with proper boundaries
|
// Check for [card] blocks - NEW syntax [card:type]...[/card]
|
||||||
|
const newCardMatch = remaining.match(/^\[card:(\w+)\]([\s\S]*?)\[\/card\]/);
|
||||||
|
if (newCardMatch) {
|
||||||
|
const cardType = newCardMatch[1] as CardType;
|
||||||
|
const content = newCardMatch[2].trim();
|
||||||
|
|
||||||
|
blocks.push({
|
||||||
|
id,
|
||||||
|
type: 'card',
|
||||||
|
cardType,
|
||||||
|
content,
|
||||||
|
});
|
||||||
|
|
||||||
|
remaining = remaining.substring(newCardMatch[0].length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for [card] blocks - OLD syntax [card type="..."]...[/card]
|
||||||
const cardMatch = remaining.match(/^\[card([^\]]*)\]([\s\S]*?)\[\/card\]/);
|
const cardMatch = remaining.match(/^\[card([^\]]*)\]([\s\S]*?)\[\/card\]/);
|
||||||
if (cardMatch) {
|
if (cardMatch) {
|
||||||
const attributes = cardMatch[1].trim();
|
const attributes = cardMatch[1].trim();
|
||||||
@@ -347,7 +364,24 @@ export function markdownToBlocks(markdown: string): EmailBlock[] {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for [button] blocks
|
// Check for [button] blocks - NEW syntax [button:style](url)Text[/button]
|
||||||
|
const newButtonMatch = remaining.match(/^\[button:(\w+)\]\(([^)]+)\)([^\[]+)\[\/button\]/);
|
||||||
|
if (newButtonMatch) {
|
||||||
|
blocks.push({
|
||||||
|
id,
|
||||||
|
type: 'button',
|
||||||
|
text: newButtonMatch[3].trim(),
|
||||||
|
link: newButtonMatch[2],
|
||||||
|
style: newButtonMatch[1] as ButtonStyle,
|
||||||
|
align: 'center',
|
||||||
|
widthMode: 'fit',
|
||||||
|
});
|
||||||
|
|
||||||
|
remaining = remaining.substring(newButtonMatch[0].length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for [button] blocks - OLD syntax [button url="..." style="..."]Text[/button]
|
||||||
const buttonMatch = remaining.match(/^\[button\s+url=["']([^"']+)["'](?:\s+style=["'](solid|outline)["'])?\]([^\[]+)\[\/button\]/);
|
const buttonMatch = remaining.match(/^\[button\s+url=["']([^"']+)["'](?:\s+style=["'](solid|outline)["'])?\]([^\[]+)\[\/button\]/);
|
||||||
if (buttonMatch) {
|
if (buttonMatch) {
|
||||||
blocks.push({
|
blocks.push({
|
||||||
|
|||||||
Reference in New Issue
Block a user