stripHtml() strips tags via DOMParser (browser) with a regex fallback for SSR. plainExcerpt() truncates at a word boundary with an ellipsis. Both covered by Vitest specs. GeschichtenCard renders the top 3 published stories about a person on /persons/[id], with an editorial excerpt, publication date, author, and a "+ Geschichte schreiben" link visible only to BLOG_WRITERs. Footer link to /geschichten?personId=... appears once geschichten.length >= 3. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
24 lines
871 B
TypeScript
24 lines
871 B
TypeScript
/**
|
|
* Strip HTML tags from a string and return the plain text.
|
|
* Uses DOMParser in the browser, falls back to a regex strip on the server
|
|
* (where DOMParser is not available without isomorphic-dompurify's JSDOM).
|
|
*/
|
|
export function stripHtml(html: string | null | undefined): string {
|
|
if (!html) return '';
|
|
if (typeof DOMParser === 'function') {
|
|
const doc = new DOMParser().parseFromString(html, 'text/html');
|
|
return (doc.body.textContent ?? '').trim();
|
|
}
|
|
return html.replace(/<[^>]*>/g, '').trim();
|
|
}
|
|
|
|
/**
|
|
* Strip HTML and truncate to a maximum length, appending an ellipsis when
|
|
* the source exceeds it. Used for editorial story excerpts.
|
|
*/
|
|
export function plainExcerpt(html: string | null | undefined, max = 80): string {
|
|
const text = stripHtml(html);
|
|
if (text.length <= max) return text;
|
|
return text.slice(0, max).replace(/\s+\S*$/, '') + '…';
|
|
}
|