您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Tries to detect provide copy buttons for TeleGuard IDs on 4chan
// ==UserScript== // @name 4chan TeleGuard ID Detector // @license GPLv3 // @namespace https://boards.4chan.org/ // @version 1.0 // @description Tries to detect provide copy buttons for TeleGuard IDs on 4chan // @author ceodoe // @match https://boards.4chan.org/*/thread/* // @match https://boards.4chan.org/*/res/* // @match https://archived.moe/*/thread/* // @match https://www.archived.moe/*/thread/* // @match https://thebarchive.com/*/thread/* // @match https://www.thebarchive.com/*/thread/* // @icon https://www.google.com/s2/favicons?sz=64&domain=4chan.org // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // ==/UserScript== let rememberCopiedIDs = GM_getValue("teleguard_rememberCopiedIDs", true); let rememberedIDs = GM_getValue("teleguard_rememberedIDs", []); let site = "4chan"; if(location.hostname.includes("archived.moe") || location.hostname.includes("thebarchive.com")) { site = "foolfuuka"; } GM_addStyle(` .fctgidd-rememberedID { color: #aaa; border-bottom: 1px dotted #aaa; } `); function parsePosts() { let posts = document.querySelectorAll("blockquote.postMessage"); if(site == "foolfuuka") { posts = document.querySelectorAll("article > div.text, div.post_wrapper > div.text"); } for(let i = 0; i < posts.length; i++) { if(posts[i].getAttribute("data-fctgidd-parsed") !== "1") { posts[i].setAttribute("data-fctgidd-parsed", "1"); // Strip all backlinks let postText = posts[i].innerText.replace(/\>\>\b[0-9]+\b/g, ""); let id = ""; let words = postText.split(/\s/); for(let j = 0; j < words.length; j++) { if(words[j].match(/[A-Z0-9]{9}/g)) { // All IDs are 9 chars, skip word if it isn't id = words[j]; break; // only do one ID per post } } if(id.length == 9) { // All IDs are 9 chars; if it's not, then we didn't find one let opPost = ""; if(posts[i].parentNode.classList.contains("op")) { opPost = "overflow: auto;"; } let archivePost = "border-top: 1px solid; width: fit-content;"; if(posts[i].parentNode.tagName.toLowerCase() == "article") { archivePost = ""; } let html = ` <div style="margin-top: 1em; padding: 0.5em; ${archivePost} ${opPost}"> <span style="color: #b5346c; font-weight: bold;">TeleGuard ID:</span> <span class="fctgidd-teleguard-id ${rememberCopiedIDs && rememberedIDs.includes(id) ? `fctgidd-rememberedID" title="ID has been previously copied` : ``}">${id}</span> <input type="button" class="fctgidd-copy-btn" id="fctgidd-copy-btn-${i}" data-fctgidd-teleguard-id="${id}" style="margin-left: 0.5em;" value="Copy"> </div> `; posts[i].insertAdjacentHTML("beforeend", html); document.getElementById(`fctgidd-copy-btn-${i}`).addEventListener("click", async function() { let tempInput = document.createElement("input"); let id = this.getAttribute("data-fctgidd-teleguard-id").trim(); tempInput.value = id; tempInput.select(); tempInput.setSelectionRange(0,66); try { await navigator.clipboard.writeText(tempInput.value); this.value = "✓"; if(rememberCopiedIDs) { // Refresh remembered ID list in case it was updated in another tab rememberedIDs = GM_getValue("teleguard_rememberedIDs", []); rememberedIDs.push(id); GM_setValue("teleguard_rememberedIDs", rememberedIDs); updateIDs(); } window.setTimeout(function() { document.getElementById(`fctgidd-copy-btn-${i}`).value = "Copy"; }, 3000); } catch (err) { alert("Failed to copy to clipboard: " + err); } }); } } } if(rememberCopiedIDs) { updateIDs(); } } function setupOptions() { let parent = document.querySelector("div.bottomCtrl"); if(site == "foolfuuka") { parent = document.querySelector("#footer"); } let html = ` <span id="fctgidd-options"> <input type="checkbox" name="fctgidd-rememberIDs-check" id="fctgidd-rememberIDs-check" ${rememberCopiedIDs ? `checked` : ``}> <label for="fctgidd-rememberIDs-check" title="Disabling also clears already remembered IDs">Remember copied TeleGuard IDs</label> | </span> `; parent.insertAdjacentHTML("afterbegin", html); document.querySelector("#fctgidd-rememberIDs-check").addEventListener("change", function() { GM_setValue("teleguard_rememberCopiedIDs", this.checked); if(!this.checked) { // Clear already remembered IDs on disable GM_setValue("teleguard_rememberedIDs", []); } location.reload(); }); } function updateIDs() { rememberedIDs = GM_getValue("teleguard_rememberedIDs", []); let idElems = document.querySelectorAll(".fctgidd-teleguard-id"); for(let i = 0; i < idElems.length; i++) { if(rememberedIDs.includes(idElems[i].innerText.trim())) { idElems[i].classList.add("fctgidd-rememberedID"); idElems[i].title = "ID has been previously copied"; } } } new MutationObserver(function(event) { parsePosts(); }).observe(document.querySelector("div.thread"), {childList: true}); setupOptions(); parsePosts();