Skip to content

Instantly share code, notes, and snippets.

@marcorinck
Last active August 17, 2020 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcorinck/0966378a9b550ed7e93aec469dc50e85 to your computer and use it in GitHub Desktop.
Save marcorinck/0966378a9b550ed7e93aec469dc50e85 to your computer and use it in GitHub Desktop.
import {Directive, HostBinding, Input, OnChanges, SecurityContext, SimpleChanges} from "@angular/core";
import {DomSanitizer, SafeHtml} from "@angular/platform-browser";
@Directive({
selector: "[appHighlight]",
})
export class HighlightDirective implements OnChanges {
@Input()
searchTerm: string;
@Input()
text: string;
@HostBinding("innerHTML")
html: SafeHtml;
constructor(private sanitizer: DomSanitizer) {
}
ngOnChanges(changes: SimpleChanges) {
if (changes.text || changes.searchTerm) {
this.highlight(this.searchTerm, this.text);
}
}
private highlight(searchTerm?: string, searchText?: string) {
const term = String(searchTerm ?? "");
const text = String(searchText ?? "");
const regEx = new RegExp('(' + this.escapeRegExp(term) + ')', 'i');
const results = text.split(regEx);
let unsanitizedHtml = "";
for (const result of results) {
if (result === term) {
unsanitizedHtml += "<span class='highlight'>" + this.escapeHtml(result) + "</span>"
} else {
unsanitizedHtml += this.escapeHtml(result);
}
}
const sanitizedHtml = this.sanitizer.sanitize(SecurityContext.HTML, unsanitizedHtml);
this.html = this.sanitizer.bypassSecurityTrustHtml(sanitizedHtml ?? "");
}
private escapeRegExp(string: string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
}
private escapeHtml(str: string): string {
return str.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment