Try the following:
Template
<script>
{
const colors = ["red", "blue", "green"];
// Words with all letters capitalized,
// except for words with only one letter, such as I.
const allCapsWordRegex = /\b[A-Z]{2,}\b/g;
let colorIndex = 0;
function containsAllCapsWords(str) {
return allCapsWordRegex.test(str);
}
function replacer(match) {
const color = colors[colorIndex % colors.length];
colorIndex++;
return `<span style="color: ${color};">${match}</span>`;
}
function colorizeAllCapsWords(text) {
return text.replace(allCapsWordRegex, replacer);
}
function maybeReplaceTextNode(node) {
if (containsAllCapsWords(node.textContent)) {
const newHtml = colorizeAllCapsWords(node.textContent);
const newNode = document.createElement("span");
newNode.innerHTML = newHtml;
node.parentNode.replaceChild(newNode, node);
}
}
const treeWalker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
(node) =>
["SCRIPT", "STYLE"].includes(node.parentNode.nodeName)
? NodeFilter.FILTER_REJECT
: NodeFilter.FILTER_ACCEPT,
);
while (treeWalker.nextNode()) {
maybeReplaceTextNode(treeWalker.currentNode);
}
}
</script>
