JSFiddle - React, Tailwind, and code Playground

by Ivan Ferrer

HTML

<button data-id-el="123" id="cancel1">
Marcar normal
</button>


<button data-id-el="321" id="cancel2">
Marcar com parágrafo
</button>

<div class="text-review">

<p>Gasolina, tomate e remédios foram os vilões do mês</p>

<p>

Já os principais impactos <span data-id="123" class="color hightcolor-3">individuais no mês</span>, segundo o IBGE, vieram das altas da gasolina (2,66%), tomate (28,64%) e dos remédios (2,25%), refletindo este último o reajuste anual, em vigor desde asfdasf saf.</p>

<p>

Outros destaques de alta no mês foram passagem aérea (5,32%), ônibus urbano (0,74%) e plano de saúde (0,80%). wqerqwrqwrqwr gfsd sdgsdgs</p>

<p>
      <strong>Gasolina, tomate e remédios foram os vilões do mês</strong></p>
      <p>Já os principais impactos individuais no mês, segundo o IBGE, vieram das altas da&nbsp;gasolina (2,66%), tomate (28,64%) e dos remédios (2,25%), refletindo este último o reajuste anual, em vigor desde 31 de março, co</p>

     <span class="color with-paragraph-321 hightcolor-3 ng-scope" data-id="321" id="mark_321" data-color="3" data-user="23455" data-date="2019-07-03 11:51:45" data-timestamp="1562165505000" data-note="" data-text="m teto de 4,33%. Outros destaqu" title="" data-zindex="3" style="z-index: 3" data-selection="2" data-category="">

             <span class="paragraph color hightcolor-3" data-id="321" id="mark_321" data-color="3" data-user="23455" data-date="2019-07-03 11:51:45" data-timestamp="1562165505000" data-note="" data-text="m teto de 4,33%. Outros destaqu" title="" data-zindex="3" style="z-index: 3" data-selection="2" data-category="">

                  <p>m teto de 4,33%.</p>

             </span>

             <span class="paragraph color hightcolor-3" data-id="321" id="mark_321" data-color="3" data-user="23455" data-date="2019-07-03 11:51:45" data-timestamp="1562165505000" data-note="" data-text="m teto de 4,33%. Outros destaqu" title="" data-zindex="3" style="z-index: 3" data-selection="2" data-category="">

          ...

CSS

.color.hightcolor-3 {
      background-image: linear-gradient(to right, transparent 50%, #b7ca58 50%);
    background-origin: 0;
    background-size: 200% 90%;
    background-repeat: repeat-x;
    background-position: -100% 100%;
    transition: background-position 0.5s;

}
.color {
      cursor: pointer;
    position: relative;
    color: white;
    padding: 4px;
}
.color p {
  display:contents;
  }
p {
  font-family: sans-serif;
  margin: 18px 0;
    text-align: justify;
    width: auto;
    font-size: 15px;
}

JavaScript

$(function() {

$(document).on('mouseup click', '.text-review', function(e) {

 if ((e.type == 'mouseup' && window.getSelection)) {
 
 $('.text-review').off("mouseup");
   e.preventDefault();
   e.stopPropagation();
   e.stopImmediatePropagation();
   return;
}

var id = Math.floor((Math.random() * 100) + new Date().getTime());

var currentDateTimeEng = '2019-10-10 10:10:10';
var add_new = false, c = 0, id = null, note = "", text = "",continueSelection = true, selectedText,selectedTextHTML, selectionEl, sel, range, 
textSelection = {
                        text: "",
                        id: 123,
                        user: 1,
                        date: currentDateTimeEng,
                        color: 3,
                        note: "",
                        zindex: 1,
                        category: "",
                        is_new:true,
                        add_btn_delete:false
                    };
                    
var color = textSelection.color;

textSelection.note = prompt("Comentário: ", 'Comentário sobre o trecho...');

var add_paragraph = '';

if (typeof window.getSelection !== "undefined") {
    selectedText = window.getSelection().toString();

    selectedTextHTML = window.getSelection().getRangeAt(0).cloneContents();
  

} else if (typeof document.selection !== "undefined" &&  document.selection.type == "Text") {
    selectedText = document.selection.createRange().text;
    selectedTextHTML = (document.selection.createRange()).getRangeAt(0).cloneContents();
  
}

if (selectedText && continueSelection) {

    //define o texto para o objeto
    textSelection.text = selectedText;

    if (document.selection && document.selection.createRange) {
        // Clone the TextRange and collapse
        range = document.selection.createRange().duplicate();
        //range.collapse(false);

    } else if (window.getSelection) {
        sel = window.getSelection();

        if (selectedText.length > 0 && sel) {

            if (typeof...