Files
Marek Lenczewski a0c8ecaf27 update
2026-04-08 08:51:59 +02:00

78 lines
2.4 KiB
JavaScript

console.log("[YT-Erfasser] Content Script geladen");
const sentUrls = new Set();
function extractVideoFromCard(element) {
const link = element.querySelector('a[href*="/watch?v="]');
if (!link) return null;
const match = link.href.match(/[?&]v=([^&]+)/);
if (!match) return null;
const title = element.querySelector("h3 a")?.textContent?.trim();
if (!title) return null;
const thumbnail = element.querySelector('a[href*="/watch?v="] img')?.src;
const youtuber = element.querySelector('a[href^="/@"]')?.textContent?.trim() || "Unbekannt";
return {
title,
youtuber,
thumbnailUrl: thumbnail || `https://img.youtube.com/vi/${match[1]}/hqdefault.jpg`,
youtubeUrl: `https://www.youtube.com/watch?v=${match[1]}`,
};
}
async function sendVideo(video) {
const stored = await browser.storage.local.get("profileId");
const profileId = stored.profileId || 1;
console.log(`[YT-Erfasser] Video senden (Profil: ${profileId})`, video.title);
browser.runtime.sendMessage({ profileId, video });
}
// --- IntersectionObserver: nur sichtbare Cards erfassen ---
const visibilityObserver = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (!entry.isIntersecting) continue;
const video = extractVideoFromCard(entry.target);
if (!video) continue;
if (sentUrls.has(video.youtubeUrl)) continue;
sentUrls.add(video.youtubeUrl);
sendVideo(video);
}
}, { threshold: 0.5 });
function observeCard(el) {
visibilityObserver.observe(el);
}
// --- MutationObserver: neue Cards registrieren ---
const mutationObserver = new MutationObserver((mutations) => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType !== Node.ELEMENT_NODE) continue;
if (node.matches?.("ytd-rich-item-renderer, ytd-video-renderer")) {
observeCard(node);
}
node.querySelectorAll?.("ytd-rich-item-renderer, ytd-video-renderer").forEach(observeCard);
}
}
});
mutationObserver.observe(document.body, { childList: true, subtree: true });
// --- SPA Navigation ---
document.addEventListener("yt-navigate-finish", () => {
sentUrls.clear();
setTimeout(() => {
document.querySelectorAll("ytd-rich-item-renderer, ytd-video-renderer").forEach(observeCard);
}, 500);
});
// --- Init ---
document.querySelectorAll("ytd-rich-item-renderer, ytd-video-renderer").forEach(observeCard);