Reddit B64 Decoder

Decode Base64-encoded text in Reddit posts and convert URLs to clickable links.

Устаревшая версия за 30.07.2024. Перейдите к последней версии.

// ==UserScript==
// @name         Reddit B64 Decoder
// @namespace    https://greasyfork.org/es/scripts/476028
// @version      1.5.2
// @description  Decode Base64-encoded text in Reddit posts and convert URLs to clickable links.
// @author       Shu2Ouma
// @icon         https://www.redditstatic.com/shreddit/assets/favicon/192x192.png
// @license      MIT
// @match        https://*.reddit.com/r/*
// @grant        none
// ==/UserScript==

// Function to decode Base64-encoded text and convert URLs to clickable links
function decodeBase64AndLinkify(text) {
  const base64Regex = /([A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)*/g;

  return text.replace(base64Regex, match => {
    try {
      const decoded = atob(match);
      if (decoded.includes('https://') || decoded.includes('http://')) {
        return (
          decoded
            .replace(/[\r\n]+/g, '<br /><br />')
            .replace(/(https?:\/\/[^\s<]+)/g, `<a href="$1" target="_blank" rel="noreferrer noopener" style='text-decoration: underline #FF4500; text-underline-offset: 2px;'>$1</a>`)
        );
      }
    } catch (error) {
      console.error(`Error decoding Base64: ${match}`, error);
    }
    return match;
  });
}

// Function to process Reddit posts on the page
function processRedditPosts(container) {
  const postContents = container.querySelectorAll('p');
  postContents.forEach(post => {
    const decodedText = decodeBase64AndLinkify(post.textContent);
    if (decodedText !== post.textContent) {
      post.innerHTML = decodedText;
    }
  });
}

// Execute the script with a 2.0-second delay after the page has finished loading
function initialProcess() {
  const container = document.querySelector('#main-content');
  if (container) {
    processRedditPosts(container);
  }
}

// Handle click events to check for new elements
function handleClick() {
  setTimeout(() => {
    const container = document.querySelector('#main-content');
    if (container) {
      processRedditPosts(container);
    }
  }, 1000); // Delay to ensure content has loaded
}

// Observe changes in the DOM within #main-content
const observer = new MutationObserver(mutationsList => {
  mutationsList.forEach(mutation => {
    if (mutation.addedNodes.length > 0) {
      mutation.addedNodes.forEach(node => {
        if (node instanceof HTMLElement) {
          const container = node.closest('#main-content');
          if (container) {
            processRedditPosts(container);
          }
        }
      });
    }
  });
});

// Start observing changes in the #main-content container
const mainContentContainer = document.querySelector('#main-content');
if (mainContentContainer) {
  observer.observe(mainContentContainer, { childList: true, subtree: true });
}

// Add event listener for clicks to check for new elements
document.addEventListener('click', handleClick);

// Initial processing after the page loads
window.addEventListener('load', () => {
  setTimeout(initialProcess, 2000);
});