// ==UserScript==
// @name Base64 Selection Decoder
// @author ChatGPT
// @namespace https://elakiri.com/
// @version 1.0
// @description Decode Base64 text when you select it
// @match https://elakiri.com/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
let popup;
function decodeBase64(str) {
try {
// Remove whitespace that may have been introduced by wrapping.
str = str.replace(/\s+/g, '');
// Basic Base64 sanity check.
if (str.length < 4 || !/^[A-Za-z0-9+/_-]+={0,2}$/.test(str))
return null;
// Support URL-safe Base64 too.
str = str.replace(/-/g, '+').replace(/_/g, '/');
// Restore missing padding.
while (str.length % 4)
str += '=';
const binary = atob(str);
// Correctly decode UTF-8 text, including Sinhala etc.
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
} catch {
return null;
}
}
function removePopup() {
if (popup) {
popup.remove();
popup = null;
}
}
document.addEventListener('mousedown', removePopup);
document.addEventListener('mouseup', () => {
setTimeout(() => {
const selection = window.getSelection();
const selected = selection.toString().trim();
if (!selected)
return;
const decoded = decodeBase64(selected);
if (decoded === null || decoded === selected)
return;
const range = selection.getRangeAt(0);
const rect = range.getBoundingClientRect();
popup = document.createElement('div');
popup.textContent = decoded;
Object.assign(popup.style, {
position: 'absolute',
left: `${window.scrollX + rect.left}px`,
top: `${window.scrollY + rect.bottom + 6}px`,
maxWidth: '600px',
padding: '8px 12px',
background: '#15202b',
color: '#fff',
border: '1px solid #536471',
borderRadius: '8px',
fontFamily: 'sans-serif',
fontSize: '14px',
lineHeight: '1.4',
whiteSpace: 'pre-wrap',
overflowWrap: 'anywhere',
zIndex: '2147483647',
boxShadow: '0 4px 12px rgba(0,0,0,.35)',
cursor: 'pointer'
});
popup.title = 'Click to copy decoded text';
popup.addEventListener('mousedown', e => {
e.stopPropagation();
});
popup.addEventListener('click', async () => {
await navigator.clipboard.writeText(decoded);
popup.textContent = 'Copied';
setTimeout(removePopup, 600);
});
document.body.appendChild(popup);
}, 0);
});
})();