I'm trying to create a simple extension that replaces certain words with others. I'm using regexp to find global matches, then using conditionals to replace the words. However, it only replaces the first occurrence of each word despite my specifying "gi". Could anyone explain why it exhibits this behavior?
I got some of the code from here: Javascript Regex to replace text NOT in html attributes
The code is below:
// Reusable generic function
function surroundInElement(el, regex, surrounderCreateFunc) {
// script and style elements are left alone
if (!/^(script|style)$/.test(el.tagName)) {
var child = el.lastChild;
while (child) {
if (child.nodeType == 1) {
surroundInElement(child, regex, surrounderCreateFunc);
} else if (child.nodeType == 3) {
surroundMatchingText(child, regex, surrounderCreateFunc);
}
child = child.previousSibling;
}
}
}
// Reusable generic function
function surroundMatchingText(textNode, regex, surrounderCreateFunc) {
var parent = textNode.parentNode;
var result, surroundingNode, matchedTextNode, matchLength, matchedText;
while ( textNode && (result = regex.exec(textNode.data)) ) {
matchedTextNode = textNode.splitText(result.index);
matchedText = result[0];
matchLength = matchedText.length;
textNode = (matchedTextNode.length > matchLength) ?
matchedTextNode.splitText(matchLength) : null;
surroundingNode = surrounderCreateFunc(matchedTextNode.cloneNode(true));
parent.insertBefore(surroundingNode, matchedTextNode);
parent.removeChild(matchedTextNode);
}
}
// This function does the surrounding for every matched piece of text
// and can be customized to do what you like
function createSpan(matchedTextNode) {
var val = matchedTextNode.nodeValue;
var valuelower = val.toLowerCase();
if(valuelower === "nice" || valuelower === "good" || valuelower === "great" || valuelower === "awesome" || valuelower === "amazing"){
var t = document.createTextNode("gj");
var el = document.createElement("span");
el.style.color = "red";
el.appendChild(t);
return el;
}
if(valuelower === "bad" || valuelower === "terrible" || valuelower === "horrendous" || valuelower === "awful" || valuelower === "abominable"){
var t = document.createTextNode("bj");
var el = document.createElement("span");
el.style.color = "red";
el.appendChild(t);
return el;
}
if(valuelower === "does"){
var t = document.createTextNode("dose");
var el = document.createElement("span");
el.style.color = "red";
el.appendChild(t);
return el;
}
}
// The main function
function wrapWords(container, words) {
// Replace the words one at a time.
for (var i = 0, len = words.length; i < len; ++i) {
surroundInElement(container, new RegExp(words[i], "gi"), createSpan);
}
}
wrapWords(document.body, ["nice", "good", "great", "awesome", "amazing", "bad", "terrible", "horrendous", "awful", "abominable", "does"]);