dotfiles/.config/qutebrowser/greasemonkey/redirect.js

1240 lines
34 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==UserScript==
// @name Privacy Redirector
// @description Redirect social media platforms to their privacy respecting frontends
// @namespace https://github.com/dybdeskarphet/privacy-redirector
// @author Ahmet Arda Kavakcı
// @license GPLv3
// @version 1.6.2
// @downloadURL
// https://raw.githubusercontent.com/dybdeskarphet/privacy-redirector/main/privacy-redirector.user.js
// @supportURL https://github.com/dybdeskarphet/privacy-redirector
// @updateURL
// https://raw.githubusercontent.com/dybdeskarphet/privacy-redirector/main/privacy-redirector.user.js
// @run-at document-start
// @match *://*.bandcamp.com/*
// @match *://*.fandom.com/*
// @match *://*.genius.com/*
// @match *://*.google.com/*
// @match *://*.imdb.com/*
// @match *://*.imgur.com/*
// @match *://*.imgur.io/*
// @match *://*.instagram.com/*
// @match *://*.medium.com/*
// @match *://*.pinterest.com/*
// @match *://*.quora.com/*
// @match *://*.reddit.com/*
// @match *://*.reuters.com/*
// @match *://*.soundcloud.com/*
// @match *://*.tiktok.com/*
// @match *://*.twitch.tv/*
// @match *://*.deepl.com/*
// @match *://*.deviantart.com/*
// @match *://twitch.tv/*
// @match *://*.twitter.com/*
// @match *://*.x.com/*
// @match *://*.tumblr.com/*
// @match *://x.com/*
// @match *://*.wikipedia.org/*
// @match *://*.youtube-nocookie.com/*
// @match *://*.youtube.com/*
// @match *://f4.bcbits.com/*
// @match *://genius.com/*
// @match *://i.pinimg.com/*
// @match *://imgur.com/*
// @match *://instagram.com/*
// @match *://medium.com/*
// @match *://news.ycombinator.com/*
// @match *://reddit.com/*
// @match *://stackoverflow.com/*
// @match *://t4.bcbits.com/*
// @match *://translate.google.com/*
// @match *://twitter.com/*
// @match *://www.goodreads.com/*
// @match *://www.pixiv.net/*
// @match *://youtube.com/*
// @exclude *://*.youtube.com/redirect*
// @exclude *://youtube.com/redirect*
// @downloadURL https://update.greasyfork.org/scripts/436359/Privacy%20Redirector.user.js
// @updateURL https://update.greasyfork.org/scripts/436359/Privacy%20Redirector.meta.js
// @noframes
// ==/UserScript==
/*
___ _ _ ___ _____ _____
/ _ \| \ | | / _ \| ___| ___|
| | | | \| |_____| | | | |_ | |_
| |_| | |\ |_____| |_| | _| | _|
\___/|_| \_| \___/|_| |_|
CHANGE THE RELEVANT VALUE TO "false" TO
DISABLE THE REDIRECTION/FARSIDE FOR THAT
PARTICULAR PLATFORM */
// REDIRECTON / FARSIDE
let bandcamp = [true, true];
let deepl = [false, true]; // Mozhi Deepl engine doesn't work
let deviantart = [true, false];
let fandom = [true, true];
let genius = [true, true];
let goodreads = [true, false];
let google = [true, true];
let gtranslate = [true, true];
let hackernews = [true, true];
let imdb = [true, true];
let imgur = [true, false];
let instagram = [true, true];
let medium = [true, true];
let pinterest = [true, true];
let pixiv = [true, true];
let quora = [true, false];
let reddit = [true, false];
let reuters = [true, true];
let soundcloud = [true, true];
let stackoverflow = [true, true];
let tiktok = [true, false];
let tumblr = [true, false];
let twitch = [true, true];
let twitter = [true, true];
let wikipedia = [true, false];
let youtube = [true, true];
// PREFERRED FRONTEND
let youtubeFrontend = "invidious"; // accepts "invidious", "piped", "tubo", "freetube"
let youtubeMusicFrontend = "invidious"; // accepts "hyperpipe", "invidious", "piped"
let redditFrontend = "libreddit"; // accepts "libreddit", "teddit"
let googleFrontend = "searxng"; // accepts "librey", "searx", "searxng"
let googleTranslateFrontend = "mozhi"; // accepts "lingva" (farside available), "mozhi" (no farside)
let geniusFrontend = "intellectual"; // accepts dumb, intellectual
let mediumFrontend = "scribe"; // accepts libmedium, scribe, mediumrip
let hackernewsFrontend = "better"; // accepts better, worker
// OTHER SETTINGS
let keepHistory = false; // keeps farside.link in the browser history
// // // // // // // // // // // // //
/*
___ _
|_ _|_ __ ___| |_ __ _ _ __ ___ ___ ___
| || '_ \/ __| __/ _` | '_ \ / __/ _ \/ __|
| || | | \__ \ || (_| | | | | (_| __/\__ \
|___|_| |_|___/\__\__,_|_| |_|\___\___||___/
LIST OF INSTANCES TO USE IF FARSIDE IS NOT ENABLED
*/
const Instances = {
anonymousoverflow: [
"code.whatever.social",
"ao.vern.cc",
"overflow.smnz.de",
"overflow.lunar.icu",
"overflow.adminforge.de",
"overflow.projectsegfau.lt",
"ao.bloat.cat",
"overflow.ducks.party",
"ao.owo.si",
"overflow.freedit.eu",
"ao.rootdo.org",
"a.opnxng.com",
"overflow.einfachzocken.eu",
"exchange.seitan-ayoub.lol",
"overflow.r4fo.com",
],
hyperpipe: [
"hyperpipe.surge.sh",
"hyperpipe.onrender.com",
"music.adminforge.de",
"music.pfcd.me",
"hyperpipe.projectsegfau.lt",
"hp.ggtyler.dev",
"hyperpipe.lunar.icu",
"music.seitan-ayoub.lol",
],
proxigram: [
"proxigram.protokolla.fi",
"proxigram.kyun.li",
"proxigram.lunar.icu",
"ig.opnxng.com",
],
biblioreads: [
"biblioreads.eu.org",
"biblioreads.vercel.app",
"biblioreads.mooo.com",
"bl.vern.cc",
"biblioreads.lunar.icu",
"read.seitan-ayoub.lol",
],
binternet: [
"binternet.ahwx.org",
"bn.bloat.cat",
"bn.opnxng.com",
"bn.vern.cc",
],
breezewiki: [
"breezewiki.com",
"antifandom.com",
"breezewiki.pussthecat.org",
"bw.hamstro.dev",
"bw.projectsegfau.lt",
"breeze.hostux.net",
"bw.artemislena.eu",
"breezewiki.woodland.cafe",
"breeze.nohost.network",
"z.opnxng.com",
"breezewiki.catsarch.com",
"breeze.mint.lgbt",
"breezewiki.lunar.icu",
"fandom.adminforge.de",
],
dumb: [
"dumb.privacydev.net",
"db.vern.cc",
"sing.whatever.social",
"dumb.lunar.icu",
],
intellectual: [
"intellectual.insprill.net",
"in.bloat.cat",
"in2.bloat.cat",
"intellectual.lumaeris.com",
],
invidious: [
"inv.cochrun.xyz",
"yewtu.be",
// "vid.puffyan.us",
// "yt.artemislena.eu",
// "invidious.flokinet.to",
// "invidious.projectsegfau.lt",
// "invidious.privacydev.net",
// "iv.ggtyler.dev",
// "invidious.lunar.icu",
// "inv.tux.pizza",
// "invidious.protokolla.fi",
// "proxied.invidious.fi",
// "onion.tube",
// "invidious.no-logs.com",
// "invidious.io.lol",
// "iv.nboeck.de",
// "invidious.private.coffee",
// "invidious.asir.dev",
// "iv.datura.network",
// "invidious.perennialte.ch",
// "yt.cdaut.de",
// "invidious.einfachzocken.eu",
// "yt.drgnz.club",
],
piped: [
"piped.video",
"cf.piped.video",
"fl.piped.video",
"do.piped.video",
"az.piped.video",
"piped.mha.fi",
"watch.leptons.xyz",
"piped.lunar.icu",
"piped.r4fo.com",
"piped.privacydev.net",
"piped.smnz.de",
"piped.adminforge.de",
"piped.astartes.nl",
"piped.osphost.fi",
"pi.ggtyler.dev",
"piped.seitan-ayoub.lol",
"yt.owo.si",
"piped.minionflo.net",
],
libmedium: [
"libmedium.batsense.net",
"md.vern.cc",
"medium.hostux.net",
"libmedium.ducks.party",
],
libreddit: [
// "redditor.fly.dev",
"libreddit.kavin.rocks",
// "libreddit.northboot.xyz",
// "libreddit.kylrth.com",
// "libreddit.tiekoetter.com",
// "l.opnxng.com",
// "libreddit.projectsegfau.lt",
"libreddit.privacydev.net",
// "libreddit.freedit.eu",
// "libreddit.mha.fi",
// "lr.artemislena.eu",
// "libreddit.nohost.network",
// "libreddit.lunar.icu",
// "snoo.habedieeh.re",
// "libreddit.tux.pizza",
// "libreddit.perennialte.ch",
// "libreddit.private.coffee",
// "lr.seitan-ayoub.lol",
// "l.bloat.cat",
],
libremdb: [
"libremdb.iket.me",
"libremdb.pussthecat.org",
"ld.vern.cc",
"binge.whatever.social",
"libremdb.lunar.icu",
"libremdb.jeikobu.net",
"libremdb.nerdyfam.tech",
"libremdb.tux.pizza",
"d.opnxng.com",
"libremdb.catsarch.com",
],
librey: [
"search.ahwx.org",
"ly.owo.si",
"librey.danyaal.xyz",
"librey.org",
"search.davidovski.xyz",
"search.funami.tech",
"librex.nohost.network",
"search.pabloferreiro.es",
"librey.baczek.me",
"search.seitan-ayoub.lol",
],
lingva: [
"lingva.ml",
"lingva.thedaviddelta.com",
"lingva.retiolus.net",
"translate.plausibility.cloud",
"lingva.lunar.icu",
"lingva.garudalinux.org",
"lingva.seitan-ayoub.lol",
],
mediumrip: ["medium.rip"],
neuters: ["neuters.de", "nu.vern.cc"],
nitter: [
"nitter.net",
"nitter.unixfox.eu",
"nitter.poast.org",
"nitter.privacydev.net",
"nitter.projectsegfau.lt",
"nitter.soopy.moe",
"nitter.rawbit.ninja",
"nitter.freedit.eu",
"nitter.nohost.network",
"nitter.io.lol",
"nitter.woodland.cafe",
"nitter.perennialte.ch",
"nitter.salastil.com",
"n.opnxng.com",
"nitter.ktachibana.party",
],
pixivfe: [
"pixivfe.drgns.space",
"pixivfe.ducks.party",
"pixiv.perennialte.ch",
],
proxitok: [
"proxitok.pabloferreiro.es",
"proxitok.pussthecat.org",
"tok.habedieeh.re",
"proxitok.privacydev.net",
"tok.artemislena.eu",
"tok.adminforge.de",
"cringe.whatever.social",
"proxitok.lunar.icu",
"proxitok.privacy.com.de",
"cringe.seitan-ayoub.lol",
"tt.opnxng.com",
"tiktok.wpme.pl",
],
quetre: [
"quetre.iket.me",
"qr.vern.cc",
"quetre.pussthecat.org",
"quetre.privacydev.net",
"ask.habedieeh.re",
"quetre.blackdrgn.nl",
"quetre.lunar.icu",
"q.opnxng.com",
"quetre.rootdo.org",
"quora.seitan-ayoub.lol",
"ask.sudovanilla.org",
"quetre.smnz.de",
],
rimgo: [
"rimgo.totaldarkness.net",
"imgur.artemislena.eu",
"rimgo.lunar.icu",
"imgur.010032.xyz",
"rimgo.kling.gg",
"rimgo.projectsegfau.lt",
"rimgo.nohost.network",
"rimgo.catsarch.com",
"rimgo.quantenzitrone.eu",
],
scribe: [
"scribe.rip",
"scribe.citizen4.eu",
"scribe.nixnet.services",
"scribe.privacyredirect.com",
"scribe.projectsegfau.lt",
"scribe.rawbit.ninja",
"m.opnxng.com",
],
teddit: [
"i.opnxng.com",
"teddit.net",
"teddit.rawbit.ninja",
"teddit.pussthecat.org",
"teddit.zaggy.nl",
"t.sneed.network",
"td.vern.cc",
],
tent: ["tent.sny.sh", "tent.bloat.cat", "tn.vern.cc"],
tubo: ["tubo.media", "tubo.reallyaweso.me", "tubo.ducks.party"],
wikiless: [
"wikiless.tiekoetter.com",
"wikiless.funami.tech",
"wl.vern.cc",
"wiki.froth.zone",
"wikiless.northboot.xyz",
"wikiless.rawbit.ninja",
"wiki.adminforge.de",
"wikiless.rootdo.org",
"w.sneed.network",
"wikiless.r4fo.com",
"wiki.seitan-ayoub.lol",
"wikiless.ditatompel.com",
],
safetwitch: [
"safetwitch.drgns.space",
"safetwitch.projectsegfau.lt",
"safetwitch.datura.network",
"ttv.vern.cc",
"twitch.seitan-ayoub.lol",
"st.ggtyler.dev",
"safetwitch.lunar.icu",
"safetwitch.r4fo.com",
"safetwitch.ducks.party",
"safetwitch.nogafam.fr",
"safetwitch.privacyredirect.com",
],
searx: [
"searx.gnu.style",
"searx.nixnet.services",
"search.projectsegfau.lt",
"searx.roflcopter.fr",
"northboot.xyz",
"opnxng.com",
],
searxng: [
"search.tfcconnection.org",
// "search.sapti.me",
// "priv.au",
// "search.demoniak.ch",
// "www.gruble.de",
// "searx.divided-by-zero.eu",
// "xo.wtf",
// "freesearch.club",
// "baresearch.org",
// "searx.perennialte.ch",
// "searx.techsaviours.org",
// "search.mdosch.de",
// "searx.si",
// "searx.namejeff.xyz",
// "search.ononoki.org",
// "etsi.me",
// "searx.work",
// "search.smnz.de",
// "searx.prvcy.eu",
// "searx.headpat.exchange",
],
hackernews: {
better: "better-hackernews.vercel.app",
worker: "news.workers.tools",
},
mozhi: [
"mozhi.aryak.me",
"nyc1.mz.ggtyler.dev",
"translate.projectsegfau.lt",
"translate.nerdvpn.de",
"mozhi.ducks.party",
"mozhi.pussthecat.org",
"mozhi.adminforge.de",
"translate.privacyredirect.com",
"mozhi.canine.tools",
"mozhi.gitro.xyz",
],
skunkyart: [
"art.bloat.cat",
"skunky.bloat.cat",
"lost-skunk.cc/skunkyart",
"skunkyart.lumaeris.com",
],
priviblur: [
"pb.bloat.cat",
"tb.opnxng.com",
"priviblur.pussthecat.org",
"priviblur.thebunny.zone",
"priviblur.gitro.xyz",
"priviblur.canine.tools",
],
};
let farsideInstance = keepHistory ? "farside.link/_" : "farside.link";
// // // // // // // // // // // // //
const hash = window.location.hash,
scheme = `${window.location.protocol}//`;
let debug_mode = false;
if (debug_mode) {
alert(
"\n== DEBUG MODE IS ON ==" +
"\nIf you're seeing this" +
"\nset the debug_mode value to" +
"\nfalse for Privacy Redirector." +
"\n======================" +
"\n\nHostname: " +
window.location.hostname +
"\nPath: " +
window.location.pathname +
"\nQuery: " +
window.location.search +
"\nHash: " +
hash,
);
}
let selectedInstance = "",
newURL = "";
const getrandom = async (instances) =>
instances[Math.floor(Math.random() * instances.length)];
async function redirectInstagram() {
if (instagram[0]) {
window.stop();
let pathname = window.location.pathname;
let search = window.location.search;
let params = new URLSearchParams(search);
selectedInstance = await getrandom(Instances.proxigram);
switch (true) {
case pathname.startsWith("/accounts/login/"):
case pathname.startsWith("/accounts/signup/"):
pathname = pathname.replace(/^\/accounts\/(login|signup)\/[a-z]*/, "");
params.delete("next");
search = params.size ? `?${params}` : "";
break;
case pathname.startsWith("/reel/"):
case pathname.startsWith("/tv/"):
pathname = pathname.replace(/^\/(reel|tv)\//, "/p/");
break;
case pathname.endsWith("/reels/"):
pathname = pathname.replace("/reels", "");
break;
}
newURL = `${scheme}${selectedInstance}${pathname}${search}${hash}`;
window.location.replace(newURL);
}
}
async function redirectTwitter() {
if (twitter[0]) {
window.stop();
const pathname = window.location.pathname;
let searchpath = `${pathname}${window.location.search}`;
selectedInstance = twitter[1]
? `${farsideInstance}/nitter`
: await getrandom(Instances.nitter);
if (pathname === "/i/flow/login")
searchpath = searchpath.replace(
"/i/flow/login?redirect_after_login=",
"",
);
if (searchpath.includes("%")) searchpath = decodeURIComponent(searchpath);
newURL = `${scheme}${selectedInstance}${searchpath}${hash}`;
window.location.replace(newURL);
}
}
async function redirectReddit() {
if (reddit[0] && !window.location.pathname.startsWith("/domain")) {
window.stop();
let pathname = window.location.pathname;
let search = window.location.search;
selectedInstance = reddit[1]
? `${farsideInstance}/${redditFrontend}`
: await getrandom(Instances[redditFrontend]);
if (pathname === "/media" && search) {
const params = new URLSearchParams(search);
const mediaURL = new URL(params.get("url"));
if (["i.redd.it", "preview.redd.it"].includes(mediaURL.hostname)) {
pathname = `/img${mediaURL.pathname}`;
search = mediaURL.search;
}
}
newURL = `${scheme}${selectedInstance}${pathname}${search}${hash}`;
window.location.replace(newURL);
}
}
async function redirectYoutube(frontend) {
if (youtube[0]) {
window.stop();
let searchpath = `${window.location.pathname}${window.location.search}`;
if (window.location.pathname.startsWith("/embed")) {
// selectedInstance = youtube[1]
// ? `${farsideInstance}/invidious`
// : await getrandom(Instances["invidious"]);
newURL = `${scheme}inv.cochrun.xyz${window.location.pathname}${
window.location.search
}${hash}`;
window.location.replace(newURL);
} else {
if (frontend === "tubo") {
// selectedInstance = await getrandom(Instances.tubo);
searchpath = `/stream?url=${window.location.href}`;
if (
window.location.pathname.startsWith("/@") ||
window.location.pathname.startsWith("/channel")
)
searchpath = `/channel?url=${window.location.href}`;
} else if (frontend === "freetube") {
let youtube_link = window.location.href;
window.location.replace(`freetube://${youtube_link}`);
return;
} else {
// selectedInstance =
// youtube[1] && frontend !== "hyperpipe"
// ? `${farsideInstance}/${frontend}`
// : await getrandom(Instances[frontend]);
}
newURL = `${scheme}inv.cochrun.xyz${searchpath}${hash}`;
window.location.replace(newURL);
}
}
}
async function redirectTiktok() {
if (tiktok[0]) {
window.stop();
let pathname = window.location.pathname;
selectedInstance = tiktok[1]
? `${farsideInstance}/proxitok`
: await getrandom(Instances.proxitok);
await Promise.any(
[
["/@/", "/@placeholder/"],
["/discover/", "/tag/"],
["/foryou", "/trending"],
].map(async ([key, value]) => {
if (pathname.startsWith(key)) pathname = pathname.replace(key, value);
}),
);
newURL = `${scheme}${selectedInstance}${pathname}${window.location.search}${
hash
}`;
window.location.replace(newURL);
}
}
async function redirectImgur() {
if (imgur[0]) {
window.stop();
selectedInstance = imgur[1]
? `${farsideInstance}/rimgo`
: await getrandom(Instances.rimgo);
newURL = `${scheme}${selectedInstance}${window.location.pathname}${
window.location.search
}${hash}`;
window.location.replace(newURL);
}
}
async function redirectMedium(frontend) {
if (medium[0]) {
let pathname = window.location.pathname;
const host_path = `${window.location.hostname}${pathname}`;
if (
(/^.+?\.medium\.com\/.+/.test(host_path) ||
/^\/@?[^\/]+?\//.test(pathname) ||
host_path === "medium.com/") &&
!(
/^\/(tag|m|hc)\//.test(pathname) ||
/\/(about|followers|following)/.test(pathname)
)
) {
window.stop();
selectedInstance =
medium[1] && frontend === "scribe"
? `${farsideInstance}/scribe`
: await getrandom(Instances[frontend]);
const username = window.location.hostname.replace(/\.?medium\.com/, "");
if (username) pathname = `/${username}${pathname}`;
newURL = `${scheme}${selectedInstance}${pathname}${
window.location.search
}${hash}`;
window.location.replace(newURL);
}
}
}
async function redirectHackerNews() {
if (hackernews[0]) {
let pathname = window.location.pathname;
if (
["/newest", "/item", "/user", "/ask", "/show", "/jobs", "/"].includes(
pathname,
)
) {
if (
hackernewsFrontend === "better" &&
window.location.pathname === "/newest"
)
pathname = "/new";
selectedInstance = Instances.hackernews[hackernewsFrontend];
} else if (
["/best", "/news", "/submitted", "/threads", "/classic"].includes(
pathname,
)
) {
selectedInstance = Instances.hackernews.worker;
}
if (selectedInstance) {
window.stop();
newURL = `${scheme}${selectedInstance}${pathname}${window.location.search}`;
window.location.replace(newURL);
}
}
}
async function redirectGTranslate() {
if (gtranslate[0]) {
window.stop();
let pathname = window.location.pathname;
switch (googleTranslateFrontend) {
case "lingva":
selectedInstance = gtranslate[1]
? `${farsideInstance}/lingva`
: await getrandom(Instances.lingva);
if (window.location.search) {
const params = new URLSearchParams(window.location.search);
pathname = `/${params.get("sl")}/${params.get("tl")}/${params.get(
"text",
)}`;
} else if (/^\/\w+?\/\w+?\/.*/.test(pathname)) {
pathname = pathname.replace(/\+/g, " ");
}
newURL = `${scheme}${selectedInstance}${pathname}`;
break;
case "mozhi":
selectedInstance = await getrandom(Instances.mozhi);
if (window.location.search) {
const params = new URLSearchParams(window.location.search);
pathname = `?text=${params.get(
"text",
)}&from=${params.get("sl")}&to=${params.get("tl")}&engine=google`;
newURL = `${scheme}${selectedInstance}${pathname}`;
} else {
newURL = `${scheme}${selectedInstance}`;
}
break;
default:
break;
}
window.location.replace(newURL);
}
}
async function redirectDeviantart() {
window.stop();
let pathname = window.location.pathname;
let query = window.location.search;
let parts = pathname.split("/").filter((n) => n);
let pathnameMatch = "";
selectedInstance = await getrandom(Instances.skunkyart);
let patterns = {
post: /\/art\/\S+/,
tag: /\/tag\/\S+/,
search: /(?<=\?q=)[^&]+/,
gallery: /\/\w+\/gallery$/,
gallery_folder: /\/\w+\/gallery\/\d+/,
favorites: /\/(\w+)\/favourites/,
profile: /^\/(\w+)$/,
};
if (deviantart[0]) {
if (patterns.post.test(pathname)) {
pathnameMatch = `/post/${parts[0].toLowerCase()}/${parts[2]}`;
} else if (patterns.tag.test(pathname)) {
pathnameMatch = `/search?q=${parts[1]}&type=tag`;
} else if (pathname.startsWith("/search")) {
query = query.match(patterns.search)[0];
pathnameMatch = `/search?q=${query}&type=all`;
} else if (patterns.gallery.test(pathname)) {
pathnameMatch = `/group_user?type=gallery&q=${parts[0]}`;
} else if (patterns.gallery_folder.test(pathname)) {
pathnameMatch = `/group_user?folder=${parts[2]}&q=${parts[0]}&type=g`;
} else if (patterns.favorites.test(pathname)) {
pathnameMatch = `/group_user?q=${pathname.match(patterns.favorites)[1]}&type=favorites`;
} else if (patterns.profile.test(pathname)) {
pathnameMatch = `/group_user?type=about&q=${pathname.match(patterns.profile)[1]}`;
}
}
newURL = `${scheme}${selectedInstance}${pathnameMatch}`;
window.location.replace(newURL);
}
async function redirectDeepl() {
if (deepl[0]) {
window.stop();
selectedInstance = await getrandom(Instances.mozhi);
if (window.location.hash) {
let hash_parts = window.location.hash.substring(1).split("/");
let pathname = `?text=${hash_parts[2]}&from=${hash_parts[0]}&to=${
hash_parts[1]
}&engine=deepl`;
newURL = `${scheme}${selectedInstance}${pathname}`;
}
window.location.replace(newURL);
}
}
async function redirectTumblr() {
if (tumblr[0]) {
window.stop();
selectedInstance = await getrandom(Instances.priviblur);
newURL = `${scheme}${selectedInstance}${window.location.pathname}${
window.location.search
}${hash}`;
window.location.replace(newURL);
}
}
async function redirectReuters() {
if (reuters[0]) {
window.stop();
selectedInstance = await getrandom(Instances.neuters);
newURL = `${scheme}${selectedInstance}${window.location.pathname}${
window.location.search
}${hash}`;
window.location.replace(newURL);
}
}
async function redirectWikipedia() {
if (wikipedia[0]) {
window.stop();
let langCode = /^([a-z\-]+)\./.exec(window.location.hostname)[1];
selectedInstance = wikipedia[1]
? `${farsideInstance}/wikiless`
: await getrandom(Instances.wikiless);
if (langCode === "www") langCode = "en";
newURL = `${scheme}${selectedInstance}${window.location.pathname}?lang=${
langCode
}${hash}`;
window.location.replace(newURL);
}
}
async function redirectImdb() {
if (imdb[0]) {
window.stop();
selectedInstance = imdb[1]
? `${farsideInstance}/libremdb`
: await getrandom(Instances.libremdb);
newURL = `${scheme}${selectedInstance}${window.location.pathname}${
window.location.search
}${hash}`;
window.location.replace(newURL);
}
}
async function redirectQuora() {
if (quora[0]) {
window.stop();
selectedInstance = quora[1]
? `${farsideInstance}/quetre`
: await getrandom(Instances.quetre);
newURL = `${scheme}${selectedInstance}${window.location.pathname}${
window.location.search
}${hash}`;
window.location.replace(newURL);
}
}
async function redirectFandom() {
if (fandom[0]) {
window.stop();
const fandomName = window.location.hostname.replace(/\..+/, "");
selectedInstance = await getrandom(Instances.breezewiki);
let pathname = window.location.pathname;
if (fandomName !== "www") pathname = `/${fandomName}${pathname}`;
newURL = `${scheme}${selectedInstance}${pathname}${window.location.search}${
hash
}`;
window.location.replace(newURL);
}
}
async function redirectGoogle() {
if (
google[0] &&
window.location.hostname.startsWith("www") &&
window.location.pathname.startsWith("/search")
) {
window.stop();
selectedInstance = google[1]
? `${farsideInstance}/${googleFrontend}`
: (selectedInstance = await getrandom(Instances[googleFrontend]));
let pathname = window.location.pathname;
if (googleFrontend === "librey" && pathname === "/search")
pathname += ".php";
const params = new URLSearchParams(window.location.search);
const query = params.entries().q;
const search = query ? `?q=${query}` : window.location.search;
newURL = `${scheme}${selectedInstance}${pathname}${search}${hash}`;
window.location.replace(newURL);
}
}
async function redirectGoodreads() {
if (goodreads[0]) {
window.stop();
selectedInstance = await getrandom(Instances.biblioreads);
if (window.location.pathname.startsWith("/search")) {
const params = new URLSearchParams(search);
search = `/${params.get("q")}`;
}
newURL = `${scheme}${selectedInstance}${window.location.pathname}${search}${
hash
}`;
window.location.replace(newURL);
}
}
async function redirectStackoverflow() {
if (
stackoverflow[0] &&
(window.location.pathname.startsWith("/questions/") ||
window.location.pathname === "/")
) {
window.stop();
selectedInstance = stackoverflow[1]
? `${farsideInstance}/anonymousoverflow`
: await getrandom(Instances.anonymousoverflow);
newURL = `${scheme}${selectedInstance}${window.location.pathname}${
window.location.search
}${hash}`;
window.location.replace(newURL);
}
}
async function redirectBandcamp() {
if (bandcamp[0]) {
// thanks to libredirect
selectedInstance = await getrandom(Instances.tent);
const params = new URLSearchParams(window.location.search);
const artist = window.location.hostname.replace(/\..+/, "");
const regex = /^\/([^\/]+?)\/(.+)/.exec(window.location.pathname);
const audio = /^\/stream\/([a-f0-9]+?)\/([^\/]+?)\/([0-9]+)/.exec(
window.location.pathname,
);
const image = /^\/img\/(.+)/.exec(window.location.pathname);
let searchpath = "";
switch (true) {
case window.location.pathname === "/search":
searchpath = `/search.php?query=${params.get("q")}`;
break;
case window.location.hostname.search(/(daily)?\.bandcamp\.com/) > 0:
if (window.location.pathname === "/") {
searchpath = `/artist.php?name=${artist}`;
} else if (regex.length > 2) {
searchpath = `/release.php?artist=${artist}&type=${regex[1]}&name=${regex[2]}`;
}
break;
case window.location.hostname === "f4.bcbits.com":
if (image.length > 1) searchpath = `/image.php?file=${image[1]}`;
break;
case window.location.hostname === "t4.bcbits.com":
if (audio.length > 3)
searchpath = `/audio.php?directory=${audio[1]}&format=${
audio[2]
}&file=${audio[3]}&token=${params.get("token")}`;
break;
default:
return;
}
window.stop();
newURL = `${scheme}${selectedInstance}${searchpath}`;
window.location.replace(newURL);
}
}
async function redirectGenius() {
if (genius[0]) {
const pathname = window.location.pathname;
selectedInstance = await getrandom(Instances[geniusFrontend]);
await Promise.any(
[
["lyrics", pathname.endsWith("-lyrics")],
["album", pathname.startsWith("/albums/")],
["artist", pathname.startsWith("/artists/")],
[, ["/", "/search"].includes(pathname)],
].map(async ([key, value]) => {
if (value) {
const searchpath =
geniusFrontend === "intellectual" && key
? `/${key}?path=${pathname.slice(1)}`
: `${pathname}${window.location.search}`;
window.stop();
newURL = `${scheme}${selectedInstance}${searchpath}${hash}`;
window.location.replace(newURL);
}
}),
);
}
}
async function redirectPinterest() {
if (pinterest[0]) {
selectedInstance = await getrandom(Instances.binternet);
let searchpath = "";
if (window.location.hostname === "i.pinimg.com") {
searchpath = `/image_proxy.php?url=${window.location.href}`;
} else if (window.location.pathname.startsWith("/search")) {
searchpath = `${window.location.pathname
.replace("search", "search.php")
.replace("/pins/", "")}${window.location.search}`;
} else if (window.location.pathname !== "/") return;
window.stop();
newURL = `${scheme}${selectedInstance}${searchpath}`;
window.location.replace(newURL);
}
}
async function redirectSoundcloud() {
if (soundcloud[0]) {
window.stop();
selectedInstance = await getrandom(Instances.tubo);
let searchpath = "/kiosk?serviceId=1";
if (window.location.pathname !== "/")
searchpath = `/stream?url=${window.location.href}`;
newURL = `${scheme}${selectedInstance}${searchpath}`;
window.location.replace(newURL);
}
}
async function redirectPixiv() {
if (pixiv[0]) {
window.stop();
selectedInstance = await getrandom(Instances.pixivfe);
const pathname = window.location.pathname.replace(/^\/\w{2}\//, "/");
newURL = `${scheme}${selectedInstance}${pathname}${window.location.search}`;
window.location.replace(newURL);
}
}
async function redirectTwitch() {
if (twitch[0]) {
window.stop();
selectedInstance = await getrandom(Instances.safetwitch);
const pathname =
window.location.pathname == "/search"
? window.location.pathname + "/"
: window.location.pathname;
let searchpath =
window.location.pathname == "/search"
? window.location.search.replace("term", "query")
: window.location.search;
newURL = `${scheme}${selectedInstance}${pathname}${searchpath}`;
window.location.replace(newURL);
}
}
const urlHostname = window.location.hostname;
switch (urlHostname) {
case "www.instagram.com":
redirectInstagram();
break;
case "twitter.com":
case "mobile.twitter.com":
case "x.com":
case "mobile.x.com":
redirectTwitter();
break;
case "www.youtube.com":
case "m.youtube.com":
case "www.youtube-nocookie.com":
redirectYoutube(youtubeFrontend);
break;
case "www.tiktok.com":
redirectTiktok();
break;
case "music.youtube.com":
redirectYoutube(youtubeMusicFrontend);
break;
case "news.ycombinator.com":
redirectHackerNews();
break;
case "translate.google.com":
redirectGTranslate();
break;
case "www.reuters.com":
redirectReuters();
break;
case "www.imdb.com":
case "m.imdb.com":
redirectImdb();
break;
case "www.quora.com":
redirectQuora();
break;
case "www.google.com":
redirectGoogle();
break;
case "www.goodreads.com":
redirectGoodreads();
break;
case "genius.com":
redirectGenius();
break;
case "stackoverflow.com":
redirectStackoverflow();
break;
case "f4.bcbits.com":
case "t4.bcbits.com":
redirectBandcamp();
break;
case "www.deviantart.com":
redirectDeviantart();
break;
case "i.pinimg.com":
redirectPinterest();
break;
case "soundcloud.com":
case "m.soundcloud.com":
redirectSoundcloud();
break;
case "www.pixiv.net":
redirectPixiv();
break;
case "www.deepl.com":
redirectDeepl();
break;
case "twitch.tv":
case "www.twitch.tv":
redirectTwitch();
break;
case urlHostname.includes("reddit.com") ? urlHostname : 0:
redirectReddit();
break;
case urlHostname.includes("medium.com") ? urlHostname : 0:
redirectMedium(mediumFrontend);
break;
case urlHostname.includes("imgur.com") ? urlHostname : 0:
case urlHostname.includes("imgur.io") ? urlHostname : 0:
redirectImgur();
break;
case urlHostname.includes("wikipedia.org") ? urlHostname : 0:
redirectWikipedia();
break;
case urlHostname.includes("fandom.com") ? urlHostname : 0:
redirectFandom();
break;
case urlHostname.includes("bandcamp.com") ? urlHostname : 0:
redirectBandcamp();
break;
case urlHostname.includes("pinterest.com") ? urlHostname : 0:
redirectPinterest();
break;
case urlHostname.includes("tumblr.com") ? urlHostname : 0:
redirectTumblr();
break;
}
// export module for the test in github action
typeof module !== "undefined"
? (module.exports = { Instances: Instances })
: true;