google-meet-captions-regex/gmcr.js

83 lines
2.5 KiB
JavaScript

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 += "<br>";
});
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);
}
/* The lastNotification prevents repetitive notifications because
* of constant updates.
*/
if (matched && surroundingText !== lastNotification) {
browser.runtime.sendMessage({
type: "match",
match: 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();