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 });  },});
评论