64 lines
1.4 KiB
JavaScript
64 lines
1.4 KiB
JavaScript
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
|
|
}); |