// ==UserScript== // @name 52 Enhance // @namespace http://tampermonkey.net/ // @version 0.3.6 // @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_registerMenuCommand // @grant GM_unregisterMenuCommand // @require https://greasyfork.org/scripts/470224-tampermonkey-config/code/Tampermonkey%20Config.js?version=1229665 // @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", }; } 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("auto-sign", "自动签到"); // 自动签到 let config = GM_config(config_desc, false); // Helper function for css function cssHelper(id, css) { let current = document.getElementById(idPrefix + id); if (css && !current) { let style = document.createElement("style"); style.id = idPrefix + id; style.textContent = css; document.head.appendChild(style); } else if (!css && current) { current.remove(); } } // Css fix function cssFix(enable) { let css = ` #jz52top { opacity: 0.2; transition: opacity 0.2s ease-in-out; } #jz52top:hover { opacity: 0.8; } @media (any-hover: none) { #jz52top { opacity: 0.8; } #jz52top:hover { opacity: 0.8; } } .authicn { cursor: initial; } `; cssHelper("css-fix", enable ? css : null); } cssFix(config["css-fix"]); // Hide if (config["hide"]) { // Hide code function toggleCode() { let code = this.parentNode.parentNode.lastChild; if (code.style.display == "none") { code.style.display = ""; this.textContent = " 隐藏代码"; } else { code.style.display = "none"; 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 toggleReplyHeader() { let reply = this.parentNode.parentNode.parentNode.nextSibling; if (reply.style.display == "none") { reply.style.display = ""; } else { reply.style.display = "none"; } } let headers = document.querySelectorAll("div.pti > div.authi"); headers.forEach(header => { let pipe = document.createElement("span"); pipe.classList.add("pipe"); pipe.textContent = "|"; let toggle = document.createElement("a"); toggle.href = "javascript:void(0);"; toggle.textContent = "隐藏/显示"; toggle.addEventListener("click", toggleReplyHeader); if (header.querySelector("span.none")) { pipe.classList.add("show"); toggle.classList.add("show"); } header.insertAdjacentElement("beforeend", pipe); header.insertAdjacentElement("beforeend", toggle); }); function toggleReplyFooter() { let reply = this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.firstChild.lastChild.lastElementChild; if (reply.style.display == "none") { reply.style.display = ""; } else { reply.style.display = "none"; } } let footers = document.querySelectorAll("td.plc >div.po.hin > div.pob.cl > p"); footers.forEach(footer => { let toggle = document.createElement("a"); toggle.href = "javascript:void(0);"; toggle.textContent = "隐藏/显示"; toggle.addEventListener("click", toggleReplyFooter); footer.insertAdjacentElement("beforeend", toggle); }); } // Get to top if (config["get-to-top"]) { // Double click navbar to get to top document.getElementById("nv").addEventListener("dblclick", e => { window.scrollTo({ top: 0, behavior: "smooth" }); }); // Change get to top button behavior (use vanilla solution) document.getElementById("goTopBtn").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 > div.t_fsz"); replies.forEach(fix); let ratings = document.querySelectorAll("tbody.ratl_l > tr"); ratings.forEach(rating => fix(rating.lastElementChild)); let signatures = document.querySelectorAll("div.sign"); signatures.forEach(fix); } // Hide signatures function hideSignature(enable) { let css = "div.sign { display: none; }"; cssHelper("hide-signature", enable ? css : null); } // Allow tiny signatures (clientHeight <= 41) function allowTinySignature(enable) { let css = "div.sign.tiny-sign { display: block; }"; cssHelper("allow-tiny-signature", enable ? css : null); } // Tag tiny signatures as `tiny-sign` document.addEventListener("readystatechange", e => { if (document.readyState == "complete") { document.querySelectorAll("div.sign").forEach(ele => { if (ele.clientHeight <= 41) { ele.classList.add("tiny-sign"); } }); } hideSignature(config["hide-signature"]); allowTinySignature(config["allow-tiny-signature"]); }); // Hide warnings function hideWarning(enable) { let css = "div[class^=vw50_kfc_p] { display: none; }"; cssHelper("hide-warning", enable ? css : null); } hideWarning(config["hide-warning"]); // Hide avatar details function hideAvatarDetail(enable) { let css = "dl.credit-list, ul.xl.xl2.o.cl { display: none; }"; cssHelper("hide-avatar-detail", enable ? css : null); } hideAvatarDetail(config["hide-avatar-detail"]); // Hide ratings function hideRating(enable) { let css = "div.pcb > h3.psth.xs1, dl.rate { display: none; }"; cssHelper("hide-rating", enable ? css : null); } hideRating(config["hide-rating"]); // Hide comments function hideComment(enable) { let css = "div.pcb > div.cm { display: none; }"; cssHelper("hide-comment", enable ? css : null); } hideComment(config["hide-comment"]); // Auto sign function autoSign(enable) { if (enable) { let sign = document.querySelector("#um > p:nth-child(3) > a:nth-child(1) > img"); if (sign) { sign.click(); } } } autoSign(config["auto-sign"]); // Listen to config changes let callbacks = { "css-fix": cssFix, "hide-signature": hideSignature, "allow-tiny-signature": allowTinySignature, "hide-warning": hideWarning, "hide-avatar-detail": hideAvatarDetail, "hide-rating": hideRating, "hide-comment": hideComment, "auto-sign": autoSign }; 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); } } }); })();