// ==UserScript== // @name Word count notifier // @namespace https://greasyfork.org/en/users/85671-jcunews // @version 0.0.1 // @license AGPL v3 // @author jcunews // @description Context: https://www.reddit.com/r/userscripts/comments/11crt1o/request_need_a_script_that_counts_occurrence_of_a/ // @match http://*/* // @match https://*/* // @grant none // ==/UserScript== (() => { const words = /something|other|the first/gi; const checkInterval = 300; //in milliseconds. how frequent to check for count difference when count is already displayed. it will blink the display if there's a difference const displayTime = 5000; //in milliseconds. how long to keep displaying count when there's no more count difference function checkEle(ele, count, node) { if (/SCRIPT|STYLE/.test(ele.tagName)) return 0; count = 0; node = ele.firstChild; while (node) { switch (node.nodeType) { case Element.ELEMENT_NODE: count += checkEle(node); break; case Element.TEXT_NODE: if (node.data !== node.oldData) count += Array.from(node.data.matchAll(words)).length; node.oldData = node.data; } node = node.nextSibling } return count } let t = 0, prevCount = 0, totalCount = 0, currentCount = 0; (new MutationObserver(recs => { recs.forEach(rec => { console.log(rec); if (!rec.addedNodes.length) { currentCount += Array.from(rec.target.data.matchAll(words)).length } else { rec.addedNodes.forEach(node => { switch (node.nodeType) { case Element.ELEMENT_NODE: currentCount += checkEle(node); break; case Element.TEXT_NODE: if (node.data !== node.oldData) currentCount += Array.from(node.data.matchAll(words)).length; node.oldData = node.data; } }) } }) })).observe(document.body, {childList: true, subtree: true, characterDataOldValue: true}); checkEle(document.body); setInterval(() => { if (currentCount !== prevCount) { t = Date.now(); let ele = document.querySelector("#eleWordCountTxt"); if (!ele) { document.documentElement.insertAdjacentHTML("beforeend", `
`); ele = document.querySelector("#eleWordCountTxt") ele.textContent = `+${currentCount}. Total = ${totalCount += currentCount}`; prevCount = 0; currentCount = 0 } else { ele.style.display = "none"; setTimeout(() => { ele.style.display = ""; ele.textContent = `+${currentCount}. Total = ${totalCount += currentCount}`; prevCount = 0; currentCount = 0 }, 100) } } else if ((Date.now() - t) >= displayTime) { let ele = document.querySelector("#eleWordCount"); if (ele) ele.remove() } }, checkInterval) })()