diff --git a/composables/content-parse.ts b/composables/content-parse.ts index 302b674ef..1e45ab99c 100644 --- a/composables/content-parse.ts +++ b/composables/content-parse.ts @@ -141,6 +141,12 @@ export function treeToText(input: Node): string { if (['p', 'pre'].includes(input.name)) pre = '\n' + if (input.attributes?.['data-type'] === 'mention') { + const acct = input.attributes['data-id'] + if (acct) + return acct.startsWith('@') ? acct : `@${acct}` + } + if (input.name === 'code') { if (input.parent?.name === 'pre') { const lang = input.attributes.class?.replace('language-', '') diff --git a/composables/content-render.ts b/composables/content-render.ts index fe6989075..26d350735 100644 --- a/composables/content-render.ts +++ b/composables/content-render.ts @@ -73,7 +73,7 @@ function handleMention(el: Node) { const matchUser = href.match(UserLinkRE) if (matchUser) { const [, server, username] = matchUser - const handle = `@${username}@${server.replace(/(.+\.)(.+\..+)/, '$2')}` + const handle = `${username}@${server.replace(/(.+\.)(.+\..+)/, '$2')}` el.attributes.href = `/${server}/@${username}` return h(AccountHoverWrapper, { handle, class: 'inline-block' }, () => nodeToVNode(el)) } diff --git a/tests/__snapshots__/content-rich.test.ts.snap b/tests/__snapshots__/content-rich.test.ts.snap index 94da49e0d..85001328f 100644 --- a/tests/__snapshots__/content-rich.test.ts.snap +++ b/tests/__snapshots__/content-rich.test.ts.snap @@ -152,3 +152,8 @@ exports[`content-rich > link + mention 1`] = `

" `; + +exports[`editor > transform mentions 1`] = ` +" +@elk Hello" +`; diff --git a/tests/content-rich.test.ts b/tests/content-rich.test.ts index bdbddc1a1..f66021bd6 100644 --- a/tests/content-rich.test.ts +++ b/tests/content-rich.test.ts @@ -168,6 +168,14 @@ describe('content-rich', () => { }) }) +describe('editor', () => { + it('transform mentions', () => { + const ast = parseMastodonHTML('

@elk Hello

') + const transformed = treeToText(ast) + expect(transformed).toMatchSnapshot() + }) +}) + async function render(content: string, options?: ContentParseOptions) { const vnode = contentToVNode(content, options) const html = (await renderToString(vnode))