Skip to content

Instantly share code, notes, and snippets.

@idolpx
Last active March 22, 2020 23:24
Show Gist options
  • Save idolpx/325e9deae5f61f3479bf8b6f0527da6b to your computer and use it in GitHub Desktop.
Save idolpx/325e9deae5f61f3479bf8b6f0527da6b to your computer and use it in GitHub Desktop.
Automatically base64 decode links in reddit posts
// ==UserScript==
// @namespace https://gist.github.com/idolpx
// @name Reddit Base64 EnDecoder
// @version 2.1.1
// @description Automatically base64 decode links in reddit posts
// Encode/Decode selected text you enter when making a post
// - Use CTRL + [SPACE] to toggle encode/decode of text entered
// Decode selected text in page for people who post Base64 text without the trailing '=='
// - Highlight the text in the browser and then press CTRL + [SPACE]
// @downloadURL https://openuserjs.org/install/idolpx/Reddit_Base64_EnDecoder.user.js
// @updateURL https://openuserjs.org/meta/idolpx/Reddit_Base64_EnDecoder.meta.js
// @author Jaime Idolpx
// @attribution Based on original code by DanielBlaze (https://openuserjs.org/users/DanielBlaze)
// @copyright 2020, idolpx (https://openuserjs.org/users/idolpx)
// @license MIT
// @match https://*.reddit.com/r/*
// @grant none
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
// ==/UserScript==
waitForKeyElements ("div[data-editor], textarea[placeholder]", main);
function create_links(text) {
return (text || "").replace(
/([^\S]|^)(((https?\:\/\/)|(www\.))(\S+))/gi,
function(match, space, url){
var hyperlink = url;
if (!hyperlink.match('^https?:\/\/')) {
hyperlink = 'http://' + hyperlink;
}
// Secure links = underline in blue. Insecure links = warning image + underlined in red
if (hyperlink.startsWith('https://')) {
return space + `<a style="border-bottom: 1px dotted #036;" target="_blank" href="${hyperlink}">${url}</a>`;
} else if (hyperlink.startsWith('http://')) {
return space + `<img style="vertical-align: middle;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAbwAAAG8B8aLcQwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIVSURBVDiNhZNLaBNRFIb/OzNJmzakqQhqjFptrK1BIfRBJ1GDjzQ0kZiImdDSIqmKC1clQiDFR6QqSJaCC0UXUhdZim7UUgoiuBQ3GomaVMVHA2LRJE5mjgtpMZlRz+7+5z/fOfdwLyMi6EUknrZW5Wq09rOy22DgztyfyRT0fEwPEBhLW0DVJ4M9n50OyyJuzndUiTd3zman3zd6Bd32VE0eEovOk8EXwGtgY3u56cJdZxaAp9HKNQpDI0lba5M8ObI3v6J57CWsav3h9h1JuP4LEBh/Pup9a7K0yLj3dAMuPuwBU4GzoZcA6M4/Af7RVPdqa2UiLP7e1+1HDsy9agcAbLcuYeuar91DsUTgrwAe7NL4/jxvNKgAAJXYH3sBpgI5kKpe1wUMj6bEjrVLkQOuD41TrsT65go8ji82XyxxQgNgjF2Z8OfAmP67WI7JfXlAUTJ1gOHxVGjnltKuvq5FnRJWd2rjZBzue2fxSYlpAOAkSeI5wuVj/pymNDiwAOe67xo9PlAEU5XTkiQZ+U2ucNy74+PxkFjUGLvs3+C2ltBiVOp0AQRzmyw8LnTaORCdiu55o3vf5I1+HJ3p1c0Ft30C1WoxAQw2U0OH5Qi7C3j+zKyb4xiBQM0CVFybutWbDolFGA1aUKR/AYWyqU6TFQ5X5zaDMX6eERGCY6mDBDYI0n4uWS57dQZQGLjZB9nMuV9Nv60tCtUXugAAAABJRU5ErkJggg==" />&nbsp; <a style="border-bottom: 1px dotted #f00;" target="_blank" href="${hyperlink}">${url}</a>`;
}
}
);
};
function decode_links() {
$('div[theme] p').each(function(i) {
var content = $(this).text();
if(content.endsWith('=')){
// split on the words we find, and make sure we have something before continuing
const words = content.split(' ');
if (words.length === 0)
return;
// decode the string
const transformed = words.map(word => {
try {
const decoded = atob(word);
const links = create_links(decoded);
return links.replace(/(?:\r\n|\r|\n)/g, '<br>');
} catch (_) {
}
return word;
});
var url = transformed.join(' ');
$(this).html(url);
}
});
}
function endecode_text() {
$('div[data-contents] span[data-text]').each(function(index, value) {
var content = $(this).text();
if(content.endsWith('=')) {
$(this).text(atob(content));
} else {
$(this).text(btoa(content));
}
console.log(`div${index}: ${this.id} {content}`);
});
}
function decode_selection() {
var range = document.getSelection().getRangeAt(0);
var content = range.toString();
if(content.length) {
console.log(content);
const decoded = atob(content); // Decode Base64
const links = create_links(decoded); // Create Links
var newNode = document.createElement('span');
newNode.innerHTML = links.replace(/(?:\r\n|\r|\n)/g, '<br>'); // Replace CR/LF
range.deleteContents();
range.insertNode(newNode);
}
}
function main() {
// Automatically decode any Base64 text it finds on the page
decode_links()
// Setup encode key combination
var ctrlPressed = false; //Variable to check if the the first button is pressed at this exact moment
$(document).keydown(function(e) {
if (e.ctrlKey) { //If it's ctrl key
ctrlPressed = true; //Set variable to true
}
}).keyup(function(e) { //If user releases ctrl button
if (e.ctrlKey) {
ctrlPressed = false; //Set it to false
}
}); //This way you know if ctrl key is pressed. You can change e.ctrlKey to any other key code you want
$(document).keydown(function(e) { //For any other keypress event
if (e.which == 32) { //Checking if it's space button
if(ctrlPressed == true){ //If it's space, check if ctrl key is also pressed
// Encode/Decode selected text you enter when making a post
// - Use CTRL + [SPACE] to toggle encode/decode of text entered
endecode_text();
// Decode selected text in page for people who post Base64 text without the trailing '=='
// - Highlight the text in the browser and then press CTRL + [SPACE]
decode_selection();
ctrlPressed = false; //Important! Set ctrlPressed variable to false. Otherwise the code will work everytime you press the space button again
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment