PatreonExpander

Simplify elements, expand contents and comments

当前为 2025-03-23 提交的版本,查看 最新版本

// ==UserScript==
// @name         PatreonExpander
// @namespace    https://github.com/frosn0w/iOSscripts
// @version      2.25.324
// @description  Simplify elements, expand contents and comments
// @author       frosn0w
// @match        *://*.patreon.com/*
// @run-at       document-end
// @icon         data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MzYgNDc2Ij48dGl0bGU+UGF0cmVvbiBsb2dvPC90aXRsZT48cGF0aCBkYXRhLWZpbGw9IjEiIGQ9Ik00MzYgMTQzYy0uMDg0LTYwLjc3OC00Ny41Ny0xMTAuNTkxLTEwMy4yODUtMTI4LjU2NUMyNjMuNTI4LTcuODg0IDE3Mi4yNzktNC42NDkgMTA2LjIxNCAyNi40MjQgMjYuMTQyIDY0LjA4OS45ODggMTQ2LjU5Ni4wNTEgMjI4Ljg4M2MtLjc3IDY3LjY1MyA2LjAwNCAyNDUuODQxIDEwNi44MyAyNDcuMTEgNzQuOTE3Ljk0OCA4Ni4wNzItOTUuMjc5IDEyMC43MzctMTQxLjYyMyAyNC42NjItMzIuOTcyIDU2LjQxNy00Mi4yODUgOTUuNTA3LTUxLjkyOUMzOTAuMzA5IDI2NS44NjUgNDM2LjA5NyAyMTMuMDExIDQzNiAxNDNaIj48L3BhdGg+PC9zdmc+
// @grant        none
// @license MIT
// ==/UserScript==

let executionCount = 1;
const INTERVAL_DELAY = 2888;
// 注入全局样式
const style = document.createElement("style");
style.textContent = `
  p { line-height: 1.4 !important; }
  div[data-tag="comment-row"]::before {
    width: 0px !important;
  }
  div[data-tag="comment-row"]::after {
    width: 0px !important;
    border-left: 0 !important;
  }
`;
document.head.appendChild(style);

// 安全移除函数(全局作用域)
const safeRemove = (element, selector = null, levels = 0, onBeforeRemove) => {
  if (!element || !(element instanceof Element)) return false;

  try {
    let target = selector ? element.closest(selector) : element;
    if (!target) return false;
    // 向上遍历父节点
    while (target && levels > 0) {
      target = target.parentElement;
      levels--;
    }
    // 元素或元素父级不存在返回false
    if (!target || !target.parentElement) return false;
    // 允许在移除前执行自定义逻辑(如清理事件监听器),避免内存泄漏
    if (typeof onBeforeRemove === "function") {
      onBeforeRemove(target);
    }
    // 移除元素
    target.remove();
    return true;
  } catch (error) {
    console.error("safeRemove error:", error);
    return false;
  }
};

setInterval(async () => {
  "use strict";
  if (executionCount >= 50) return;
  // 获取当前日期
  const currentDate = new Date();
  const currentDay = currentDate.getDate();
  const currentMonth = currentDate.getMonth() + 1;
  const lastMonth = currentDate.getMonth();
  const yesterday = currentDate.getDate() - 1;

  // 优化选择器性能
  const processElements = (selector, processor) => {
    document.querySelectorAll(selector).forEach(processor);
  };
  // 缩短正文部分的 p 标签行距
  processElements("span", (element) => {
    if (element.getAttribute("data-tag") === "post-title") {
      element.parentNode?.parentNode?.parentNode?.parentNode?.classList.add(
        "TAI-body-div"
      );
      const style = document.createElement("style");
      style.textContent = `
      .TAI-body-div p {
        margin: 8px 0 !important;
      }
    `;
      document.head.appendChild(style);
    }
  });
  // 处理 ul 标签样式
  processElements("ul", (element) => {
    element.style.setProperty("margin", "6px 0", "important");
  });
  // 处理 a 标签
  processElements("a", (element) => {
    const text = element.innerText;
    const dataTag = element.getAttribute("data-tag");
    // 格式化日期
    if (text.includes(" 小时前") || text.includes(" 分钟前")) {
      element.textContent = `${currentMonth}月${currentDay}日`;
    } else if (text.includes("昨天")) {
      element.textContent = `${currentMonth}月${yesterday}日`;
    }
    // 删除过期的内容
    if (dataTag === "post-published-at") {
      if (
        text.includes(" 天前") ||
        (text.includes(`${currentMonth}月`) &&
          parseInt(text.split(`${currentMonth}月`)[1]) < yesterday) ||
        (text.includes(`${currentMonth}月`) &&
          parseInt(text.split(`${currentMonth}月`)[0]) === lastMonth)
      ) {
        safeRemove(element, 'div[data-tag="post-card"]', 2);
      }
    } else if (text.includes("Skip navigation")) {
      element.remove();
    } else if (dataTag === "comment-avatar-wrapper") {
      element.parentNode?.remove();
    } else if (
      element.href === "https://www.patreon.com/user/gift?u=80821958"
    ) {
      safeRemove(element, null, 4);
    }
  });
  // 处理 div 标签
  processElements("div", (element) => {
    const dataTag = element.getAttribute("data-tag");
    if (element.id === "main-app-navigation") {
      safeRemove(element, null, 1);
    } else if (
      element.ariaExpanded === "false" &&
      element.innerText.includes("我的会籍")
    ) {
      safeRemove(element, "nav", 3);
    } else if (
      dataTag === "creation-name" &&
      element.innerText.includes("Love & Peace !")
    ) {
      safeRemove(element, null, 4);
    } else if (dataTag === "search-input-box") {
      safeRemove(element, null, 5);
    } else if (dataTag === "chip-container") {
      safeRemove(element, null, 2);
    } else if (dataTag === "post-details") {
      safeRemove(element);
    } // 移除已删除的留言及发布人头像
    else if (
      dataTag === "comment-body" &&
      element.innerText.includes("此留言已被删除。")
    ) {
      safeRemove(element, null, 3);
    } else if (dataTag === "comment-actions") {
      safeRemove(element);
    } else if (dataTag === "comment-field-box") {
      safeRemove(element, null, 3);
    } // 缩窄页边距
    else if (dataTag === "post-stream-container") {
      element.parentNode?.style.setProperty("padding-left", "4px");
      element.parentNode?.style.setProperty("padding-right", "4px");
    }
  });
  // 处理按钮
  processElements("button", (button) => {
    const text = button.innerText;
    const clickHandler = () => button.click();
    //remove header
    if (
      button.ariaExpanded === "false" &&
      button.getAttribute("aria-label") === "打开导航"
    ) {
      safeRemove(button, "header");
    } else if (["收起", "收起回复"].includes(text)) {
      safeRemove(button, null, 1);
    } else if (text === "展开") {
      setInterval(clickHandler, 2888);
    } else if (text === "加载更多留言") {
      setInterval(clickHandler, 1688);
    } else if (text === "加载回复") {
      setInterval(clickHandler, 1888);
    } else if (
      button.getAttribute("data-tag") === "commenter-name" &&
      text === "贝乐斯 Think Analyze Invest"
    ) {
      safeRemove(button, '[data-tag="commenter-name"]'); // 添加选择器二次验证
    }
  });
  executionCount++;
}, INTERVAL_DELAY);