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:
36
src/lib/utils/highlightText.ts
Normal file
36
src/lib/utils/highlightText.ts
Normal 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> = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": '''
|
||||
};
|
||||
return text.replace(/[&<>"']/g, (char) => map[char]);
|
||||
}
|
||||
Reference in New Issue
Block a user