JSFiddle - React, Tailwind, and code Playground

by gilly3

HTML

<b>Before:</b>
<div id="htmlBefore" class="html"></div>
<div id="before"></div>
<br/>
<b>After:</b>
<div id="htmlAfter" class="html"></div>

CSS

body { font-family: sans-serif; }
.html { font-family: monospace; }
span { border: 1px solid red; }

JavaScript

window.onload = function()
{
    var html = "The rain in <b class=\"spain\">Spain</b> stays mainly in the spain <i data-test=\"Spain\">plain</i>.";
    var container = document.createElement("div");
    document.body.appendChild(container);
    container.innerHTML = html;
    wrapWord(container, "SPAIN");

    var before = document.createTextNode(html);
    var after = document.createTextNode(container.innerHTML);
    document.getElementById("before").innerHTML = html;
    document.getElementById("htmlBefore").appendChild(before);
    document.getElementById("htmlAfter").appendChild(after);
};


function wrapWord(el, word)
{
    var expr = new RegExp(word, "i");
    var nodes = [].slice.call(el.childNodes, 0);
    for (var i = 0; i < nodes.length; i++)
    {
        var node = nodes[i];
        if (node.nodeType == 3) // textNode
        {
            var matches = node.nodeValue.match(expr);
            if (matches)
            {
                var parts = node.nodeValue.split(expr);
                for (var n = 0; n < parts.length; n++)
                {
                    if (n)
                    {
                        var span = el.insertBefore(document.createElement("span"), node);
                        span.appendChild(document.createTextNode(matches[n - 1]));
                    }
                    if (parts[n])
                    {
                        el.insertBefore(document.createTextNode(parts[n]), node);
                    }
                }
                el.removeChild(node);
            }
        }
        else
        {
            wrapWord(node, word);
        }
    }
}