const DEFAULT_REPLACEMENTS = { "consultant": "conslutant", "AI process engineer": "algorithm inventor" }; function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&"); } function replaceInTextNode(node, replacements) { let text = node.nodeValue; let updated = text; for (const [search, replace] of Object.entries(replacements)) { const regex = new RegExp(escapeRegExp(search), "gi"); updated = updated.replace(regex, replace); } if (updated !== text) { node.nodeValue = updated; } } function walk(node, replacements) { if ( node.nodeType === Node.ELEMENT_NODE && ["SCRIPT", "STYLE", "TEXTAREA", "INPUT"].includes(node.tagName) ) { return; } if (node.nodeType === Node.TEXT_NODE) { replaceInTextNode(node, replacements); return; } for (const child of node.childNodes) { walk(child, replacements); } } async function getReplacements() { return new Promise((resolve) => { chrome.storage.sync.get(["replacements"], (result) => { resolve(result.replacements || DEFAULT_REPLACEMENTS); }); }); } async function runReplacement() { const replacements = await getReplacements(); walk(document.body, replacements); } runReplacement(); const observer = new MutationObserver(() => { runReplacement(); }); observer.observe(document.body, { childList: true, subtree: true });