Created
February 25, 2025 11:54
-
-
Save slashedzer0/f55dcdf8b17c2b87ce5fc9610552f65a to your computer and use it in GitHub Desktop.
High-performance Reddit to RedLib frontend redirector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Reddit to RedLib Redirector | |
// @namespace https://github.com/slashedzer0 | |
// @version 1.1.0 | |
// @description High-performance Reddit to RedLib frontend redirector | |
// @author slashedzer0 | |
// @match *://*.reddit.com/* | |
// @match *://reddit.com/* | |
// @match *://*/* | |
// @grant none | |
// @run-at document-start | |
// @noframes true | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
const REDLIB_BASE = 'https://redlib.perennialte.ch'; | |
const REDDIT_PATTERN = /^(?:(?:https?:)?\/\/)?(?:(?:www|old|new)\.)?reddit\.com(\/[^?#]*)?(\?[^#]*)?(#.*)?$/i; | |
const redditHostRegex = /\breddit\.com$/i; | |
const processedLinks = new Set(); | |
const convertToRedLib = (() => { | |
const a = document.createElement('a'); | |
return (url) => { | |
if (!url || url.includes(REDLIB_BASE)) return url; | |
try { | |
a.href = url; | |
if (!REDDIT_PATTERN.test(url)) return url; | |
return REDLIB_BASE + (a.pathname || '/') + a.search + a.hash; | |
} catch { | |
return url; | |
} | |
}; | |
})(); | |
const debounce = (fn, delay) => { | |
let timeoutId; | |
return (...args) => { | |
clearTimeout(timeoutId); | |
timeoutId = setTimeout(() => fn.apply(null, args), delay); | |
}; | |
}; | |
const processLink = (link) => { | |
if (!link || !link.href || processedLinks.has(link)) return; | |
if (link.href.indexOf('reddit.com') !== -1) { | |
const newHref = convertToRedLib(link.href); | |
if (newHref !== link.href) { | |
link.href = newHref; | |
processedLinks.add(link); | |
} | |
} | |
}; | |
const processLinks = debounce((links) => { | |
const len = links.length; | |
for (let i = 0; i < len; i++) { | |
processLink(links[i]); | |
} | |
}, 50); | |
const observerCallback = (mutations) => { | |
const links = []; | |
mutations.forEach(mutation => { | |
if (mutation.type === 'childList') { | |
const addedNodes = mutation.addedNodes; | |
const addedNodesLen = addedNodes.length; | |
for (let i = 0; i < addedNodesLen; i++) { | |
const node = addedNodes[i]; | |
if (node.nodeType === 1) { | |
if (node.tagName === 'A') { | |
links.push(node); | |
} else if (node.getElementsByTagName) { | |
const nodeLinks = node.getElementsByTagName('a'); | |
if (nodeLinks.length) { | |
links.push(...nodeLinks); | |
} | |
} | |
} | |
} | |
} | |
}); | |
if (links.length) { | |
processLinks(links); | |
} | |
}; | |
if (redditHostRegex.test(window.location.hostname)) { | |
const redirectUrl = convertToRedLib(window.location.href); | |
if (redirectUrl !== window.location.href) { | |
window.stop(); | |
window.location.replace(redirectUrl); | |
} | |
} | |
document.addEventListener('click', (e) => { | |
const link = e.target.closest('a'); | |
if (!link || !link.href) return; | |
if (link.href.indexOf('reddit.com') !== -1) { | |
const newHref = convertToRedLib(link.href); | |
if (newHref !== link.href) { | |
e.preventDefault(); | |
window.location.href = newHref; | |
} | |
} | |
}, { capture: true, passive: false }); | |
const observer = new MutationObserver(observerCallback); | |
observer.observe(document.documentElement, { | |
childList: true, | |
subtree: true, | |
attributes: false, | |
characterData: false | |
}); | |
processLinks(document.getElementsByTagName('a')); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment