diff --git a/content.js b/content.js index 5682d1a..c2f2409 100644 --- a/content.js +++ b/content.js @@ -1,25 +1,56 @@ console.log("[MemberFilter] content script loaded"); const seen = new WeakSet(); +let whitelist = []; -function findMemberVideos(root = document) { - const badges = root.querySelectorAll( - 'badge-shape, ytd-badge-supported-renderer' - ); +/* ---------------- CSS injection ---------------- */ + +function injectStyleOnce() { + if (document.getElementById("member-filter-style")) return; + + const style = document.createElement("style"); + style.id = "member-filter-style"; + style.textContent = ` + [data-member-filter-hidden="true"] { + display: none !important; + } + `; + document.head.appendChild(style); +} + +injectStyleOnce(); + +/* ---------------- load whitelist ---------------- */ + +function loadWhitelist() { + chrome.storage.local.get({ whitelist: [] }, data => { + whitelist = data.whitelist.map(n => n.toLowerCase()); + console.log("[MemberFilter] whitelist loaded:", whitelist); + }); +} + +loadWhitelist(); + +// Reload whitelist if popup changes it +chrome.storage.onChanged.addListener(loadWhitelist); + +/* ---------------- detection logic ---------------- */ + +function process(root = document) { + const badges = root.querySelectorAll("badge-shape"); badges.forEach(badge => { if (!badge.textContent?.includes("Nur für Kanalmitglieder")) return; - const video = - badge.closest("ytd-rich-item-renderer, ytd-video-renderer, ytd-grid-video-renderer"); + const video = badge.closest( + "ytd-rich-item-renderer, ytd-video-renderer, ytd-grid-video-renderer" + ); if (!video) return; if (seen.has(video)) return; seen.add(video); - // ---- extract data ---- - const titleEl = video.querySelector("#video-title"); const channelEl = video.querySelector("ytd-channel-name a") || @@ -28,25 +59,33 @@ function findMemberVideos(root = document) { const title = titleEl?.textContent?.trim() ?? "(no title)"; const url = titleEl?.href ?? "(no url)"; const channel = channelEl?.textContent?.trim() ?? "(no channel)"; + const channelKey = channel.toLowerCase(); - console.group("[MemberFilter] Member-only video found"); + const whitelisted = whitelist.includes(channelKey); + + console.group("[MemberFilter]"); console.log("Title :", title); console.log("Channel:", channel); console.log("URL :", url); - console.log("Node :", video); + console.log("Whitelisted:", whitelisted); console.groupEnd(); + + if (!whitelisted) { + video.setAttribute("data-member-filter-hidden", "true"); + } }); } -// Initial scan -findMemberVideos(); +/* ---------------- initial + observer ---------------- */ + +process(); -// Observe dynamic changes const observer = new MutationObserver(mutations => { for (const m of mutations) { for (const node of m.addedNodes) { - if (!(node instanceof HTMLElement)) continue; - findMemberVideos(node); + if (node instanceof HTMLElement) { + process(node); + } } } }); diff --git a/manifest.json b/manifest.json index af59769..bad29fd 100644 --- a/manifest.json +++ b/manifest.json @@ -18,6 +18,23 @@ ], "action": { - "default_popup": "popup.html" + "default_popup": "popup.html", + "default_icon": { + "16": "icons/anti-bs-icon-16.png", + "32": "icons/anti-bs-icon-32.png", + "48": "icons/anti-bs-icon-48.png", + "64": "icons/anti-bs-icon-64.png", + "128": "icons/anti-bs-icon-128.png" + } + }, + "icons": { + "16": "icons/anti-bs-icon-16.png", + "32": "icons/anti-bs-icon-32.png", + "48": "icons/anti-bs-icon-48.png", + "64": "icons/anti-bs-icon-64.png", + "128": "icons/anti-bs-icon-128.png", + "256": "icons/anti-bs-icon-256.png", + "512": "icons/anti-bs-icon-512.png", + "1024": "icons/anti-bs-icon-1024.png" } }