feat(05-02): create highlightText utility function

- Wrap matching text in <mark> tags with bold styling
- Escape HTML before highlighting to prevent XSS
- 2-character minimum query requirement
- Uses bg-transparent (no background per CONTEXT.md)
This commit is contained in:
Thomas Richter
2026-01-31 17:12:43 +01:00
parent b7a982c104
commit 6dbe660a8e

View File

@@ -0,0 +1,36 @@
/**
* Wraps matching text in <mark> tags for highlighting.
* Returns HTML string to be used with {@html} in Svelte.
*
* @param text - The text to search within
* @param query - The search query to highlight
* @returns HTML string with matches wrapped in <mark> tags
*/
export function highlightText(text: string, query: string): string {
// Don't highlight if query is too short
if (!query || query.length < 2) return escapeHtml(text);
// Escape HTML in the original text first
const escaped = escapeHtml(text);
// Escape regex special characters in query
const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(`(${escapedQuery})`, 'gi');
// Wrap matches in <mark> with bold styling (no background per CONTEXT.md)
return escaped.replace(regex, '<mark class="font-bold bg-transparent">$1</mark>');
}
/**
* Escapes HTML special characters to prevent XSS.
*/
function escapeHtml(text: string): string {
const map: Record<string, string> = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return text.replace(/[&<>"']/g, (char) => map[char]);
}