-
-
Save kgashok/0df06a59d30e1ff19707782e02e83ee7 to your computer and use it in GitHub Desktop.
Replaces words in a web page
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ### 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