mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Merge branch 'fix-apostrophe-issue' into 'main'
Fixed apostrophe issue Closes #190 See merge request soapbox-pub/ditto!470
This commit is contained in:
commit
cde70e4c8f
2 changed files with 42 additions and 15 deletions
|
|
@ -10,6 +10,27 @@ Deno.test('parseNoteContent', () => {
|
||||||
assertEquals(firstUrl, undefined);
|
assertEquals(firstUrl, undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test('parseNoteContent handles apostrophes', () => {
|
||||||
|
const { html } = parseNoteContent(
|
||||||
|
`did you see nostr:nprofile1qqsqgc0uhmxycvm5gwvn944c7yfxnnxm0nyh8tt62zhrvtd3xkj8fhgprdmhxue69uhkwmr9v9ek7mnpw3hhytnyv4mz7un9d3shjqgcwaehxw309ahx7umywf5hvefwv9c8qtmjv4kxz7gpzemhxue69uhhyetvv9ujumt0wd68ytnsw43z7s3al0v's speech?`,
|
||||||
|
[{
|
||||||
|
id: '0461fcbecc4c3374439932d6b8f11269ccdb7cc973ad7a50ae362db135a474dd',
|
||||||
|
username: 'alex',
|
||||||
|
acct: 'alex@gleasonator.dev',
|
||||||
|
url: 'https://gleasonator.dev/@alex',
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
html,
|
||||||
|
`did you see <span class="h-card"><a class="u-url mention" href="https://gleasonator.dev/@alex" rel="ugc">@<span>alex@gleasonator.dev</span></a></span>'s speech?`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test("parseNoteContent doesn't parse invalid nostr URIs", () => {
|
||||||
|
const { html } = parseNoteContent(`nip19 has URIs like nostr:npub and nostr:nevent, etc.`, []);
|
||||||
|
assertEquals(html, 'nip19 has URIs like nostr:npub and nostr:nevent, etc.');
|
||||||
|
});
|
||||||
|
|
||||||
Deno.test('getMediaLinks', () => {
|
Deno.test('getMediaLinks', () => {
|
||||||
const links = [
|
const links = [
|
||||||
{ href: 'https://example.com/image.png' },
|
{ href: 'https://example.com/image.png' },
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import 'linkify-plugin-hashtag';
|
import 'linkify-plugin-hashtag';
|
||||||
import linkifyStr from 'linkify-string';
|
import linkifyStr from 'linkify-string';
|
||||||
import linkify from 'linkifyjs';
|
import linkify from 'linkifyjs';
|
||||||
import { nip19, nip21, nip27 } from 'nostr-tools';
|
import { nip19, nip27 } from 'nostr-tools';
|
||||||
|
|
||||||
import { Conf } from '@/config.ts';
|
import { Conf } from '@/config.ts';
|
||||||
import { MastodonMention } from '@/entities/MastodonMention.ts';
|
import { MastodonMention } from '@/entities/MastodonMention.ts';
|
||||||
|
import { html } from '@/utils/html.ts';
|
||||||
import { getUrlMediaType, isPermittedMediaType } from '@/utils/media.ts';
|
import { getUrlMediaType, isPermittedMediaType } from '@/utils/media.ts';
|
||||||
|
|
||||||
linkify.registerCustomProtocol('nostr', true);
|
linkify.registerCustomProtocol('nostr', true);
|
||||||
|
|
@ -24,16 +25,21 @@ function parseNoteContent(content: string, mentions: MastodonMention[]): ParsedN
|
||||||
const links = linkify.find(content).filter(isLinkURL);
|
const links = linkify.find(content).filter(isLinkURL);
|
||||||
const firstUrl = links.find(isNonMediaLink)?.href;
|
const firstUrl = links.find(isNonMediaLink)?.href;
|
||||||
|
|
||||||
const html = linkifyStr(content, {
|
const result = linkifyStr(content, {
|
||||||
render: {
|
render: {
|
||||||
hashtag: ({ content }) => {
|
hashtag: ({ content }) => {
|
||||||
const tag = content.replace(/^#/, '');
|
const tag = content.replace(/^#/, '');
|
||||||
const href = Conf.local(`/tags/${tag}`);
|
const href = Conf.local(`/tags/${tag}`);
|
||||||
return `<a class=\"mention hashtag\" href=\"${href}\" rel=\"tag\"><span>#</span>${tag}</a>`;
|
return html`<a class="mention hashtag" href="${href}" rel="tag"><span>#</span>${tag}</a>`;
|
||||||
},
|
},
|
||||||
url: ({ attributes, content }) => {
|
url: ({ attributes, content }) => {
|
||||||
try {
|
try {
|
||||||
const { decoded } = nip21.parse(content);
|
const { pathname } = new URL(content);
|
||||||
|
const match = pathname.match(new RegExp(`^${nip19.BECH32_REGEX.source}`));
|
||||||
|
if (match) {
|
||||||
|
const bech32 = match[0];
|
||||||
|
const extra = pathname.slice(bech32.length);
|
||||||
|
const decoded = nip19.decode(bech32);
|
||||||
const pubkey = getDecodedPubkey(decoded);
|
const pubkey = getDecodedPubkey(decoded);
|
||||||
if (pubkey) {
|
if (pubkey) {
|
||||||
const mention = mentions.find((m) => m.id === pubkey);
|
const mention = mentions.find((m) => m.id === pubkey);
|
||||||
|
|
@ -41,10 +47,10 @@ function parseNoteContent(content: string, mentions: MastodonMention[]): ParsedN
|
||||||
const acct = mention?.acct ?? npub;
|
const acct = mention?.acct ?? npub;
|
||||||
const name = mention?.acct ?? npub.substring(0, 8);
|
const name = mention?.acct ?? npub.substring(0, 8);
|
||||||
const href = mention?.url ?? Conf.local(`/@${acct}`);
|
const href = mention?.url ?? Conf.local(`/@${acct}`);
|
||||||
return `<span class="h-card"><a class="u-url mention" href="${href}" rel="ugc">@<span>${name}</span></a></span>`;
|
return html`<span class="h-card"><a class="u-url mention" href="${href}" rel="ugc">@<span>${name}</span></a></span>${extra}`;
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return content;
|
||||||
} catch {
|
} catch {
|
||||||
const attr = Object.entries(attributes)
|
const attr = Object.entries(attributes)
|
||||||
.map(([name, value]) => `${name}="${value}"`)
|
.map(([name, value]) => `${name}="${value}"`)
|
||||||
|
|
@ -57,7 +63,7 @@ function parseNoteContent(content: string, mentions: MastodonMention[]): ParsedN
|
||||||
}).replace(/\n+$/, '');
|
}).replace(/\n+$/, '');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
html,
|
html: result,
|
||||||
links,
|
links,
|
||||||
firstUrl,
|
firstUrl,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue