PatreonExpander

Simplify elements, expand contents and comments

目前為 2025-03-23 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==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);