forked from Mirrors/elk
fix: use mention accts within a status to render links (#955)
This commit is contained in:
parent
f9509f8987
commit
c2850a34ae
4 changed files with 41 additions and 2 deletions
|
@ -17,6 +17,7 @@ const vnode = $computed(() => {
|
|||
return null
|
||||
const vnode = contentToVNode(status.content, {
|
||||
emojis: emojisObject.value,
|
||||
mentions: 'mentions' in status ? status.mentions : undefined,
|
||||
markdown: true,
|
||||
})
|
||||
return vnode
|
||||
|
|
|
@ -8,6 +8,7 @@ import { emojiRegEx, getEmojiAttributes } from '../config/emojis'
|
|||
|
||||
export interface ContentParseOptions {
|
||||
emojis?: Record<string, mastodon.v1.CustomEmoji>
|
||||
mentions?: mastodon.v1.StatusMention[]
|
||||
markdown?: boolean
|
||||
replaceUnicodeEmoji?: boolean
|
||||
astTransforms?: Transform[]
|
||||
|
@ -47,6 +48,7 @@ export function parseMastodonHTML(
|
|||
markdown = true,
|
||||
replaceUnicodeEmoji = true,
|
||||
convertMentionLink = false,
|
||||
mentions,
|
||||
} = options
|
||||
|
||||
if (markdown) {
|
||||
|
@ -74,6 +76,9 @@ export function parseMastodonHTML(
|
|||
if (markdown)
|
||||
transforms.push(transformMarkdown)
|
||||
|
||||
if (mentions?.length)
|
||||
transforms.push(createTransformNamedMentions(mentions))
|
||||
|
||||
if (convertMentionLink)
|
||||
transforms.push(transformMentionLink)
|
||||
|
||||
|
@ -377,3 +382,18 @@ function transformMentionLink(node: Node): string | Node | (string | Node)[] | n
|
|||
}
|
||||
return node
|
||||
}
|
||||
|
||||
function createTransformNamedMentions(mentions: mastodon.v1.StatusMention[]) {
|
||||
return (node: Node): string | Node | (string | Node)[] | null => {
|
||||
if (node.name === 'a' && node.attributes.class?.includes('mention')) {
|
||||
const href = node.attributes.href
|
||||
const mention = href && mentions.find(m => m.url === href)
|
||||
if (mention) {
|
||||
node.attributes.href = `/${currentServer.value}/@${mention.acct}`
|
||||
node.children = [h('span', { 'data-type': 'mention', 'data-id': mention.acct }, `@${mention.username}`)]
|
||||
return node
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,19 @@ exports[`content-rich > custom emoji 1`] = `
|
|||
|
||||
exports[`content-rich > empty 1`] = `""`;
|
||||
|
||||
exports[`content-rich > group mention > html 1`] = `
|
||||
"<p>
|
||||
<span class=\\"h-card\\"
|
||||
><a
|
||||
class=\\"u-url mention\\"
|
||||
rel=\\"nofollow noopener noreferrer\\"
|
||||
to=\\"//@pilipinas@lemmy.ml\\"
|
||||
></a
|
||||
></span>
|
||||
</p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`content-rich > handles html within code blocks 1`] = `
|
||||
"<p>
|
||||
HTML block code:<br />
|
||||
|
|
|
@ -20,6 +20,11 @@ describe('content-rich', () => {
|
|||
expect(formatted).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('group mention', async () => {
|
||||
const { formatted } = await render('<p><span class="h-card"><a href="https://lemmy.ml/c/pilipinas" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>pilipinas</span></a></span></p>', undefined, [{ id: '', username: 'pilipinas', url: 'https://lemmy.ml/c/pilipinas', acct: 'pilipinas@lemmy.ml' }])
|
||||
expect(formatted).toMatchSnapshot('html')
|
||||
})
|
||||
|
||||
it('inline code with link', async () => {
|
||||
const { formatted } = await render('<p>Inline code with link: `<a href="https://api.iconify.design/noto.css?icons=1st-place-medal,2nd-place-medal" target="_blank" rel="nofollow noopener noreferrer" class="status-link unhandled-link" title="https://api.iconify.design/noto.css?icons=1st-place-medal,2nd-place-medal"><span class="invisible">https://</span><span class="ellipsis">api.iconify.design/noto.css?ic</span><span class="invisible">ons=1st-place-medal,2nd-place-medal</span></a>`</p>')
|
||||
expect(formatted).toMatchSnapshot()
|
||||
|
@ -64,8 +69,8 @@ describe('content-rich', () => {
|
|||
})
|
||||
})
|
||||
|
||||
async function render(content: string, emojis?: Record<string, mastodon.v1.CustomEmoji>) {
|
||||
const vnode = contentToVNode(content, { emojis })
|
||||
async function render(content: string, emojis?: Record<string, mastodon.v1.CustomEmoji>, mentions?: mastodon.v1.StatusMention[]) {
|
||||
const vnode = contentToVNode(content, { emojis, mentions })
|
||||
const html = (await renderToString(vnode))
|
||||
.replace(/<!--[\[\]]-->/g, '')
|
||||
let formatted = ''
|
||||
|
|
Loading…
Reference in a new issue