Build an HTML-safe string with every case-insensitive occurrence of query inside
text wrapped in the supplied <mark> tag. Designed for search-result UIs whose
output is bound to Angular's [innerHTML] (or any equivalent that trusts raw HTML).
SECURITY: The result IS raw HTML. Each text segment (before / match / after) is
HTML-escaped individually before concatenation. Callers must pass plain text,
not pre-escaped HTML — escaping the input up-front would corrupt entity codes
when the search term overlaps an entity (e.g. searching "amp" inside &)
and is the exact failure mode this helper is built to prevent.
Behavior notes:
Case-insensitive match; original casing of text is preserved in the output.
All occurrences are highlighted (matches the behavior of a /.../gi regex).
query is treated as a literal string — no regex semantics, so search terms
like . or $10 work as users expect.
Empty/falsy query returns EscapeHTML(text) so the result is always
[innerHTML]-safe.
Parameters
text: string
The plain text to search and render.
query: string
The substring to highlight (literal match, case-insensitive).
OptionalmarkClass: string
Optional CSS class to apply to the <mark> element.
Build an HTML-safe string with every case-insensitive occurrence of
queryinsidetextwrapped in the supplied<mark>tag. Designed for search-result UIs whose output is bound to Angular's[innerHTML](or any equivalent that trusts raw HTML).SECURITY: The result IS raw HTML. Each text segment (before / match / after) is HTML-escaped individually before concatenation. Callers must pass plain text, not pre-escaped HTML — escaping the input up-front would corrupt entity codes when the search term overlaps an entity (e.g. searching "amp" inside
&) and is the exact failure mode this helper is built to prevent.Behavior notes:
textis preserved in the output./.../giregex).queryis treated as a literal string — no regex semantics, so search terms like.or$10work as users expect.queryreturnsEscapeHTML(text)so the result is always[innerHTML]-safe.