JSFiddle - React, Tailwind, and code Playground

by brigand

HTML

<div>
<p>
line1
</p>
<p>
line2
</p>
<span>line3</span>
<p>
line4
</p>
<span>line5</span>
<p>
line6
</p>
<span>line7</span>
<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
    <th>Age</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td>
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
</table>
</div>
<span>awoifja woiefj awf</span>

JavaScript

function getSafeRanges(dangerous) {
  // a for ancestor
  const a = dangerous.commonAncestorContainer;
  // Starts -- Work inward from the start, selecting the largest safe range
  const s = [];
  const rs = [];
  // if highlight doesn't start and end in the same container…
  if (dangerous.startContainer != a) {
    for (let i = dangerous.startContainer; i != a; i = i.parentNode) {
      // put the starting text and all its parents (except
      // common ancestor of start and end) into array `s`
      /*       debugger */
      s.push(i);
    }
  }
  // if highlight didn't start and end in the same container,
  // then create a new range for each item in `s`
  if (s.length > 0) {
    for (let i = 0; i < s.length; i++) {
      const xs = document.createRange();
      console.log(i, xs)
      /* debugger */
      // if at the parents of starting node
      if (i) {
        xs.setStartAfter(s[i - 1]);
        xs.setEndAfter(s[i].lastChild);
      }
      // if at the starting node (text node)
      else {
        xs.setStart(s[i], dangerous.startOffset);
        /* if (s[i].nodeType != Node.TEXT_NODE) debugger */
        xs.setEndAfter(
          (s[i].nodeType == Node.TEXT_NODE) ?
          s[i] :
          s[i].lastChild
        );
      }
      console.log(i)
      rs.push(xs);
      console.log("rs", rs)
      /* debugger */
    }
  }

  // Ends -- basically the same code reversed
  const e = [];
  const re = [];
  // if highlight doesn't start and end in the same container…
  if (dangerous.endContainer != a) {
    for (let i = dangerous.endContainer; i != a; i = i.parentNode) {
      // put the ending text and all its parents (except
      // common ancestor of start and end) into array `e`
      e.push(i);
    }
  }
  // if highlight didn't start and end in the same container,
  // then create a new range for each item in `e`
  if (e.length > 0) {
    for (let i = 0; i < e.length; i++) {
      const xe = document.createRange();
      // if at the parents of...