Highlight text with color in HTML contenteditable element.
I am trying to implement a possibility to highlight some text with a pre-defined highlight color in an HTML contenteditable element with a keyboard shortcut.
Initial idea was to use the native CTRL+U and give it css styles like
{ text-decoration: none, color: [my-highlight-color]}
This works great to set the color, but removing the color already doesn't work, as the browser recognizes that the text is not underlined.
I tried implementing a custom listener on editable elements:
const iframeDocument = this.templatePreviewIframe.nativeElement.contentWindow.document;
const selection = iframeDocument.getSelection();
if (!selection) return;
const range = selection.getRangeAt(0);
const selectedText = range.toString();
const paragraphText = elem.innerHTML;
const startIndex = paragraphText.indexOf(selectedText);
const endIndex = startIndex + selectedText.length;
if (!this.isHighlighted(range)) {
elem.innerHTML =
elem.innerHTML.slice(0, startIndex) + `<span style="color: ${this.highlightColor}">${selectedText}</span>` + elem.innerHTML.slice(endIndex, elem.innerHTML.length);
} else {
elem.innerHTML =
elem.innerHTML.slice(0, startIndex) + `</span>${selectedText}<span style="color: ${this.highlightColor}">` + elem.innerHTML.slice(endIndex, elem.innerHTML.length);
}
isHighlighted() just checks the computed style, works correct.
The problem I dont know how to solve is that the start index is calculated by first occurence of the selected substring and I dont have ideas how to get it correctly, unfortunately didnt find anything helpful on the Selection API, or I just don't understand how to use it properly. Also, not sure how to handle the more complex scenarios where user selected something mixed, where there is both highlighted and unhighlighted text. isHighlighted() return false in such scenarios.
p.s. Im using Angular