JSFiddle - React, Tailwind, and code Playground
HTML
<p style="color:red">This is line #1</p>
<p style="color:blue"><span style="color:yellow"><span style="color:red">This is</span> line #2</span></p>
<p style="color:blue"><span style="color:yellow"><span style="color:green">This is line #3</span></span>
<p style="color:blue"><span style="color:yellow">This is</span><span style="color:red">line #4</span></span></p>
JavaScript
[].forEach.call(document.getElementsByTagName("p"), format);
function wrap(text, color) {
var span = document.createElement("span");
span.style.color = color;
span.appendChild(text);
return span;
}
function format(p) {
for (var cur = p.firstChild; cur != null; cur = next) {
var next = cur.nextSibling;
if (cur.nodeType == 3) {
// top-level text nodes are wrapped in spans
next = p.insertBefore(wrap(cur, p.style.color), next);
} else {
if (cur.childNodes.length == 1 && cur.firstChild.nodeType == 3)
continue;
// top-level spans are unwrapped…
while (cur.firstChild) {
if (cur.firstChild.nodeType == 1)
// with nested spans becoming unnested
p.insertBefore(cur.firstChild, next);
else
// and child text nodes becoming wrapped again
p.insertBefore(wrap(cur.firstChild, cur.style.color), next);
}
// now empty span is removed
next = cur.nextSibling;
p.removeChild(cur);
}
}
p.style.color = p.firstChild.style.color;
}