fix(tiptap): mention transform, close #521

zio/stable
Anthony Fu 2023-01-08 10:39:11 +01:00
parent c7f4b33bf1
commit 2df2fefdc9
1 changed files with 22 additions and 0 deletions

View File

@ -10,6 +10,7 @@ export interface ContentParseOptions {
markdown?: boolean markdown?: boolean
replaceUnicodeEmoji?: boolean replaceUnicodeEmoji?: boolean
astTransforms?: Transform[] astTransforms?: Transform[]
convertMentionLink?: boolean
} }
const sanitizerBasicClasses = filterClasses(/^(h-\S*|p-\S*|u-\S*|dt-\S*|e-\S*|mention|hashtag|ellipsis|invisible)$/u) const sanitizerBasicClasses = filterClasses(/^(h-\S*|p-\S*|u-\S*|dt-\S*|e-\S*|mention|hashtag|ellipsis|invisible)$/u)
@ -53,6 +54,7 @@ export function parseMastodonHTML(
const { const {
markdown = true, markdown = true,
replaceUnicodeEmoji = true, replaceUnicodeEmoji = true,
convertMentionLink = false,
} = options } = options
if (markdown) { if (markdown) {
@ -77,6 +79,9 @@ export function parseMastodonHTML(
if (markdown) if (markdown)
transforms.push(transformMarkdown) transforms.push(transformMarkdown)
if (convertMentionLink)
transforms.push(transformMentionLink)
transforms.push(replaceCustomEmoji(options.emojis || {})) transforms.push(replaceCustomEmoji(options.emojis || {}))
transforms.push(transformParagraphs) transforms.push(transformParagraphs)
@ -92,6 +97,7 @@ export function convertMastodonHTML(html: string, customEmojis: Record<string, m
emojis: customEmojis, emojis: customEmojis,
markdown: true, markdown: true,
replaceUnicodeEmoji: false, replaceUnicodeEmoji: false,
convertMentionLink: true,
}) })
return render(tree) return render(tree)
} }
@ -360,3 +366,19 @@ function transformParagraphs(node: Node): Node | Node[] {
return [node, h('p')] return [node, h('p')]
return node return node
} }
function transformMentionLink(node: Node): string | Node | (string | Node)[] | null {
if (node.name === 'a' && node.attributes.class?.includes('mention')) {
const href = node.attributes.href
if (href) {
const matchUser = href.match(UserLinkRE)
if (matchUser) {
const [, server, username] = matchUser
const handle = `${username}@${server.replace(/(.+\.)(.+\..+)/, '$2')}`
// convert to TipTap mention node
return h('span', { 'data-type': 'mention', 'data-id': handle }, handle)
}
}
}
return node
}