From f7f93bcffea52a82cda15d7ddd808f961ce84121 Mon Sep 17 00:00:00 2001 From: Ceda EI Date: Thu, 10 Sep 2020 21:00:06 +0530 Subject: [PATCH] Add content script gmcr.js to read captions and send notifs --- gmcr.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/gmcr.js b/gmcr.js index e69de29..7f0bfe4 100644 --- a/gmcr.js +++ b/gmcr.js @@ -0,0 +1,81 @@ +let lastNotification = ""; +function surroundText(haystack, wordList, padding) { + let surroundingText = ""; + wordList.forEach(word => { + if (word.idx < 0) + return; + const start = Math.max(0, word.idx - padding); + const end = word.idx + word.length + padding; + if (start > 0) + surroundingText += "..."; + surroundingText += haystack.slice(start, end).trim(); + if (end < haystack.length) + surroundingText += "..."; + + surroundingText += "
"; + console.log(start, end, surroundingText); + }); + return surroundingText.trim(); +} + +function simpleMatch(captions, words) { + const wordList = words.map(word => ({ + idx: captions.toLowerCase().indexOf(word.toLowerCase()), + length: word.length + })).filter(i => i.idx >= 0); + const surroundingText = surroundText(captions, wordList, 10); + return [ wordList.length, surroundingText ]; +} + +function advancedMatch(captions, regex, flags) { + const reg = RegExp(regex, flags); + let wordList = []; + if (reg.global) { + wordList = [...captions.matchAll(reg)].map(i => ({ idx: i.index, length: i[0].length })); + } else { + const match = captions.match(reg); + if (match.length) + wordList = [ {idx: match.index, length: match[0].length} ]; + } + const surroundingText = surroundText(captions, wordList, 10); + return [ Boolean(wordList.length), surroundingText ]; +} + +function captionUpdate() { + const captions = [...document.querySelector(".a4cQT").children].map(i => i.innerText).reduce((i, j) => i + "\n" + j); + browser.storage.local.get(["advanced", "flags", "regex", "words"]) + .then(storage => { + let surroundingText = ""; + let matched = false; + if (storage.advanced) { + [ matched, surroundingText ] = advancedMatch(captions, storage.regex, storage.flags); + } else { + [ matched, surroundingText ] = simpleMatch(captions, storage.words); + } + console.log(matched, surroundingText); + /* The lastNotification prevents repetitive notifications because + * of constant updates. + */ + if (matched && surroundingText !== lastNotification) { + new Notification("Match found", {body: surroundingText}); + lastNotification = surroundingText; + } + }) +} + +/* The script gets injected when the "Ask to join" page. However, captions + * element isn't shown until you actually join the meeting, so a 0.5s loop lets + * us add a listener whenever it shows up. + */ +function setupListener() { + const captionElement = document.querySelector(".a4cQT"); + if (captionElement === null) { + setTimeout(setupListener, 500); + return; + } + const config = { subtree: true, childList: true }; + const observer = new MutationObserver(captionUpdate); + observer.observe(captionElement, config); +} + +setupListener();