NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Facebook HEX // @name:vi Facebook HEX // @namespace https://lelinhtinh.github.io // @description Convert HEX to text, in a post or comment on Facebook. // @description:vi Chuyển đổi HEX thành URL hoặc text, trong bài viết hoặc bình luận trên Facebook. // @version 1.0.0 // @icon https://i.imgur.com/oz5CjJe.png // @author lelinhtinh // @oujs:author baivong // @license MIT; https://baivong.mit-license.org/license.txt // @match https://*.facebook.com/* // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?v=a834d46 // @noframes // @supportURL https://github.com/lelinhtinh/Userscript/issues // @run-at document-idle // @grant GM.openInTab // @grant GM_openInTab // ==/UserScript== /** * If `false`, open in new tab after clicking on decoded link. * @type {boolean} true or false */ const COPY_ONLY = false; /** * Makes the tab being opened inside a incognito mode/private mode window. * Currently, only works with Tampermonkey BETA. * @type {boolean} true or false */ const PRIVATE = true; /* === DO NOT CHANGE === */ function fallbackCopyTextToClipboard(text) { let textArea = document.createElement('textarea'); textArea.value = text; textArea.style.top = '0'; textArea.style.left = '0'; textArea.style.position = 'fixed'; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { document.execCommand('copy'); } catch (err) { console.error('Fallback: Oops, unable to copy', err); } document.body.removeChild(textArea); } function copyTextToClipboard(text) { if (!navigator.clipboard) { fallbackCopyTextToClipboard(text); return; } navigator.clipboard.writeText(text).catch((err) => { console.error('Async: Could not copy text', err); }); } function validURL(url) { try { const uri = new URL(url); return !!uri.host && uri.host.includes('.'); } catch (e) { return false; } } function cleanWordBreak(post) { if (post.querySelector('.word_break') !== null) { post.querySelectorAll('wbr').forEach((e) => e.remove()); post.querySelectorAll('span').forEach((span) => { if (span.querySelector('span, img') !== null) return; const text = document.createTextNode(span.textContent); span.parentNode.replaceChild(text, span); }); } } function renderResult(post, data) { const { content, result } = data; if (!content || !result) return; copyTextToClipboard(result); post.innerHTML = post.innerHTML.replace( content, ` <strong class="fb-hex${validURL(result) ? ' fb-hex-link' : ''}" title="Copied to clipboard${COPY_ONLY ? '' : '\nClick to open in new tab'}" style="cursor:pointer" >${result}</strong> `, ); } function handle(post) { if (post.querySelector('.fb-hex') !== null) return; cleanWordBreak(post); const handleURL = URL.createObjectURL( new Blob( [ '(', function () { self.onmessage = (e) => { function hex2ascii(hex) { if (!(typeof hex === 'number' || typeof hex == 'string')) return ''; hex = hex.toString().replace(/\s+/gi, ''); const stack = []; for (let i = 0; i < hex.length; i += 2) { const code = parseInt(hex.substr(i, 2), 16); if (!isNaN(code) && code !== 0) { stack.push(String.fromCharCode(code)); } } return stack.join(''); } function getResult(content) { content = content.match(/\b[a-f0-9\s]{12,}\b/i); if (content === null) return {}; content = content[0].trim(); const result = hex2ascii(content); return { content, result }; } self.postMessage(getResult(e.data)); }; }.toString(), ')()', ], { type: 'application/javascript', }, ), ); const worker = new Worker(handleURL); worker.onmessage = (e) => { if (!e.data) return; renderResult(post, e.data); }; worker.postMessage(post.textContent); } function getPost(e) { const target = e.target; if (target.getAttribute('role') === 'button') return; const role = target.closest('[role]'); if (role.getAttribute('role') !== 'article') return; const post = target.closest('p, span, [dir="auto"], [data-ft] > div[style]'); if (post === null) return; const parent = post.parentNode; if (parent.querySelector('.word_break') !== null) { handle(parent); return; } handle(post); } document.addEventListener('click', getPost); function decodedClicking(e) { const target = e.target; if (!target.classList.contains('fb-hex')) return; const result = target.textContent; copyTextToClipboard(result); if (COPY_ONLY) return; if (!target.classList.contains('fb-hex-link')) return; GM.openInTab(result, { active: true, insert: true, incognito: PRIVATE, }); } document.addEventListener('click', decodedClicking);