feat: add content.js
This commit is contained in:
64
content.js
Normal file
64
content.js
Normal file
@@ -0,0 +1,64 @@
|
||||
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
|
||||
});
|
||||
Reference in New Issue
Block a user