Skip to content

Instantly share code, notes, and snippets.

@kgashok
Forked from mrcoles/replace_words.js
Created December 14, 2017 18:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kgashok/0df06a59d30e1ff19707782e02e83ee7 to your computer and use it in GitHub Desktop.
Save kgashok/0df06a59d30e1ff19707782e02e83ee7 to your computer and use it in GitHub Desktop.
Replaces words in a web page
// ### Replace words in document
//
// Update all instances of `fromWord` to `toWord` within the text
// in the current document.
//
function replaceWordsInDocument(fromWord, toWord) {
if (/\s/.test(fromWord)) {
throw new Error('You must enter a single word without whitespace');
}
let nodes = iterAllTextNodes();
replaceInNodes(fromWord, toWord, nodes);
}
// ### Iterate all text nodes
//
// Returns a generator that yields all the text nodes within a
// document (excluding those within link, style, and script tags)
//
function* iterAllTextNodes() {
let ignoreNodes = {'LINK': true, 'STYLE': true, 'SCRIPT': true};
for (let elt of document.querySelectorAll('*')) {
if (!ignoreNodes[elt.nodeName]) {
for (let node of elt.childNodes) {
if (node.nodeType === 3) {
yield node;
}
}
}
}
}
// ### Replace in nodes
//
// Replaces all instances of fromText with toText within
// the textNodes. Matches whole words and expects
// `fromText` to have no whitespaces. Matches are also
// case-insensitve, and replacements attempt to replicate
// the original capitalization found in the node.
//
// - fromText (string) representing one word with no spaces
// - toText (string)
// - textNodes (nodeList of text nodes)
//
function replaceInNodes(fromText, toText, textNodes) {
let fromLower = fromText.toLowerCase();
let replacements = {
[fromLower]: toText.toLowerCase(),
[fromText.toUpperCase()]: toText.toUpperCase(),
[capitalize(fromText)]: capitalize(toText)
}
for (let node of textNodes) {
node.nodeValue = node.nodeValue.split(/(\s+)/).map((token, i) => {
if (i % 2 === 0) {
let tokenLower = token.toLowerCase();
if (tokenLower === fromLower) {
return replacements[token] || toText;
}
}
return token;
}).join('');
}
}
// ### Helpers
//
let capitalize = (text) => text.substring(0, 1).toUpperCase() + text.toLowerCase().substring(1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment