(async function init() {
const domain = window.location.hostname;
const { disabledSites = [] } = await chrome.storage.local.get('disabledSites');
if (disabledSites.includes(domain)) return;
let conversionCount = 0;
const pronounMap = { 'm': 'aym', 'll': 'ayll', 've': 'ayve', 'd': 'ayd' };
const acronymMap = { 'TIL': 'TAL', 'AITAH': 'AATAH' };
const pronounRegex = /\bI(?:['’](m|ll|ve|d))?\b/g;
const acronymRegex = /\b(TIL|AITAH)\b/g;
function updateBadge() {
chrome.runtime.sendMessage({ action: 'updateBadge', count: conversionCount });
}
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
function isSentenceStart(text, offset) {
if (offset === 0) return true;
const before = text.slice(0, offset).trim();
if (before.length === 0) return true;
const lastChar = before.slice(-1);
return /[.!?\"\'“”‘’:]/.test(lastChar);
}
function transformText(text) {
let changed = false;
let result = text;
result = result.replace(acronymRegex, (match) => {
conversionCount++;
changed = true;
return acronymMap[match];
});
result = result.replace(pronounRegex, (match, suffix, offset, fullText) => {
if (offset > 0 && fullText[offset - 1] === '.') {
return match;
}
const nextCharIndex = offset + match.length;
if (nextCharIndex < fullText.length && (fullText[nextCharIndex] === '.' || fullText[nextCharIndex] === '-' || fullText[nextCharIndex] === '/')) {
return match;
}
conversionCount++;
changed = true;
const rep = suffix ? pronounMap[suffix] : 'ayh';
return isSentenceStart(fullText, offset) ? capitalize(rep) : rep;
});
if (changed) updateBadge();
return result;
}
function walk(node) {
const skipTags = ['SCRIPT', 'STYLE', 'INPUT', 'TEXTAREA', 'IFRAME', 'CODE', 'PRE'];
const walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, {
acceptNode: (n) => skipTags.includes(n.parentElement?.tagName) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT
});
let textNode;
while (textNode = walker.nextNode()) {
const newVal = transformText(textNode.nodeValue);
if (newVal !== textNode.nodeValue) textNode.nodeValue = newVal;
}
}
walk(document.body);
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === 1) walk(node);
else if (node.nodeType === 3) {
const newVal = transformText(node.nodeValue);
if (newVal !== node.nodeValue) node.nodeValue = newVal;
}
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();