Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
(function() {
'use strict';
/**
* Modifications to perform (processed in order)
*
* @type {Function[]}
*/
const modifications = [
(text) => text.replace(/!+/g, '!'),
];
/**
* Root element to watch for changes in descendants
*
* @type {Element}
*/
const container = document.body;
/**
* Execute the replacement operations against a CharacterData node
*
* @param {CharacterData} node
*/
function process_text_node(node)
{
let fixed = node.nodeValue;
modifications.forEach(function(callback) {
fixed = callback(fixed);
});
if (node.nodeValue !== fixed) {
node.nodeValue = fixed;
}
}
/**
* Recursively walk the children of an Element and process any CharacterData nodes found in its descendants
*
* @param {Element} element
*/
function walk_element(element)
{
let node = element.firstChild;
while (node) {
if (node instanceof CharacterData) {
process_text_node(node);
} else if (node instanceof Element) {
walk_element(node);
}
node = node.nextSibling;
}
}
/**
* Process an array of MutationRecord objects for added or updated character data
*
* @param {MutationRecord[]} mutations
*/
function process_mutations(mutations)
{
mutations.forEach(function(mutation) {
switch (mutation.type) {
case 'childList':
Array.prototype.forEach.call(mutation.addedNodes, function(node) {
if (node instanceof CharacterData) {
process_text_node(node);
} else if (node instanceof Element) {
walk_element(node);
}
});
break;
case 'characterData':
process_text_node(mutation.target);
break;
}
});
}
// Fix existing page text
walk_element(container);
// Register the mutation observer to process future changes on the page
(new MutationObserver(process_mutations)).observe(container, {
childList: true,
subtree: true,
characterData: true,
});
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment