UNPKG

@engie-group/fluid-design-system-angular

Version:

Fluid Design System Angular

75 lines (66 loc) 2.4 kB
import {Directive, ElementRef, Input, OnChanges, SimpleChanges} from '@angular/core'; import {Utils} from '../../utils/utils.util'; @Directive({ selector: '[njHighlight]', standalone: true }) export class HighlightDirective implements OnChanges { /** * Content we want to highlight */ @Input() public content: string; /** * Text to highlight in the content */ @Input() public textToHighlight: string; /** * Whether to escape accents or no */ @Input() public escapeAccents = true; /** * Whether to take into account case or no */ @Input() public caseSensitive = false; private readonly OPENING_TAG = '<mark class="nj-highlight">'; private readonly CLOSING_TAG = '</mark>'; constructor(private el: ElementRef) {} ngOnChanges(changes: SimpleChanges) { this.highlightText(); } private highlightText(): void { if (Utils.isUndefinedOrNull(this.content) || Utils.isUndefinedOrNull(this.el?.nativeElement)) { return; } const regexFlags = this.caseSensitive ? 'g' : 'gi'; let innerHtml: string; if (Utils.isUndefinedOrNull(this.textToHighlight)) { innerHtml = this.content; } else { if (this.escapeAccents) { const regExp = new RegExp(Utils.normalizeString(this.textToHighlight), regexFlags); const matches = Utils.normalizeString(this.content).matchAll(regExp); let finalText = this.content; let buffer = 0; if (!Utils.isUndefinedOrNull(matches)) { for (const match of matches) { const updatedIndex = buffer + match.index; const textBeforeOccurrence = finalText.slice(0, updatedIndex); const occurrence = finalText.slice(updatedIndex, updatedIndex + this.textToHighlight.length); const textAfterOccurrence = finalText.slice(updatedIndex + this.textToHighlight.length, finalText.length); finalText = `${textBeforeOccurrence}${this.OPENING_TAG}${occurrence}${this.CLOSING_TAG}${textAfterOccurrence}`; buffer = buffer + this.OPENING_TAG.length + this.CLOSING_TAG.length; } } innerHtml = finalText; } else { const regExp = new RegExp(this.textToHighlight, regexFlags); innerHtml = this.content.replace(regExp, `${this.OPENING_TAG}$&${this.CLOSING_TAG}`); } } this.el.nativeElement.innerHTML = innerHtml; } }