@engie-group/fluid-design-system-angular
Version:
Fluid Design System Angular
75 lines (66 loc) • 2.4 kB
text/typescript
import {Directive, ElementRef, Input, OnChanges, SimpleChanges} from '@angular/core';
import {Utils} from '../../utils/utils.util';
export class HighlightDirective implements OnChanges {
/**
* Content we want to highlight
*/
public content: string;
/**
* Text to highlight in the content
*/
public textToHighlight: string;
/**
* Whether to escape accents or no
*/
public escapeAccents = true;
/**
* Whether to take into account case or no
*/
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;
}
}