Advertisement
jcunews

word-count-notifier.user.js

Feb 27th, 2023 (edited)
887
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        Word count notifier
  3. // @namespace   https://greasyfork.org/en/users/85671-jcunews
  4. // @version     0.0.1
  5. // @license     AGPL v3
  6. // @author      jcunews
  7. // @description Context: https://www.reddit.com/r/userscripts/comments/11crt1o/request_need_a_script_that_counts_occurrence_of_a/
  8. // @match       http://*/*
  9. // @match       https://*/*
  10. // @grant       none
  11. // ==/UserScript==
  12.  
  13. (() => {
  14.   const words = /something|other|the first/gi;
  15.   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
  16.   const displayTime = 5000; //in milliseconds. how long to keep displaying count when there's no more count difference
  17.  
  18.   function checkEle(ele, count, node) {
  19.     if (/SCRIPT|STYLE/.test(ele.tagName)) return 0;
  20.     count = 0;
  21.     node = ele.firstChild;
  22.     while (node) {
  23.       switch (node.nodeType) {
  24.         case Element.ELEMENT_NODE:
  25.           count += checkEle(node);
  26.           break;
  27.         case Element.TEXT_NODE:
  28.           if (node.data !== node.oldData) count += Array.from(node.data.matchAll(words)).length;
  29.           node.oldData = node.data;
  30.       }
  31.       node = node.nextSibling
  32.     }
  33.     return count
  34.   }
  35.   let t = 0, prevCount = 0, totalCount = 0, currentCount = 0;
  36.   (new MutationObserver(recs => {
  37.     recs.forEach(rec => {
  38.       console.log(rec);
  39.       if (!rec.addedNodes.length) {
  40.         currentCount += Array.from(rec.target.data.matchAll(words)).length
  41.       } else {
  42.         rec.addedNodes.forEach(node => {
  43.           switch (node.nodeType) {
  44.             case Element.ELEMENT_NODE:
  45.               currentCount += checkEle(node);
  46.               break;
  47.             case Element.TEXT_NODE:
  48.               if (node.data !== node.oldData) currentCount += Array.from(node.data.matchAll(words)).length;
  49.               node.oldData = node.data;
  50.           }
  51.         })
  52.       }
  53.     })
  54.   })).observe(document.body, {childList: true, subtree: true, characterDataOldValue: true});
  55.   checkEle(document.body);
  56.   setInterval(() => {
  57.     if (currentCount !== prevCount) {
  58.       t = Date.now();
  59.       let ele = document.querySelector("#eleWordCountTxt");
  60.       if (!ele) {
  61.         document.documentElement.insertAdjacentHTML("beforeend", `
  62. <div id="eleWordCount">
  63.   <style>
  64.     #eleWordCount, #eleWordCount * { all: revert }
  65.     #eleWordCount {
  66.       position: fixed; right: .5em; bottom: .5em; box-sizing: border-box; border-radius: .3em;
  67.       padding: .2em .5em; background: #000b; color: #fff; font: 16pt/normal sans-serif;
  68.     }
  69.   </style>
  70.   <div id="eleWordCountTxt"></div>
  71. </div>`);
  72.         ele = document.querySelector("#eleWordCountTxt")
  73.         ele.textContent = `+${currentCount}. Total = ${totalCount += currentCount}`;
  74.         prevCount = 0;
  75.         currentCount = 0
  76.       } else {
  77.         ele.style.display = "none";
  78.         setTimeout(() => {
  79.           ele.style.display = "";
  80.           ele.textContent = `+${currentCount}. Total = ${totalCount += currentCount}`;
  81.           prevCount = 0;
  82.           currentCount = 0
  83.         }, 100)
  84.       }
  85.     } else if ((Date.now() - t) >= displayTime) {
  86.       let ele = document.querySelector("#eleWordCount");
  87.       if (ele) ele.remove()
  88.     }
  89.   }, checkInterval)
  90. })()
  91.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement