// ==UserScript== // @name 52 Enhance // @namespace http://tampermonkey.net/ // @version 0.5.3 // @description 52 破解论坛增强脚本 // @author PRO // @match https://www.52pojie.cn/* // @icon http://52pojie.cn/favicon.ico // @license gpl-3.0 // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @require https://greasyfork.org/scripts/470224-tampermonkey-config/code/Tampermonkey%20Config.js?version=1243832 // @downloadURL none // ==/UserScript== (function() { 'use strict'; let idPrefix = "52-enhance-"; let config_desc = {}; function addDesc(id, name, default_value=true) { config_desc[id] = { name: name, value: default_value, input: "current", processor: "not", formatter: "boolean", title: name.startsWith("* ") ? `此选项 (${name.slice(2)}) 需要刷新页面才能生效` : `此选项 (${name}) 立即生效`, autoClose: false }; } addDesc("css-fix", "CSS 修复"); // 动态透明度;图标上光标不显示为 pointer addDesc("hide", "* 一键隐藏"); // 为旧版代码块添加“隐藏代码”的按钮;一键隐藏所有置顶帖;添加隐藏回复的按钮 addDesc("get-to-top", "* 回到顶部"); // 双击导航栏回到顶部;修改回到顶部按钮行为为原生 addDesc("emoji-fix", "* 修复 Emoji"); // 修复 Emoji 显示 addDesc("hide-signature", "隐藏签名档", false); // 隐藏所有签名档 addDesc("allow-tiny-signature", "允许小签名", true); // 允许小型签名档 (clientHeight <= 41) addDesc("hide-warning", "隐藏提醒", false); // 隐藏所有提醒 addDesc("hide-avatar-detail", "隐藏头像详情", false); // 隐藏头像下的详情 (统计信息、各类奖章、收听按钮) addDesc("hide-rating", "隐藏评分", false); // 隐藏所有评分 addDesc("hide-comment", "隐藏点评", false); // 隐藏所有点评 addDesc("hide-serial", "隐藏序号"); // 隐藏主页帖子列表的序号 (https://www.52pojie.cn/source/plugin/toplist_7ree/template/images/list_bg_7ree.gif) addDesc("auto-sign", "自动签到"); // 自动签到 addDesc("shortcut", "快捷键"); // 快捷键 (Enter: 快速回复) let config = GM_config(config_desc, false); // Styles const dynamicStyle = { "css-fix": `#jz52top { opacity: 0.2; transition: opacity 0.2s ease-in-out; } #jz52top:hover { opacity: 0.8; } .authicn { cursor: initial; } @media (any-hover: none) { #jz52top { opacity: 0.8; } #jz52top:hover { opacity: 0.8; } } html { scroll-behavior: smooth; }`, "hide-signature": "div.sign { display: none; }", "allow-tiny-signature": "div.sign.tiny-sign { display: block; }", "hide-warning": "div[class^=vw50_kfc_p] { display: none; }", "hide-avatar-detail": "div.tns.xg2, dl.credit-list, p.md_ctrl, p.xg1, ul.xl.xl2.o.cl { display: none; }", "hide-rating": "div.pcb > h3.psth.xs1, dl.rate { display: none; }", "hide-comment": "div.pcb > div.cm { display: none; }", "hide-serial": "div.boxbg_7ree { background-image: none; padding-left: 0; }" }; // Helper function for css function injectCSS(id, css) { let style = document.createElement("style"); style.id = idPrefix + id; style.textContent = css; document.head.appendChild(style); } function cssHelper(id, enable) { let current = document.getElementById(idPrefix + id); if (current) { current.disabled = !enable; } else if (enable) { injectCSS(id, dynamicStyle[id]); } } // Hide if (config["hide"]) { // Basic CSS let css = `div.hidden, tr.hidden { display: none; } td.hidden { cursor: help; background: repeating-linear-gradient(135deg, transparent 0, transparent 6px, #e7e7e7 6px, #e7e7e7 12px, transparent 12px) no-repeat 0 0, #eee; } td.hidden > div { pointer-events: none; } td.hidden > div > div > em::after { content: "此回复已被隐藏,点击以重新显示"; } .plhin:hover td.hidden .hin { opacity: 0.2; } .toggle-reply-header { opacity: 0.6; } .toggle-reply-footer { display: block; text-align: center; position: relative; top: 0.8em; }`; injectCSS("hide", css); // Hide code function toggleCode() { let code = this.parentNode.parentNode.lastChild; if (code.classList.toggle("hidden")) { this.textContent = " 显示代码"; } else { this.textContent = " 隐藏代码"; } } document.querySelectorAll("em.viewsource").forEach(ele => { let hide_code = document.createElement("em"); hide_code.setAttribute("style", ele.getAttribute("style")); hide_code.setAttribute("num", ele.getAttribute("num")); hide_code.textContent = " 隐藏代码"; hide_code.addEventListener("click", toggleCode); ele.parentNode.appendChild(hide_code); }); // Hide all top threads let display = Boolean(document.querySelectorAll("tbody[id^='stickthread_']").length); let table = document.getElementById("threadlisttableid"); if (display && table) { function hideAll() { document.querySelectorAll("tbody[id^='stickthread_']").forEach(ele => { let close = ele.querySelector("a.closeprev"); if (close) close.click(); }); } let tooltip = document.querySelector("div#threadlist > div.th > table > tbody > tr > th > div.tf"); let show_top = tooltip.querySelector("span#clearstickthread"); show_top.removeAttribute("style"); show_top.insertAdjacentHTML("beforeend", "  "); let hide_all = document.createElement("a"); hide_all.href = "javascript:;"; hide_all.className = "xi2"; hide_all.textContent = "隐藏置顶"; hide_all.title = "隐藏置顶"; hide_all.addEventListener("click", hideAll); show_top.insertAdjacentElement("beforeend", hide_all); } // Hide reply function toggleReply(keep) { for (let ele of keep.parentElement.children) { if (ele != keep) { ele.classList.toggle("hidden"); } } let ele = keep.lastElementChild; if (ele.classList.toggle("hidden")) { ele.addEventListener("click", e => { toggleReply(keep); ele.removeAttribute("title"); }, { once: true }); ele.title = "点击显示被隐藏的回复"; } } function toggleReplyFooter() { toggleReply(this.parentElement.parentElement); } function toggleReplyHeader() { toggleReply(this.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.children[3]); } document.querySelectorAll("table.plhin tbody:has( tr > td.pls)").forEach(ele => { let toggle_reply_footer = document.createElement("a"); toggle_reply_footer.href = "javascript:void(0);"; toggle_reply_footer.className = "toggle-reply-footer"; toggle_reply_footer.textContent = "隐藏/显示回复"; toggle_reply_footer.addEventListener("click", toggleReplyFooter); let keep = ele.querySelector("tr:nth-child(4) > td.pls"); keep.appendChild(toggle_reply_footer); let toggle_reply_header = document.createElement("a"); toggle_reply_header.href = "javascript:void(0);"; toggle_reply_header.className = "toggle-reply-header"; toggle_reply_header.textContent = "👀"; toggle_reply_header.addEventListener("click", toggleReplyHeader); let header = ele.querySelector("tr:nth-child(1) > td.pls > div.favatar div.authi"); header.appendChild(toggle_reply_header); if (!keep.parentElement.parentElement.firstElementChild.querySelector("div.avatar img")) { toggle_reply_footer.click(); // Hide reply by default if no avatar (blocked user) } }); } // Get to top if (config["get-to-top"]) { // Double click navbar to get to top let nv = document.getElementById("nv"); if (nv) nv.addEventListener("dblclick", e => { window.scrollTo({ top: 0, behavior: "smooth" }); }); // Change get to top button behavior (use vanilla solution) let btn = document.getElementById("goTopBtn"); if (btn) btn.onclick = e => { window.scrollTo({ top: 0, behavior: "smooth" }); }; } // Emoji fix if (config["emoji-fix"]) { let temp = document.createElement("span"); function fixEmoji(html) { // Replace patterns like `&#128077;` with represented emoji return html.replace(/&(amp;)*#(\d+);/g, (match, p1, p2) => { temp.innerHTML = `&#${p2};`; // console.log(`${match} -> ${temp.textContent}`); // DEBUG return temp.textContent; }); } function fix(node) { // Select text nodes let walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false); let textNode; while (textNode = walker.nextNode()) { textNode.nodeValue = fixEmoji(textNode.nodeValue); } } let replies = document.querySelectorAll("table.plhin td.plc div.pct > div.pcb"); replies.forEach(fix); let signatures = document.querySelectorAll("div.sign, div.bm_c.u_profile > div:nth-child(1) > ul:nth-child(3) > li > table > tbody > tr > td"); signatures.forEach(fix); } // Auto sign function autoSign(enable) { if (enable && window === window.top) { // Only run on top frame let sign = document.querySelector("#um > p:nth-child(3) > a:nth-child(1) > img"); let url = "https://www.52pojie.cn/home.php?mod=task&do=apply&id=2&referer=%2F"; let waf = "https://www.52pojie.cn/waf_text_verify.html"; if (sign) { // Checkin let iframe = document.createElement("iframe"); iframe.src = url; iframe.style.display = "none"; document.body.appendChild(iframe); sign.title = "后台签到中..."; sign.style.opacity = 0.5; sign.height = 20; sign.src = "https://static.52pojie.cn/static/image/common/imageloading.gif"; sign.style.cursor = "progress"; sign.parentElement.removeAttribute("href"); function check() { let curr = iframe.contentWindow.location.href; let msg; if (curr === "https://www.52pojie.cn/home.php?mod=task&item=new" || curr.match(/https:\/\/www\.52pojie\.cn\/*/)) { msg = "签到成功!"; sign.src = "https://static.52pojie.cn/static/image/common/wbs.png"; } else if (curr.startsWith(waf)) { msg = "触发了防火墙,请稍后刷新页面检查是否签到成功。"; sign.src = "https://static.52pojie.cn/static/image/common/qds.png"; sign.parentElement.href = url; } else { return false; } sign.title = msg; sign.style.opacity = 1; sign.style.cursor = "default"; return true; } let id = window.setInterval(() => { if (check()) window.clearInterval(id); }, 500); // Peoredically check if we are done } } } autoSign(config["auto-sign"]); // CSS injection let delayedCSS = ["hide-signature", "allow-tiny-signature"]; for (let prop in dynamicStyle) { if (delayedCSS.includes(prop)) continue; cssHelper(prop, config[prop]); } // Tag tiny signatures as `tiny-sign`; Delayed CSS injection document.addEventListener("readystatechange", e => { if (document.readyState == "complete") { document.querySelectorAll("div.sign").forEach(ele => { if (ele.clientHeight <= 41) { ele.classList.add("tiny-sign"); } }); for (let prop of delayedCSS) { cssHelper(prop, config[prop]); } } }); // Shortcut function handleShortcut(e) { if (e.target.tagName == "TEXTAREA" || e.target.tagName == "INPUT") return; if (e.key == "Enter") { const reply = document.querySelector("textarea#fastpostmessage"); if (reply) { reply.scrollIntoView(); reply.focus(); e.preventDefault(); } } } function shortcut(enable) { if (enable) { document.addEventListener("keydown", handleShortcut); } else { document.removeEventListener("keydown", handleShortcut); } } shortcut(config["shortcut"]); // Listen to config changes let callbacks = { "auto-sign": autoSign, "shortcut": shortcut }; window.addEventListener(GM_config_event, e => { if (e.detail.type == "set") { let callback = callbacks[e.detail.prop]; if (callback && (e.detail.before !== e.detail.after)) { callback(e.detail.after); } else if (e.detail.prop in dynamicStyle) { cssHelper(e.detail.prop, e.detail.after); } } }); })();