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...