您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Decode base64-encoded links in 4chan posts and various archives
当前为
// ==UserScript== // @name Base64 Link Decoder for 4chan and Archives // @namespace Violentmonkey Scripts // @match *://boards.4channel.org/* // @match *://boards.4chan.org/* // @match *://archived.moe/* // @match *://archiveofsins.com/* // @grant none // @version 1.0 // @description Decode base64-encoded links in 4chan posts and various archives // @license MIT // ==/UserScript== (function() { 'use strict'; const base64Regex = /^[A-Za-z0-9+/]+=*$/; const isURL = (str) => /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i.test(str); function decodeAndReplace(element) { const html = element.innerHTML; const modifiedHtml = html.replace(/<wbr>/g, ''); // Remove <wbr> tags element.innerHTML = modifiedHtml; const textNodes = []; const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false); let node; while (node = walker.nextNode()) { textNodes.push(node); } textNodes.forEach(node => { const parts = node.textContent.split(/\s+/); let changed = false; for (let i = 0; i < parts.length; i++) { if (base64Regex.test(parts[i])) { try { const decoded = atob(parts[i]); if (isURL(decoded)) { parts[i] = `<a href="${decoded}" target="_blank">${decoded}</a>`; changed = true; } } catch (e) { // Not a valid base64 string, skip } } } if (changed) { const span = document.createElement('span'); span.innerHTML = parts.join(' '); node.parentNode.replaceChild(span, node); } }); } function processNewPosts() { // For 4chan const posts = document.querySelectorAll('.postMessage'); posts.forEach(decodeAndReplace); // For Archives (ArchiveOfSins, Archived.Moe, etc.) const archivePosts = document.querySelectorAll('.text'); archivePosts.forEach(decodeAndReplace); } function initScript() { // Initial processing processNewPosts(); // Watch for new posts const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { // For 4chan if (node.classList.contains('postContainer')) { const postMessage = node.querySelector('.postMessage'); if (postMessage) decodeAndReplace(postMessage); } // For Archives if (node.classList.contains('post')) { const textElement = node.querySelector('.text'); if (textElement) decodeAndReplace(textElement); } } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); } // Delay script execution by 5 seconds setTimeout(initScript, 5000); })();