Merge pull request #5 from jedmund/markdown-links
Fix markdown link saving and rendering
This commit is contained in:
commit
2513e19b37
3 changed files with 9087 additions and 9172 deletions
18154
package-lock.json
generated
18154
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -239,20 +239,21 @@
|
|||
return true // Prevent default paste behavior
|
||||
}
|
||||
|
||||
// Handle text paste - strip HTML formatting
|
||||
// Handle text paste - preserve links while stripping other formatting
|
||||
const htmlData = clipboardData.getData('text/html')
|
||||
const plainText = clipboardData.getData('text/plain')
|
||||
|
||||
if (htmlData && plainText) {
|
||||
// If we have both HTML and plain text, use plain text to strip formatting
|
||||
event.preventDefault()
|
||||
|
||||
// Use editor commands to insert text so all callbacks are triggered
|
||||
// Use editor commands to insert HTML content, but let Tiptap handle the parsing
|
||||
// This will preserve links while stripping unwanted formatting based on editor config
|
||||
const editorInstance = (view as any).editor
|
||||
if (editorInstance) {
|
||||
editorInstance.chain().focus().insertContent(plainText).run()
|
||||
// Use pasteHTML to let Tiptap process the HTML and apply configured extensions
|
||||
editorInstance.chain().focus().insertContent(htmlData, { parseOptions: { preserveWhitespace: false } }).run()
|
||||
} else {
|
||||
// Fallback to manual transaction
|
||||
// Fallback to plain text if editor instance not available
|
||||
const { state, dispatch } = view
|
||||
const { selection } = state
|
||||
const transaction = state.tr.insertText(plainText, selection.from, selection.to)
|
||||
|
|
|
|||
|
|
@ -135,93 +135,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Convert Tiptap format back to blocks format for saving
|
||||
function convertTiptapToBlocks(tiptapContent: JSONContent): any {
|
||||
if (!tiptapContent || !tiptapContent.content) {
|
||||
return { blocks: [] }
|
||||
}
|
||||
|
||||
const blocks = tiptapContent.content
|
||||
.map((node: any) => {
|
||||
switch (node.type) {
|
||||
case 'paragraph':
|
||||
const text = extractTextFromNode(node)
|
||||
return text ? { type: 'paragraph', content: text } : null
|
||||
|
||||
case 'heading':
|
||||
return {
|
||||
type: 'heading',
|
||||
level: node.attrs?.level || 1,
|
||||
content: extractTextFromNode(node)
|
||||
}
|
||||
|
||||
case 'bulletList':
|
||||
return {
|
||||
type: 'bulletList',
|
||||
content:
|
||||
node.content
|
||||
?.map((item: any) => {
|
||||
const itemText = extractTextFromNode(item.content?.[0])
|
||||
return itemText
|
||||
})
|
||||
.filter(Boolean) || []
|
||||
}
|
||||
|
||||
case 'orderedList':
|
||||
return {
|
||||
type: 'orderedList',
|
||||
content:
|
||||
node.content
|
||||
?.map((item: any) => {
|
||||
const itemText = extractTextFromNode(item.content?.[0])
|
||||
return itemText
|
||||
})
|
||||
.filter(Boolean) || []
|
||||
}
|
||||
|
||||
case 'blockquote':
|
||||
return {
|
||||
type: 'blockquote',
|
||||
content: extractTextFromNode(node.content?.[0])
|
||||
}
|
||||
|
||||
case 'codeBlock':
|
||||
return {
|
||||
type: 'codeBlock',
|
||||
language: node.attrs?.language || '',
|
||||
content: node.content?.[0]?.text || ''
|
||||
}
|
||||
|
||||
case 'image':
|
||||
return {
|
||||
type: 'image',
|
||||
src: node.attrs?.src || '',
|
||||
alt: node.attrs?.alt || '',
|
||||
caption: node.attrs?.title || ''
|
||||
}
|
||||
|
||||
case 'horizontalRule':
|
||||
return { type: 'hr' }
|
||||
|
||||
default:
|
||||
// Skip unknown types
|
||||
return null
|
||||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
return { blocks }
|
||||
}
|
||||
|
||||
// Helper function to extract text from a node
|
||||
function extractTextFromNode(node: any): string {
|
||||
if (!node) return ''
|
||||
if (node.text) return node.text
|
||||
if (node.content && Array.isArray(node.content)) {
|
||||
return node.content.map((n: any) => extractTextFromNode(n)).join('')
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
// Wait a tick to ensure page params are loaded
|
||||
|
|
@ -310,11 +223,8 @@
|
|||
|
||||
saving = true
|
||||
|
||||
// Convert content to blocks format if it's in Tiptap format
|
||||
let saveContent = content
|
||||
if (config?.showContent && content && content.type === 'doc') {
|
||||
saveContent = convertTiptapToBlocks(content)
|
||||
}
|
||||
// Save content in native Tiptap format to preserve all formatting
|
||||
const saveContent = content
|
||||
|
||||
const postData = {
|
||||
title: config?.showTitle ? title : null,
|
||||
|
|
|
|||
Loading…
Reference in a new issue