fix(workspace): tighten link preview card, slash menu matching/scrolling, and Enter on last empty bullet

This commit is contained in:
sandrodach committed 2026-10-30 09:21:29 +01:00
1 parent 02ce554c02
commit 446f8e4649
5 files changed
+209 -48

No files matched your search

+11 -9
View File
@@ -1,14 +1,16 @@
import { describe, expect, it } from 'vitest';
import { firstBareUrl, hidePreviewContent } from '../linkPreview';
import { linkCardUrl, hidePreviewContent } from '../linkPreview';
describe('link preview helpers', () => {
it('finds the first plain https address', () => {
expect(firstBareUrl('https://example.com/a?b=1')).toBe('https://example.com/a?b=1');
expect(firstBareUrl('Rezept: https://koch.de/spaetzle, lecker!')).toBe('https://koch.de/spaetzle');
expect(firstBareUrl('siehe (https://x.de/p).')).toBeNull(); // inside brackets: not a plain address
expect(firstBareUrl('[Kochseite](https://koch.de)')).toBeNull();
expect(firstBareUrl('http://unsicher.de')).toBeNull();
expect(firstBareUrl('nur Text')).toBeNull();
it('returns the URL only when the entire trimmed content is a single https address', () => {
expect(linkCardUrl('https://example.com/a?b=1')).toBe('https://example.com/a?b=1');
expect(linkCardUrl(' https://example.com/page/ ')).toBe('https://example.com/page/');
expect(linkCardUrl('Rezept: https://koch.de/spaetzle, lecker!')).toBeNull();
expect(linkCardUrl('https://a.de https://b.de')).toBeNull();
expect(linkCardUrl('siehe (https://x.de/p).')).toBeNull();
expect(linkCardUrl('[Kochseite](https://koch.de)')).toBeNull();
expect(linkCardUrl('http://unsicher.de')).toBeNull();
expect(linkCardUrl('nur Text')).toBeNull();
});
it('hides a preview by turning the address into a named link', () => {
@@ -16,6 +18,6 @@ describe('link preview helpers', () => {
'Lesen: [Käsespätzle Rezept](https://koch.de/x)'
);
expect(hidePreviewContent('https://koch.de/x', 'https://koch.de/x', '')).toBe('[koch.de](https://koch.de/x)');
expect(firstBareUrl(hidePreviewContent('https://koch.de/x', 'https://koch.de/x', 'T'))).toBeNull();
expect(linkCardUrl(hidePreviewContent('https://koch.de/x', 'https://koch.de/x', 'T'))).toBeNull();
});
});
+5 -5
View File
@@ -16,12 +16,12 @@ export interface LinkPreview {
ok: boolean;
}
// First plain https address in a text (not inside [text](url), not right after "(" or "<")
const BARE_URL_RE = /(^|[\s])(https:\/\/[^\s<>()\]]+[^\s<>()\].,;:!?'"])/;
// Entire bullet content (trimmed) is a single plain https address
const CARD_URL_RE = /^https:\/\/[^\s<>()\]]+[^\s<>()\].,;:!?'"]$/;
export function firstBareUrl(content: string): string | null {
const m = BARE_URL_RE.exec(content || '');
return m ? m[2] : null;
export function linkCardUrl(content: string): string | null {
const trimmed = (content || '').trim();
return CARD_URL_RE.test(trimmed) ? trimmed : null;
}
/** Replaces the address by a named link, which shows no preview. */