import { defineContentScript } from "wxt/sandbox";import { defaultBlur, storageKeys } from "@/const";import { createButton } from "@/utils";
const BLUR_EMOJI = "👀";const UN_BLUR_EMOJI = "🙈";
// 元素状态const statusMap = new Map<string, boolean>();
// 资源选择器(需要被模糊屏蔽的媒体资源)const selectors = [ '[data-testid="tweetPhoto"]', '[data-testid="videoComponent"]', '[data-testid="videoPlayer"]', '[data-testid="card.layoutLarge.media"]', '[data-testid="collection-hero-image"]', '[data-testid="article-cover-image"]',];
async function handleElements() { const enable = (await storage.getItem<boolean>(storageKeys.enable)) ?? true; const blur = (await storage.getItem<number>(storageKeys.blur)) ?? defaultBlur;
selectors.forEach((selector) => { let elements: HTMLElement[] = Array.from( document.querySelectorAll(selector) );
elements.forEach((element) => { let current = element; let hasBlur = false;
while (current.parentElement !== null) { current = current.parentElement; if (current.matches(selectors.join(","))) { hasBlur = true; break; } }
// 检测是否已存在被处理的父级 if (hasBlur) return;
let comfortId = element.getAttribute("data-comfort-id");
if (!comfortId) { // 标记待处理元素,生成唯一ID comfortId = crypto.randomUUID(); element.setAttribute("data-comfort-id", comfortId);
// 添加按钮手动切换元素状态 const button = createButton(comfortId, handleElements); button.onclick = (e) => { e.preventDefault(); e.stopPropagation();
const newStatus = !statusMap.get(comfortId!);
statusMap.set(comfortId!, newStatus);
if (newStatus) { element.style.filter = `blur(${blur}px)`; button.innerText = BLUR_EMOJI; } else { element.style.filter = "none"; button.innerText = UN_BLUR_EMOJI; } };
element.parentElement?.insertBefore(button, element); }
// 保存元素的模糊状态 if (!statusMap.has(comfortId)) { statusMap.set(comfortId, enable); }
const targetElement = element as HTMLElement; const toggleButton = document.getElementById(comfortId) as HTMLElement;
if (!enable) { targetElement.style.filter = "none"; toggleButton.style.display = "none"; statusMap.clear(); return; } else { targetElement.style.transition = ".3s"; toggleButton.style.display = "block"; }
const blurStatus = statusMap.get(comfortId); if (blurStatus && targetElement.style.filter !== `blur(${blur}px)`) { targetElement.style.filter = `blur(${blur}px)`; toggleButton.innerText = BLUR_EMOJI; }
if (!blurStatus && targetElement.style.filter !== "none") { targetElement.style.filter = "none"; toggleButton.innerText = UN_BLUR_EMOJI; } }); });}
export default defineContentScript({ // 匹配脚本生效的域名 matches: ["*://x.com/*"], // 脚本运行时机 runAt: "document_idle", main(ctx) { console.log("Hello from X-Comfort-Browser.");
// 监听 自定义参数值 变化 [storageKeys.blur, storageKeys.enable].forEach((key) => { storage.watch<number | boolean>(key, (v) => { handleElements(); }); });
// 监听 页面元素 变化 const observer = new MutationObserver(() => handleElements()); observer.observe(document.body, { childList: true, subtree: true }); },});
评论