Refactor content script to manage video visibility based on a dynamic whitelist and enhance popup icon configuration in manifest
This commit is contained in:
parent
4bbbcd8040
commit
351116c85a
69
content.js
69
content.js
@ -1,25 +1,56 @@
|
|||||||
console.log("[MemberFilter] content script loaded");
|
console.log("[MemberFilter] content script loaded");
|
||||||
|
|
||||||
const seen = new WeakSet();
|
const seen = new WeakSet();
|
||||||
|
let whitelist = [];
|
||||||
|
|
||||||
function findMemberVideos(root = document) {
|
/* ---------------- CSS injection ---------------- */
|
||||||
const badges = root.querySelectorAll(
|
|
||||||
'badge-shape, ytd-badge-supported-renderer'
|
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 => {
|
badges.forEach(badge => {
|
||||||
if (!badge.textContent?.includes("Nur für Kanalmitglieder")) return;
|
if (!badge.textContent?.includes("Nur für Kanalmitglieder")) return;
|
||||||
|
|
||||||
const video =
|
const video = badge.closest(
|
||||||
badge.closest("ytd-rich-item-renderer, ytd-video-renderer, ytd-grid-video-renderer");
|
"ytd-rich-item-renderer, ytd-video-renderer, ytd-grid-video-renderer"
|
||||||
|
);
|
||||||
|
|
||||||
if (!video) return;
|
if (!video) return;
|
||||||
if (seen.has(video)) return;
|
if (seen.has(video)) return;
|
||||||
|
|
||||||
seen.add(video);
|
seen.add(video);
|
||||||
|
|
||||||
// ---- extract data ----
|
|
||||||
|
|
||||||
const titleEl = video.querySelector("#video-title");
|
const titleEl = video.querySelector("#video-title");
|
||||||
const channelEl =
|
const channelEl =
|
||||||
video.querySelector("ytd-channel-name a") ||
|
video.querySelector("ytd-channel-name a") ||
|
||||||
@ -28,25 +59,33 @@ function findMemberVideos(root = document) {
|
|||||||
const title = titleEl?.textContent?.trim() ?? "(no title)";
|
const title = titleEl?.textContent?.trim() ?? "(no title)";
|
||||||
const url = titleEl?.href ?? "(no url)";
|
const url = titleEl?.href ?? "(no url)";
|
||||||
const channel = channelEl?.textContent?.trim() ?? "(no channel)";
|
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("Title :", title);
|
||||||
console.log("Channel:", channel);
|
console.log("Channel:", channel);
|
||||||
console.log("URL :", url);
|
console.log("URL :", url);
|
||||||
console.log("Node :", video);
|
console.log("Whitelisted:", whitelisted);
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
|
|
||||||
|
if (!whitelisted) {
|
||||||
|
video.setAttribute("data-member-filter-hidden", "true");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial scan
|
/* ---------------- initial + observer ---------------- */
|
||||||
findMemberVideos();
|
|
||||||
|
process();
|
||||||
|
|
||||||
// Observe dynamic changes
|
|
||||||
const observer = new MutationObserver(mutations => {
|
const observer = new MutationObserver(mutations => {
|
||||||
for (const m of mutations) {
|
for (const m of mutations) {
|
||||||
for (const node of m.addedNodes) {
|
for (const node of m.addedNodes) {
|
||||||
if (!(node instanceof HTMLElement)) continue;
|
if (node instanceof HTMLElement) {
|
||||||
findMemberVideos(node);
|
process(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -18,6 +18,23 @@
|
|||||||
],
|
],
|
||||||
|
|
||||||
"action": {
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user