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 || null; const payload = { ...video, profileId }; console.log(`[YT-Erfasser] Video senden (Profil: ${profileId})`, payload.title); browser.runtime.sendMessage(payload); } // --- 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);