A lone link's preview is looked up where the server filed it
The server unfurls what detect_urls finds, trailing .,;:!? trimmed, and files the preview under that. The web and Android cards looked a lone link's preview up under body.trim(), punctuation included, so a note reading "https://example.com/a." never showed its card. - grammar.json gains a urls section: what the server finds in a body, and the link a lone-link note is filed under. - The web's rule moves out of NoteCard into notes/links.ts loneUrl(); Android's LinkPreviewRow gets the same loneUrl(); both trim like the server. - The server and web suites run the cases; Android's JVM test pins them by hand, as it does the tint. Fixes #5399. DRY pass #2, batch 3 (#5372). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import { describe, expect, it } from "vitest";
|
||||
import fixture from "../../../core/testdata/grammar.json";
|
||||
import { DERIVED_TINT_KEYS, derivedTint, resolveLabelColor, tintHash } from "./colors";
|
||||
import { parseInline, parseTaskLine, renderTaskLine } from "./markdown";
|
||||
import { loneUrl } from "./links";
|
||||
import { RECURRENCES } from "./recurrence";
|
||||
|
||||
describe("checklist lines", () => {
|
||||
@@ -59,3 +60,9 @@ describe("recurrences", () => {
|
||||
expect(RECURRENCES.map((r) => r.value)).toEqual(fixture.recurrences);
|
||||
});
|
||||
});
|
||||
|
||||
describe("links", () => {
|
||||
it.each(fixture.urls)("lone link in $body", ({ body, lone }) => {
|
||||
expect(loneUrl(body)).toBe(lone);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// A note that is nothing but a link renders as a link card.
|
||||
//
|
||||
// The characters a link runs over, and the punctuation trimmed off its end, are the
|
||||
// server's (unfurl_queue.detect_urls): the server files the preview under the trimmed
|
||||
// link, so the card has to look it up under the same one (#5399). Android's
|
||||
// LinkPreviewRow holds the same rule, and all three run the `urls` cases in
|
||||
// core/testdata/grammar.json.
|
||||
//
|
||||
// Whitespace either side still counts as lone: someone pasting a link rarely trims it.
|
||||
const LONE_URL_RE = /^\s*(https?:\/\/[^\s<>"'\])]+)\s*$/;
|
||||
|
||||
/** The link a lone-link note's preview is filed under, or null for any other body. */
|
||||
export function loneUrl(body: string): string | null {
|
||||
const match = LONE_URL_RE.exec(body);
|
||||
if (!match) return null;
|
||||
return match[1].replace(/[.,;:!?]+$/, "") || null;
|
||||
}
|
||||
Reference in New Issue
Block a user