116 lines
5.2 KiB
JavaScript
116 lines
5.2 KiB
JavaScript
const findCaptionsContainer = () => {
|
|
let e = document.querySelector('div[jsname="dsyhDe"]');
|
|
return e || (e = document.querySelector('div[jscontroller="D1tHje"] > div > div:first-child')), e && (captionContainerChildObserver.observe(e, {
|
|
childList: !0,
|
|
subtree: !0,
|
|
characterData: !0
|
|
}), captionContainerAttributeObserver.observe(e, {
|
|
attributes: !0,
|
|
subtree: !1,
|
|
attributeOldValue: !0
|
|
}), Array.from(e.children).forEach(tryTo((e => {
|
|
updateCurrentTranscriptSession(e)
|
|
}), "handling child node")), debug("Final CaptionsContainer", e)), e
|
|
},
|
|
findCaptionsContainerObsolete = () => {
|
|
captionContainerChildObserver.disconnect(), captionContainerAttributeObserver.disconnect();
|
|
const e = {},
|
|
t = Array.from(document.querySelectorAll("img")).filter((e => e.src.match(/\.googleusercontent\.com\//)));
|
|
for (let n of t) n.className in e || (e[n.className] = []), e[n.className].push(n);
|
|
const n = [];
|
|
for (let t of Object.values(e)) {
|
|
let e = 0;
|
|
for (let n of t) {
|
|
const t = document.evaluate("..//span", n.parentElement, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
|
|
let r;
|
|
for (; r = t.iterateNext();)
|
|
if (0 === r.children.length && r.textContent.length > 3) {
|
|
e += 1;
|
|
break
|
|
}
|
|
}
|
|
if (e !== t.length) continue;
|
|
let r = null;
|
|
if (t.length >= 2) {
|
|
const e = [...t];
|
|
let n = null,
|
|
o = !1;
|
|
do {
|
|
for (let t in e) {
|
|
if (!e[t].parent) {
|
|
o = !0;
|
|
break
|
|
}
|
|
e[t] = e[t].parent, 0 === t ? n = e[t] : n && n !== e[t] && (n = null), debug("current", n)
|
|
}
|
|
} while (null === n && !1 === o);
|
|
r = n
|
|
} else {
|
|
let e = t[0];
|
|
for (; null === r && e;) e.getAttribute("jscontroller") ? r = e : e = e.parentNode
|
|
}
|
|
if (r) {
|
|
const e = r?.firstChild?.firstChild?.tagName;
|
|
debug("first grand child tag name", e);
|
|
const t = "IMG" === e ? r : r.firstChild.firstChild;
|
|
debug("caption container candidate", t), null !== t && n.push(t)
|
|
}
|
|
}
|
|
if (1 === n.length) return captionContainerChildObserver.observe(n[0], {
|
|
childList: !0,
|
|
subtree: !0,
|
|
characterData: !0
|
|
}), captionContainerAttributeObserver.observe(n[0], {
|
|
attributes: !0,
|
|
subtree: !1,
|
|
attributeOldValue: !0
|
|
}), Array.from(n[0].children).forEach(tryTo((e => {
|
|
updateCurrentTranscriptSession(e)
|
|
}), "handling child node")), debug("Final CaptionsContainer", n[0]), n[0]
|
|
},
|
|
captionContainerChildObserver = new MutationObserver(tryTo((e => {
|
|
for (let t of e)
|
|
if (debug("mutation target", t.target), t.target === captionsContainer) {
|
|
debug("update with added nodes");
|
|
for (let e of t.addedNodes) updateCurrentTranscriptSession(e)
|
|
} else {
|
|
const e = Array.from(t.addedNodes).filter((e => "SPAN" === e.nodeName || "#text" === e.nodeName)),
|
|
n = Array.from(t.removedNodes).filter((e => "SPAN" === e.nodeName || "#text" === e.nodeName));
|
|
if (debug("addedSpansOrTexts", e), "characterData" === t.type || e.length > 0 || n.length > 0) {
|
|
let e = t.target;
|
|
for (; e && e.parentNode !== captionsContainer;) e = e.parentNode;
|
|
if (!e) {
|
|
debug("could not find root for", t.target);
|
|
continue
|
|
}
|
|
if (debug("update with parent node"), e.querySelector("button")) {
|
|
let t = Array.from(e.children),
|
|
n = t.slice(0, t.length - 1).slice(-4);
|
|
for (let e of n) updateCurrentTranscriptSession(e)
|
|
} else updateCurrentTranscriptSession(e)
|
|
}
|
|
}
|
|
}), "executing observer")),
|
|
captionContainerAttributeObserver = new MutationObserver(tryTo((e => {
|
|
for (let t of e)
|
|
if ("style" === t.attributeName) {
|
|
const e = t.target.getAttribute("style");
|
|
"display: none;" === t.oldValue && "" === e && (currentSessionIndex = null)
|
|
}
|
|
}), "executing observer"));
|
|
let isCaptionTurnedOn = !1;
|
|
const closedCaptionsAttachLoop = () => {
|
|
if (captionsContainer = findCaptionsContainer(), captionsContainer) debug("attached to closed captions"), isCaptionTurnedOn = !0, clearInterval(closedCaptionsAttachInterval);
|
|
else if (!hasCaptionButtons) {
|
|
if (isCaptionTurnedOn) return;
|
|
if (getElementWithXPathFallback(document, XPATH_CAPTION_OPEN_TOAST, XPATH_CAPTION_OPEN_TOAST_V20210602)) return popup.classList.remove("show"), isCaptionTurnedOn = !0, notificationsOn(), void clearInterval(closedCaptionsAttachInterval);
|
|
isCaptionTurnedOn || turnOnCaptionNotificationsOn()
|
|
}
|
|
},
|
|
removeCaptionPanel = () => {
|
|
// debug("start remove caption panel");
|
|
// const e = document.querySelector('div[jscontroller="D1tHje"]');
|
|
// debug("googleMeetCaptionsPanel", e), e && (e.style = "height: 0px", turnOffCaptions(), setTimeout((() => {
|
|
// turnOnCaptions()
|
|
// }), 500))
|
|
}; |