Greasy Fork

Greasy Fork is available in English.

Base64 Link Decoder for 4chan and Archives

Decode base64-encoded links in 4chan posts and various archives

当前为 2024-09-14 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

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