Merge branch 'master' into patch-3

This commit is contained in:
Edward 2022-10-09 19:04:15 +05:30 committed by GitHub
commit 26abc5d2c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
127 changed files with 6660 additions and 13104 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ web-ext-artifacts/
nod
node_modules
package-lock.json
.vscode

View File

@ -6,18 +6,16 @@ pipeline:
event: cron
commands:
- python -m pip install --upgrade pip
- pip install requests bs4 colorama
- pip install requests colorama
- python src/instances/get_instances.py
# SSH configuration
- mkdir ~/.ssh
- ssh-keyscan -t ed25519 codeberg.org >> ~/.ssh/known_hosts
- eval `ssh-agent`
- echo "$TOKEN" | tr -d '\r' | ssh-add -
# Git configuration
- git config --global user.email $MAIL
- git config --global user.name "Woodpecker CI"
- git commit -am "updated instances"
- mkdir ~/.ssh
- ssh-keyscan -t ed25519 codeberg.org >> ~/.ssh/known_hosts
- git remote set-url origin git@codeberg.org:libredirect/libredirect.git
#- echo $TOKEN > key
#- chmod 0600 key
- eval `ssh-agent`
- echo "$TOKEN" | tr -d '\r' | ssh-add -
#- ssh-add key
- git push --set-upstream origin master

View File

@ -2,7 +2,7 @@
A web extension that redirects YouTube, Twitter, Instagram... requests to alternative privacy friendly frontends and backends.
[![Matrix Badge](https://img.shields.io/matrix/libredirect:matrix.org?label=matrix%20chat)](https://matrix.to/#/#libredirect-space:matrix.org)
[![Matrix Badge](https://img.shields.io/matrix/libredirect:matrix.org?label=matrix%20chat)](https://matrix.to/#/#libredirect:matrix.org)
[![Firefox users Badge](https://img.shields.io/amo/users/libredirect?label=Firefox%20users)](https://addons.mozilla.org/firefox/addon/libredirect/)
[![LibrePay Badge](https://img.shields.io/liberapay/gives/libredirect?label=Liberapay)](https://liberapay.com/LibRedirect)
@ -26,7 +26,7 @@ Imgur => [Rimgo](https://codeberg.org/video-prize-ranch/rimgo)\
Wikipedia => [Wikiless](https://codeberg.org/orenom/wikiless)\
Medium => [Scribe](https://sr.ht/~edwardloveall/scribe/)\
Quora => [Quetre](https://github.com/zyachel/quetre)\
IMDb => [Libremdb](https://github.com/zyachel/libremdb)\
IMDb => [libremdb](https://github.com/zyachel/libremdb)\
PeerTube => [SimpleerTube](https://git.sr.ht/~metalune/simpleweb_peertube)\
LBRY/Odysee => [Librarian](https://codeberg.org/librarian/librarian), [LBRY Desktop](https://lbry.com/get)\
Search => [SearXNG](https://github.com/searxng/searxng), [SearX](https://searx.github.io/searx/), [Whoogle](https://benbusby.com/projects/whoogle-search/), [LibreX](https://github.com/hnhx/librex/)\
@ -36,13 +36,14 @@ Send Files => [Send](https://gitlab.com/timvisee/send)
**Note**: The Extension will be using random instances by default. You can modify this and add custom instances too.
# Please read the [FAQ](https://libredirect.github.io/faq.html) if you have any questions!
# Please read the [FAQ](https://libredirect.codeberg.page/faq.html) if you have any questions!
## Donate
[![Liberapay](./img/liberapay.svg)](https://liberapay.com/LibRedirect) 
[![Patreon](./img/patreon.svg)](https://patreon.com/LibRedirect) 
[![Buy me a coffee](./img/bmc.svg)](https://www.buymeacoffee.com/libredirect)
[![Buy me a coffee](./img/bmc.svg)](https://www.buymeacoffee.com/libredirect) 
<a href="https://opencollective.com/libredirect"><img src = ./img/Open-Collective.png width=17% height=17%></a>
BTC: bc1qrhue0frps6p2vkg978u9ayethnwprtmfug827q\
BCH: qqz5vfnrngk0tjy73q2688qzw4wnllnuzqfndflhl8\
@ -51,8 +52,9 @@ XMR: 4AM5CVfaGsnEXQQjZSzJvaWufe7pT86ubcZPr83fCjb2Hn3iwcForTWFy2Z3ugXcufUwHaGcucf
## Mirror Repos
[![GitHub](https://raw.githubusercontent.com/ManeraKai/manerakai/main/icons/github.svg)](https://github.com/libredirect/libredirect/)&nbsp;&nbsp;
[![Codeberg](https://raw.githubusercontent.com/ManeraKai/manerakai/main/icons/codeberg.svg)](https://codeberg.org/LibRedirect/libredirect)&nbsp;&nbsp;
[![GitHub](https://raw.githubusercontent.com/ManeraKai/manerakai/main/icons/github.svg)](https://github.com/libredirect/libredirect/)&nbsp;&nbsp;
## Translate
@ -69,21 +71,19 @@ npm update
npm install
```
If you are modifying any files ending with .pug, the pug cli needs to be installed with the following command (with root privileges):
If you are modifying `config.json` or any files ending with .ejs, you need to run the following command to render html:
```
npm install -g pug-cli
npm run ejs
```
and then run `npm run pug` to generate pages in the background.
### Build
### Build the extention zip archive:
```
npm run build
```
### Test
### Run automated tests
```
npm run test
@ -117,4 +117,4 @@ select `load unpacked extension`\
select `src` folder
[Privacy Policy](Privacy-Policy.md)\
Credits: [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect)
Forked from [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect)

BIN
img/Open-Collective.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -9,23 +9,22 @@
"start": "web-ext run --browser-console --source-dir ./src/",
"build": "web-ext build --overwrite-dest --source-dir ./src/",
"test": "web-ext lint --source-dir ./src/ || true",
"pug": "pug ./src/pages/options/*.pug ./src/pages/popup/ -P -w",
"prettier": "npx prettier --write .",
"instances": "python3 src/instances/get_instances.py; git update-index --assume-unchanged src/instances/blacklist.json src/instances/data.json"
"instances": "python3 src/instances/get_instances.py; git update-index --assume-unchanged src/instances/blacklist.json src/instances/data.json",
"ejs": "npx ejs src/pages/options/index.ejs -f src/config/config.json -o src/pages/options/index.html; npx ejs src/pages/popup/popup.ejs -f src/config/config.json -o src/pages/popup/popup.html"
},
"repository": {
"type": "git",
"url": "git+https://github.com/LibRedirect/LibRedirect.git"
"url": "git+https://codeberg.org/LibRedirect/LibRedirect.git"
},
"author": "LibRedirect",
"license": "GPL-3.0-only",
"bugs": {
"url": "https://github.com/LibRedirect/LibRedirect/issues"
"url": "https://codeberg.org/LibRedirect/LibRedirect/issues"
},
"homepage": "https://libredirect.github.io",
"homepage": "https://libredirect.codeberg.page",
"devDependencies": {
"prettier": "2.7.1",
"web-ext": "^6.7.0"
"web-ext": "^7.2.0"
},
"dependencies": {
"buffer": "^6.0.3",

View File

@ -210,5 +210,13 @@
},
"lbryDesktop": {
"message": "LBRY Desktop"
},
"toggleTab": {
"message": "Toggle redirects in this tab",
"description": "Used in context menus when right clicking on a page/tab"
},
"redirectLink": {
"message": "Attempt to redirect this hyperlink",
"description": "Used in context menus when right clicking on a hyperlink"
}
}

View File

@ -1,12 +1,4 @@
import requests
import json
from urllib.parse import urlparse
from bs4 import BeautifulSoup
import re
from colorama import Fore, Back, Style
from urllib.parse import urlparse
import socket
import subprocess
ar_json = {}

View File

@ -1,4 +1,4 @@
{
"youtube": {
"message": "YouTube",
"description": "Utilizado na página de configurações"
@ -18,8 +18,9 @@
"message": "Twitter",
"description": "Utilizado na página de configurações"
},
"i2p": {
"message": "I2P"
"extensionDescription": {
"message": "Uma extensão para os navegadores de internet que redireciona os sítios/sites populares para interfaces gráficas e interfaces de textos alternativos e amigáveis ​​à sua privacidade",
"description": "Descrição da extensão"
},
"switchInstance": {
"message": "Trocar a Instância",
@ -49,6 +50,18 @@
"message": "Enviar Arquivos",
"description": "Utilizado na página de configurações"
},
"youtube": {
"message": "YouTube",
"description": "Utilizado na página de configurações"
},
"instagram": {
"message": "Instagram",
"description": "Utilizado na página de configurações"
},
"twitter": {
"message": "Twitter",
"description": "Utilizado na página de configurações"
},
"reddit": {
"message": "Reddit",
"description": "Utilizado na página de configurações"
@ -198,6 +211,9 @@
"copied": {
"message": "Copiado"
},
"unifySettings": {
"message": "Unificar as Configurações"
},
"lbry": {
"message": "LBRY"
},
@ -208,8 +224,7 @@
"message": "Uma extensão para os navegadores de internet que redireciona os sítios/sites populares para interfaces gráficas e interfaces de textos alternativas e amigáveis que respeitam sua privacidade",
"description": "Descrição da Extensão"
},
"instagram": {
"message": "Instagram",
"description": "Utilizado na página de configurações"
"protocolFallback": {
"message": "Retornar ao normal se não houver outras instâncias disponíveis para o protocolo atual"
}
}

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" fill="currentColor">
<path d="M11 17h2v-6h-2Zm1-8q.425 0 .713-.288Q13 8.425 13 8t-.287-.713Q12.425 7 12 7t-.712.287Q11 7.575 11 8t.288.712Q11.575 9 12 9Zm0 13q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Zm0-2q3.35 0 5.675-2.325Q20 15.35 20 12q0-3.35-2.325-5.675Q15.35 4 12 4 8.65 4 6.325 6.325 4 8.65 4 12q0 3a.35 2.325 5.675Q8.65 20 12 20Zm0-8Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 665 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="wds-brand-fandom-logomark" viewBox="0 0 174 242"><path fill="#FA005A" d="M166.935 118.154L50.108 1.273C49.504.67 48.735.259 47.898.093c-.837-.166-1.705-.08-2.493.247-.788.327-1.461.88-1.935 1.59-.474.71-.727 1.546-.727 2.4v98.276L7.365 67.22c-.604-.604-1.373-1.014-2.21-1.18-.837-.166-1.704-.08-2.492.247-.789.327-1.462.88-1.936 1.59-.474.71-.727 1.545-.727 2.4v101.487c-.003 3.172.62 6.312 1.833 9.242 1.214 2.929 2.993 5.59 5.237 7.83l46.037 46.099c4.528 4.53 10.666 7.078 17.068 7.085h33.68c6.4-.003 12.537-2.547 17.063-7.075l46.027-46.099c2.239-2.242 4.014-4.904 5.225-7.833 1.21-2.93 1.832-6.069 1.83-9.239v-36.533c.002-3.173-.621-6.315-1.834-9.247-1.212-2.932-2.989-5.596-5.231-7.84z"/><path fill="#FFC500" d="M131.297 160.901c.001 1.915-.757 3.754-2.108 5.111l-37.11 37.3c-.672.677-1.472 1.215-2.354 1.582-.88.366-1.826.555-2.78.555-.954 0-1.9-.189-2.78-.555-.882-.367-1.682-.905-2.355-1.582l-36.99-37.3c-1.352-1.351-2.114-3.184-2.117-5.096v-14.191c0-.951.19-1.892.554-2.77.366-.878.9-1.675 1.574-2.346l13.317-13.328c.672-.675 1.47-1.209 2.35-1.574.879-.365 1.82-.553 2.772-.553.952 0 1.894.188 2.773.553.879.365 1.677.899 2.35 1.574l18.624 18.645 18.596-18.65c.672-.675 1.47-1.209 2.349-1.574.879-.365 1.821-.553 2.773-.553.951 0 1.893.188 2.772.553.879.365 1.677.899 2.349 1.574l13.318 13.328c.673.671 1.207 1.469 1.571 2.347.364.877.552 1.819.552 2.769v14.181z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="26px" viewBox="0 0 24 24" width="26px" fill="currentColor">
<path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="26px" viewBox="0 0 24 24" width="26px" fill="currentColor">
<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"></path>
</svg>

After

Width:  |  Height:  |  Size: 979 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM10 5.47l4 1.4v11.66l-4-1.4V5.47zm-5 .99l3-1.01v11.7l-3 1.16V6.46zm14 11.08l-3 1.01V6.86l3-1.16v11.84z"></path>
</svg>

After

Width:  |  Height:  |  Size: 391 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1770 1000" fill="currentColor">
<circle cx="500" cy="500" r="500"></circle>
<ellipse ry="475" rx="250" cy="501" cx="1296"></ellipse>
<ellipse cx="1682" cy="502" rx="88" ry="424"></ellipse>
</svg>

After

Width:  |  Height:  |  Size: 255 B

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>

After

Width:  |  Height:  |  Size: 343 B

View File

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="33.866665mm"
height="33.866665mm"
viewBox="0 0 33.866665 33.866665"
version="1.1"
id="svg898"
sodipodi:docname="send-icon.svg"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7" />
<sodipodi:namedview
id="namedview5"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.6623698"
inkscape:cx="46.950653"
inkscape:cy="88.079425"
inkscape:window-width="1888"
inkscape:window-height="1060"
inkscape:window-x="32"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg898" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.17791"
id="path1168"
cx="16.933332"
cy="16.933332"
r="16.933332" />
<g
id="layer1"
transform="matrix(0.36395732,0,0,0.36395732,5.286709,5.2870656)">
<path
id="cloud-upload"
d="m 64,34.286 a 17.033,17.033 0 0 1 -4.406,11.428 14.857,14.857 0 0 1 -10.558,4.572 h -2.179 v -6.857 h 2.179 a 8.004,8.004 0 0 0 5.468,-2.31 10.184,10.184 0 0 0 2.639,-6.833 11.442,11.442 0 0 0 -11.429,-11.429 c -0.377,0 -2.312,0.242 -3.49,0.394 A 1.136,1.136 0 0 1 41.003,22.487 L 40.537,21.13 A 14.103,14.103 0 0 0 28.821,11.498 13.666,13.666 0 0 0 14.091,28.277 l 0.489,2.087 a 1.143,1.143 0 0 1 -0.783,1.355 l -2.054,0.62 a 6.794,6.794 0 0 0 -4.886,6.518 4.604,4.604 0 0 0 0.947,2.808 5.539,5.539 0 0 0 4.089,1.764 h 5.25 v 6.857 h -5.25 A 12.236,12.236 0 0 1 2.213,45.634 11.506,11.506 0 0 1 0,38.857 13.573,13.573 0 0 1 6.944,26.973 19.51,19.51 0 0 1 6.857,25.143 20.563,20.563 0 0 1 45.844,16 18.307,18.307 0 0 1 64,34.286 Z M 32.923,32.123 a 1.143,1.143 0 0 0 -1.846,0 l -8.592,11.775 a 1.143,1.143 0 0 0 0.923,1.816 h 5.163 v 12.572 a 1.143,1.143 0 0 0 1.143,1.143 h 4.572 a 1.143,1.143 0 0 0 1.143,-1.143 V 45.714 h 5.163 a 1.143,1.143 0 0 0 0.923,-1.816 z"
stroke-width="2.286"
fill="#45a1ff"
fill-opacity="1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"></path>
</svg>

After

Width:  |  Height:  |  Size: 316 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"></path>
</svg>

After

Width:  |  Height:  |  Size: 432 B

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,143 +0,0 @@
class FrontEnd {
constructor({ enable, frontends, frontend, redirect }) {
this.redirects = {}
this.enable = enable
this.frontend = frontend
this.protocol = "normal"
this.protocolFallback = true
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
data = JSON.parse(data)
fetch("/instances/blacklist.json")
.then(response => response.text())
.then(async blackList => {
blackList = JSON.parse(blackList)
for (const frontend in frontends) {
this.redirects[frontend] = {}
this.redirects[frontend].cookies = [...frontends[frontend].cookies]
for (const protocol in data[frontend]) {
this.redirects[frontend][protocol] = {}
this.redirects[frontend][protocol].all = [...data[frontend][protocol]]
this.redirects[frontend][protocol].custom = []
this.redirects[frontend][protocol].checked = [...data[frontend][protocol]]
for (const instance of blackList.cloudflare) {
const a = this.redirects[frontend][protocol].checked.indexOf(instance)
if (a > -1) this.redirects[frontend][protocol].checked.splice(a, 1)
}
for (const instance of blackList.offline) {
const a = this.redirects[frontend][protocol].checked.indexOf(instance)
if (a > -1) this.redirects[frontend][protocol].checked.splice(a, 1)
}
}
}
})
})
this.unifyCookies = from =>
new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(from)
const list = [...this.redirects[this.frontend][this.protocol]]
if (![...list.checked, ...list.custom].includes(protocolHost)) {
resolve()
return
}
for (const cookie of this.redirects[this.frontend].cookies) {
await utils.copyCookie(frontend, protocolHost, [...list.checked, list.custom], cookie)
}
resolve(true)
})
this.switchInstance = (url, disableOverride) => {
if (!this.enable && !disableOverride) return
const protocolHost = utils.protocolHost(url)
const list = [...this.redirects[this.frontend][this.protocol]]
if (!list.all.includes(protocolHost)) return
let userList = [...list.checked, ...list.custom]
if (userList.length === 0 && this.protocolFallback) userList = [...list.normal.all]
const i = userList.indexOf(protocolHost)
if (i > -1) userList.splice(i, 1)
if (userList.length === 0) return
const randomInstance = utils.getRandomInstance(userList)
return `${randomInstance}${url.pathname}${url.search}`
}
this.redirect = (url, type, initiator, disableOverride) => {
const result = redirect(url, type, initiator, disableOverride)
if (result == "BYPASSTAB") return "BYPASSTAB"
if (result) {
const list = [...this.redirects[this.frontend][this.protocol]]
let userList = [...list.checked, ...list.custom]
const randomInstance = utils.getRandomInstance(userList)
return `${randomInstance}${result.pathname}${result.search}`
}
}
let init = () => new Promise(async resolve => {})
}
}
let Reddit = new FrontEnd({
enable: true,
frontends: {
libreddit: { cookies: ["theme", "front_page", "layout", "wide", "post_sort", "comment_sort", "show_nsfw", "autoplay_videos", "use_hls", "hide_hls_notification", "subscriptions", "filters"] },
teddit: {
cookies: [
"collapse_child_comments",
"domain_instagram",
"domain_twitter",
"domain_youtube",
"flairs",
"highlight_controversial",
"nsfw_enabled",
"post_media_max_height",
"show_upvoted_percentage",
"show_upvotes",
"theme",
"videos_muted",
],
},
},
frontend: "libreddit",
redirect: (url, type, initiator, disableOverride) => {
if (this.enable && !disableOverride) return
const targets = [/^https?:\/{2}(www\.|old\.|np\.|new\.|amp\.|)reddit\.com/, /^https?:\/{2}(i\.|preview\.)redd\.it/]
if (!targets.some(rx => rx.test(url.href))) return
if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
if (!["main_frame", "xmlhttprequest", "other", "image", "media"].includes(type)) return
const bypassPaths = /\/(gallery\/poll\/rpan\/settings\/topics)/
if (url.pathname.match(bypassPaths)) return
const protocolHost = utils.protocolHost(url)
if (url.host === "i.redd.it") {
if (this.frontend == "libreddit") return `${protocolHost}/img${url.pathname}${url.search}`
if (this.frontend == "teddit") return `${protocolHost}/pics/w:null_${url.pathname.substring(1)}${url.search}`
} else if (url.host === "redd.it") {
// https://redd.it/foo => https://libredd.it/comments/foo
if (this.frontend == "libreddit" && !url.pathname.match(/^\/+[^\/]+\/+[^\/]/)) return `${protocolHost}/comments${url.pathname}${url.search}`
// https://redd.it/foo => https://teddit.net/comments/foo
if (this.frontend == "teddit" && !url.pathname.match(/^\/+[^\/]+\/+[^\/]/)) return `${protocolHost}/comments${url.pathname}${url.search}`
} else if (url.host === "preview.redd.it") {
if (this.frontend == "libreddit") return `${protocolHost}/preview/pre${url.pathname}${url.search}`
if (this.frontend == "teddit") return
} else {
return `${url.href}`
}
},
})
export default {}

View File

@ -1,17 +1,20 @@
"use strict"
window.browser = window.browser || window.chrome
let exceptions
function isException(url) {
for (const item of exceptions.url) if (item == `${url.protocol}//${url.host}`) return true
for (const item of exceptions.regex) if (new RegExp(item).test(url.href)) return true
return false
}
let exceptions
function init() {
browser.storage.local.get("exceptions", r => {
exceptions = r.exceptions
return new Promise(resolve => {
browser.storage.local.get("options", r => {
if (r.options) exceptions = r.options.exceptions
resolve()
})
})
}
@ -22,46 +25,26 @@ async function initDefaults() {
return new Promise(resolve =>
browser.storage.local.set(
{
exceptions: {
url: [],
regex: [],
options: {
exceptions: {
url: [],
regex: [],
},
theme: "detect",
popupServices: ["youtube", "twitter", "instagram", "tiktok", "imgur", "reddit", "quora", "translate", "maps"],
autoRedirect: false,
firstPartyIsolate: false,
network: "clearnet",
networkFallback: true,
latencyThreshold: 1000,
},
theme: "DEFAULT",
popupFrontends: ["youtube", "twitter", "instagram", "tiktok", "imgur", "reddit", "quora", "translate", "maps"],
autoRedirect: false,
firstPartyIsolate: false,
protocol: "normal",
protocolFallback: true,
latencyThreshold: 1000,
},
() => resolve()
)
)
}
const allPopupFrontends = [
"youtube",
"youtubeMusic",
"twitter",
"instagram",
"tiktok",
"imgur",
"reddit",
"search",
"translate",
"maps",
"wikipedia",
"medium",
"quora",
"imdb",
"reuters",
"peertube",
"lbry",
"sendTargets",
]
export default {
isException,
initDefaults,
allPopupFrontends,
}

View File

@ -0,0 +1,15 @@
window.browser = window.browser || window.chrome
browser.storage.local.get(["localstorage", "tmp"], r => {
let localstorageJson = r.localstorage
const frontend = r.tmp[0]
const items = r.tmp[1]
localstorageJson[frontend] = {}
for (const item of items) {
let tmp = localStorage.getItem(item)
if (tmp) localstorageJson[frontend][item] = tmp
}
browser.storage.local.set({ localstorage: localstorageJson })
})

View File

@ -1,221 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}(?:www\.|)imdb\.com.*/]
const frontends = new Array("libremdb")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.libremdb = val
libremdbNormalRedirectsChecks = [...redirects.libremdb.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = libremdbNormalRedirectsChecks.indexOf(instance)
if (a > -1) libremdbNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
imdbRedirects: redirects,
libremdbNormalRedirectsChecks,
libremdbTorRedirectsChecks: [...redirects.libremdb.tor],
libremdbI2pRedirectsChecks: [...redirects.libremdb.i2p],
libremdbLokiRedirectsChecks: [...redirects.libremdb.loki],
},
() => resolve()
)
})
)
}
let disableImdb,
protocol,
protocolFallback,
imdbRedirects,
libremdbNormalRedirectsChecks,
libremdbNormalCustomRedirects,
libremdbTorRedirectsChecks,
libremdbTorCustomRedirects,
libremdbI2pCustomRedirects,
libremdbLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableImdb",
"protocol",
"protocolFallback",
"imdbRedirects",
"libremdbNormalRedirectsChecks",
"libremdbNormalCustomRedirects",
"libremdbTorRedirectsChecks",
"libremdbTorCustomRedirects",
"libremdbI2pCustomRedirects",
"libremdbLokiCustomRedirects",
],
r => {
disableImdb = r.disableImdb
protocol = r.protocol
protocolFallback = r.protocolFallback
imdbRedirects = r.imdbRedirects
libremdbNormalRedirectsChecks = r.libremdbNormalRedirectsChecks
libremdbNormalCustomRedirects = r.libremdbNormalCustomRedirects
libremdbTorRedirectsChecks = r.libremdbTorRedirectsChecks
libremdbTorCustomRedirects = r.libremdbTorCustomRedirects
libremdbI2pCustomRedirects = r.libremdbI2pCustomRedirects
libremdbLokiCustomRedirects = r.libremdbLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function redirect(url, type, initiator, disableOverride) {
if (disableImdb && !disableOverride) return
if (url.pathname == "/") return
if (type != "main_frame") return
const all = [...imdbRedirects.libremdb.normal, ...libremdbNormalCustomRedirects]
if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return
if (!targets.some(rx => rx.test(url.href))) return
let instancesList = []
if (protocol == "loki") instancesList = [...libremdbLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...libremdbI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...libremdbTorRedirectsChecks, ...libremdbTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...libremdbNormalRedirectsChecks, ...libremdbNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
const randomInstance = utils.getRandomInstance(instancesList)
return `${randomInstance}${url.pathname}`
}
function reverse(url) {
return new Promise(async resolve => {
await init()
let protocolHost = utils.protocolHost(url)
const all = [
...imdbRedirects.libremdb.normal,
...imdbRedirects.libremdb.tor,
...libremdbNormalCustomRedirects,
...libremdbTorCustomRedirects,
...libremdbI2pCustomRedirects,
...libremdbLokiCustomRedirects,
]
if (!all.includes(protocolHost)) {
resolve()
return
}
resolve(`https://imdb.com${url.pathname}${url.search}`)
})
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableImdb && !disableOverride) {
resolve()
return
}
let protocolHost = utils.protocolHost(url)
const all = [
...imdbRedirects.libremdb.tor,
...imdbRedirects.libremdb.normal,
...libremdbNormalCustomRedirects,
...libremdbTorCustomRedirects,
...libremdbI2pCustomRedirects,
...libremdbLokiCustomRedirects,
]
if (!all.includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...libremdbLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...libremdbI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...libremdbTorRedirectsChecks, ...libremdbTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...libremdbNormalRedirectsChecks, ...libremdbNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
libremdbNormalRedirectsChecks = [...redirects.libremdb.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = libremdbNormalRedirectsChecks.indexOf(instance)
if (a > -1) libremdbNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableImdb: true,
imdbRedirects: redirects,
libremdbNormalRedirectsChecks,
libremdbNormalCustomRedirects: [],
libremdbTorRedirectsChecks: [...redirects.libremdb.tor],
libremdbTorCustomRedirects: [],
libremdbI2pRedirectsChecks: [],
libremdbI2pCustomRedirects: [],
libremdbLokiRedirectsChecks: [],
libremdbLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
reverse,
switchInstance,
initDefaults,
}

View File

@ -1,221 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = /^https?:\/{2}([im]\.)?imgur\.(com|io)(\/|$)/
const frontends = new Array("rimgo")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.rimgo = val
rimgoNormalRedirectsChecks = [...redirects.rimgo.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = rimgoNormalRedirectsChecks.indexOf(instance)
if (a > -1) rimgoNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
imgurRedirects: redirects,
rimgoNormalRedirectsChecks,
rimgoTorRedirectsChecks: [...redirects.rimgo.tor],
rimgoI2pRedirectsChecks: [...redirects.rimgo.i2p],
rimgoLokiRedirectsChecks: [...redirects.rimgo.loki],
},
() => resolve()
)
})
)
}
let disableImgur,
imgurRedirects,
protocol,
protocolFallback,
rimgoNormalRedirectsChecks,
rimgoNormalCustomRedirects,
rimgoTorRedirectsChecks,
rimgoTorCustomRedirects,
rimgoI2pRedirectsChecks,
rimgoI2pCustomRedirects,
rimgoLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableImgur",
"imgurRedirects",
"protocol",
"protocolFallback",
"rimgoNormalRedirectsChecks",
"rimgoNormalCustomRedirects",
"rimgoTorRedirectsChecks",
"rimgoTorCustomRedirects",
"rimgoI2pRedirectsChecks",
"rimgoI2pCustomRedirects",
"rimgoLokiCustomRedirects",
],
r => {
disableImgur = r.disableImgur
imgurRedirects = r.imgurRedirects
protocol = r.protocol
protocolFallback = r.protocolFallback
rimgoNormalRedirectsChecks = r.rimgoNormalRedirectsChecks
rimgoNormalCustomRedirects = r.rimgoNormalCustomRedirects
rimgoTorRedirectsChecks = r.rimgoTorRedirectsChecks
rimgoTorCustomRedirects = r.rimgoTorCustomRedirects
rimgoI2pRedirectsChecks = r.rimgoI2pRedirectsChecks
rimgoI2pCustomRedirects = r.rimgoI2pCustomRedirects
rimgoLokiCustomRedirects = r.rimgoLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
// https://imgur.com/gallery/s4WXQmn
// https://imgur.com/a/H8M4rcp
// https://imgur.com/gallery/gYiQLWy
// https://imgur.com/gallery/cTRwaJU
// https://i.imgur.com/CFSQArP.jpeg
function all() {
return [
...imgurRedirects.rimgo.normal,
...imgurRedirects.rimgo.tor,
...imgurRedirects.rimgo.i2p,
...rimgoNormalCustomRedirects,
...rimgoTorCustomRedirects,
...rimgoI2pCustomRedirects,
...rimgoLokiCustomRedirects,
]
}
function redirect(url, type, initiator, disableOverride) {
if (disableImgur && !disableOverride) return
if (url.pathname == "/" && !disableOverride) return
if (!["main_frame", "sub_frame", "xmlhttprequest", "other", "image", "media"].includes(type)) return
if (initiator && (all().includes(initiator.origin) || targets.test(initiator.host))) return
if (!targets.test(url.href)) return
if (url.pathname.includes("delete/")) return
let instancesList = []
if (protocol == "loki") instancesList = [...rimgoLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...rimgoI2pCustomRedirects, ...rimgoI2pRedirectsChecks]
else if (protocol == "tor") instancesList = [...rimgoTorRedirectsChecks, ...rimgoTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...rimgoNormalRedirectsChecks, ...rimgoNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
const randomInstance = utils.getRandomInstance(instancesList)
return `${randomInstance}${url.pathname}${url.search}`
}
function reverse(url) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
resolve(`https://imgur.com${url.pathname}${url.search}`)
})
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableImgur && !disableOverride) {
resolve()
return
}
let protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...rimgoLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...rimgoI2pCustomRedirects, ...rimgoI2pRedirectsChecks]
else if (protocol == "tor") instancesList = [...rimgoTorRedirectsChecks, ...rimgoTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...rimgoNormalRedirectsChecks, ...rimgoNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
rimgoNormalRedirectsChecks = [...redirects.rimgo.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = rimgoNormalRedirectsChecks.indexOf(instance)
if (a > -1) rimgoNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableImgur: false,
imgurRedirects: redirects,
rimgoNormalRedirectsChecks: rimgoNormalRedirectsChecks,
rimgoNormalCustomRedirects: [],
rimgoTorRedirectsChecks: [...redirects.rimgo.tor],
rimgoTorCustomRedirects: [],
rimgoI2pRedirectsChecks: [...redirects.rimgo.i2p],
rimgoI2pCustomRedirects: [],
rimgoLokiRedirectsChecks: [...redirects.rimgo.loki],
rimgoLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
reverse,
initDefaults,
switchInstance,
}

View File

@ -1,249 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = ["instagram.com", "www.instagram.com"]
const frontends = new Array("bibliogram")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
redirects.bibliogram = val
bibliogramNormalRedirectsChecks = [...redirects.bibliogram.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = bibliogramNormalRedirectsChecks.indexOf(instance)
if (a > -1) bibliogramNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
instagramRedirects: redirects,
bibliogramNormalRedirectsChecks,
bibliogramTorRedirectsChecks: [...redirects.bibliogram.tor],
bibliogramI2pRedirectsChecks: [...redirects.bibliogram.i2p],
bibliogramLokiRedirectsChecks: [...redirects.bibliogram.loki],
},
() => resolve()
)
})
)
}
let disableInstagram,
protocol,
protocolFallback,
instagramRedirects,
bibliogramNormalRedirectsChecks,
bibliogramTorRedirectsChecks,
bibliogramNormalCustomRedirects,
bibliogramTorCustomRedirects,
bibliogramI2pCustomRedirects,
bibliogramLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableInstagram",
"protocol",
"protocolFallback",
"instagramRedirects",
"bibliogramNormalRedirectsChecks",
"bibliogramTorRedirectsChecks",
"bibliogramNormalCustomRedirects",
"bibliogramTorCustomRedirects",
"bibliogramI2pCustomRedirects",
"bibliogramLokiCustomRedirects",
],
r => {
disableInstagram = r.disableInstagram
protocol = r.protocol
protocolFallback = r.protocolFallback
instagramRedirects = r.instagramRedirects
bibliogramNormalRedirectsChecks = r.bibliogramNormalRedirectsChecks
bibliogramTorRedirectsChecks = r.bibliogramTorRedirectsChecks
bibliogramNormalCustomRedirects = r.bibliogramNormalCustomRedirects
bibliogramTorCustomRedirects = r.bibliogramTorCustomRedirects
bibliogramI2pCustomRedirects = r.bibliogramI2pCustomRedirects
bibliogramLokiCustomRedirects = r.bibliogramLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function initBibliogramPreferences(test, from) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(from)
if (
![
...bibliogramNormalRedirectsChecks,
...bibliogramTorRedirectsChecks,
...bibliogramNormalCustomRedirects,
...bibliogramTorCustomRedirects,
...bibliogramI2pCustomRedirects,
...bibliogramLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...bibliogramLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...bibliogramI2pCustomRedirects]
else if (protocol == "tor") checkedInstances = [...bibliogramTorRedirectsChecks, ...bibliogramTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...bibliogramNormalRedirectsChecks, ...bibliogramNormalCustomRedirects]
}
await utils.getPreferencesFromToken("bibliogram", from, checkedInstances, "settings", "settings.json")
}
resolve(true)
})
}
function all() {
return [
...bibliogramNormalRedirectsChecks,
...bibliogramTorRedirectsChecks,
...bibliogramNormalCustomRedirects,
...bibliogramTorCustomRedirects,
...bibliogramI2pCustomRedirects,
...bibliogramLokiCustomRedirects,
]
}
function redirect(url, type, initiator, disableOverride) {
if (disableInstagram && !disableOverride) return
if (!targets.includes(url.host)) return
if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
if (!["main_frame", "sub_frame", "xmlhttprequest", "other", "image", "media"].includes(type)) return
const bypassPaths = [/about/, /explore/, /support/, /press/, /api/, /privacy/, /safety/, /admin/, /\/(accounts\/|embeds?.js)/]
if (bypassPaths.some(rx => rx.test(url.pathname))) return
let instancesList = []
if (protocol == "loki") instancesList = [...bibliogramLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...bibliogramI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...bibliogramTorRedirectsChecks, ...bibliogramTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...bibliogramNormalRedirectsChecks, ...bibliogramNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
let randomInstance = utils.getRandomInstance(instancesList)
const reservedPaths = ["u", "p", "privacy"]
if (url.pathname === "/" || reservedPaths.includes(url.pathname.split("/")[1])) return `${randomInstance}${url.pathname}${url.search}`
if (url.pathname.startsWith("/reel") || url.pathname.startsWith("/tv")) return `${randomInstance}/p${url.pathname.replace(/\/reel|\/tv/i, "")}${url.search}`
else return `${randomInstance}/u${url.pathname}${url.search}` // Likely a user profile, redirect to '/u/...'
}
function reverse(url) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
if (url.pathname.startsWith("/p")) resolve(`https://instagram.com${url.pathname.replace("/p", "")}${url.search}`)
if (url.pathname.startsWith("/u")) resolve(`https://instagram.com${url.pathname.replace("/u", "")}${url.search}`)
resolve(`https://instagram.com${url.pathname}${url.search}`)
})
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableInstagram && !disableOverride) {
resolve()
return
}
let protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...bibliogramLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...bibliogramI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...bibliogramTorRedirectsChecks, ...bibliogramTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...bibliogramNormalRedirectsChecks, ...bibliogramNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
bibliogramNormalRedirectsChecks = [...redirects.bibliogram.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = bibliogramNormalRedirectsChecks.indexOf(instance)
if (a > -1) bibliogramNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set({
disableInstagram: false,
instagramRedirects: redirects,
bibliogramNormalRedirectsChecks,
bibliogramNormalCustomRedirects: [],
bibliogramTorRedirectsChecks: [...redirects.bibliogram.tor],
bibliogramTorCustomRedirects: [],
bibliogramI2pRedirectsChecks: [...redirects.bibliogram.i2p],
bibliogramI2pCustomRedirects: [],
bibliogramLokiRedirectsChecks: [...redirects.bibliogram.loki],
bibliogramLokiCustomRedirects: [],
})
resolve()
})
})
})
}
export default {
setRedirects,
initBibliogramPreferences,
reverse,
redirect,
initDefaults,
switchInstance,
}

View File

@ -1,223 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}odysee\.com/]
const frontends = new Array("librarian")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.librarian = val
librarianNormalRedirectsChecks = [...redirects.librarian.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = librarianNormalRedirectsChecks.indexOf(instance)
if (a > -1) librarianNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
lbryTargetsRedirects: redirects,
librarianNormalRedirectsChecks,
librarianTorRedirectsChecks: [...redirects.librarian.tor],
librarianI2pRedirectsChecks: [...redirects.librarian.i2p],
librarianLokiRedirectsChecks: [...redirects.librarian.loki],
},
() => resolve()
)
})
)
}
let disableLbryTargets,
lbryFrontend,
protocol,
protocolFallback,
lbryTargetsRedirects,
lbryRedirectType,
librarianNormalRedirectsChecks,
librarianNormalCustomRedirects,
librarianTorRedirectsChecks,
librarianTorCustomRedirects,
librarianI2pRedirectsChecks,
librarianI2pCustomRedirects,
librarianLokiCustomRedirects
function init() {
return new Promise(resolve => {
browser.storage.local.get(
[
"disableLbryTargets",
"lbryFrontend",
"protocol",
"protocolFallback",
"lbryTargetsRedirects",
"lbryRedirectType",
"librarianNormalRedirectsChecks",
"librarianNormalCustomRedirects",
"librarianTorRedirectsChecks",
"librarianTorCustomRedirects",
"librarianI2pRedirectsChecks",
"librarianI2pCustomRedirects",
"librarianLokiCustomRedirects",
],
r => {
disableLbryTargets = r.disableLbryTargets
lbryFrontend = r.lbryFrontend
protocol = r.protocol
protocolFallback = r.protocolFallback
lbryTargetsRedirects = r.lbryTargetsRedirects
lbryRedirectType = r.lbryRedirectType
librarianNormalRedirectsChecks = r.librarianNormalRedirectsChecks
librarianNormalCustomRedirects = r.librarianNormalCustomRedirects
librarianTorRedirectsChecks = r.librarianTorRedirectsChecks
librarianTorCustomRedirects = r.librarianTorCustomRedirects
librarianI2pRedirectsChecks = r.librarianI2pRedirectsChecks
librarianI2pCustomRedirects = r.librarianI2pCustomRedirects
librarianLokiCustomRedirects = r.librarianLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function all() {
return [...redirects.librarian.normal, ...redirects.librarian.tor, ...librarianNormalCustomRedirects, ...librarianTorCustomRedirects, ...librarianI2pCustomRedirects, ...librarianLokiCustomRedirects]
}
function getInstancesList() {
let tmpList = []
switch (protocol) {
case "loki":
tmpList = [...librarianLokiCustomRedirects]
break
case "i2p":
tmpList = [...librarianI2pRedirectsChecks, ...librarianI2pCustomRedirects]
break
case "tor":
tmpList = [...librarianTorRedirectsChecks, ...librarianTorCustomRedirects]
}
if ((tmpList.length === 0 && protocolFallback) || protocol == "normal") {
tmpList = [...librarianNormalRedirectsChecks, ...librarianNormalCustomRedirects]
}
return tmpList
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableLbryTargets && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...librarianLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...librarianI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...librarianTorRedirectsChecks, ...librarianTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...librarianNormalRedirectsChecks, ...librarianNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function redirect(url, type, initiator, disableOverride) {
if (disableLbryTargets && !disableOverride) return
if (initiator && (all().includes(initiator.origin) || targets.includes(initiator.host))) return
if (!targets.some(rx => rx.test(url.href))) return
if (type == "sub_frame" && lbryRedirectType == "main_frame") return
const instancesList = getInstancesList()
switch (type) {
case "main_frame":
switch (lbryFrontend) {
case "librarian":
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
return `${randomInstance}${url.pathname}${url.search}`
case "lbryDesktop":
if (type == "main_frame") {
return url.href.replace(/^https?:\/{2}odysee\.com\//, "lbry://").replace(/:(?=[a-zA-Z0-9])/g, "#")
}
}
case "sub_frame":
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
return `${randomInstance}${url.pathname}${url.search}`.replace(/\/(?=[a-f0-9]{40})/, ":")
}
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
librarianNormalRedirectsChecks = [...redirects.librarian.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = librarianNormalRedirectsChecks.indexOf(instance)
if (a > -1) librarianNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableLbryTargets: true,
lbryFrontend: "librarian",
lbryTargetsRedirects: redirects,
lbryRedirectType: "both",
librarianNormalRedirectsChecks,
librarianNormalCustomRedirects: [],
librarianTorRedirectsChecks: [...redirects.librarian.tor],
librarianTorCustomRedirects: [],
librarianI2pRedirectsChecks: [...redirects.librarian.i2p],
librarianI2pCustomRedirects: [],
librarianLokiRedirectsChecks: [...redirects.librarian.loki],
librarianLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
switchInstance,
redirect,
initDefaults,
}

View File

@ -1,309 +0,0 @@
"use strict"
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = /^https?:\/{2}(((www|maps)\.)?(google\.).*(\/maps)|maps\.(google\.).*)/
const frontends = new Array("facil")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
redirects.osm = {}
redirects.osm.normal = ["https://www.openstreetmap.org"]
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.facil = val
facilNormalRedirectsChecks = [...redirects.facil.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = facilNormalRedirectsChecks.indexOf(instance)
if (a > -1) facilNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
mapsRedirects: redirects,
facilNormalRedirectsChecks,
facilTorRedirectsChecks: [...redirects.facil.tor],
facilI2pRedirectsChecks: [...redirects.facil.i2p],
facilLokiRedirectsChecks: [...redirects.facil.loki],
},
() => resolve()
)
})
)
}
let disableMaps,
mapsFrontend,
protocol,
protocolFallback,
facilNormalRedirectsChecks,
facilNormalCustomRedirects,
facilTorRedirectsChecks,
facilTorCustomRedirects,
facilI2pRedirectsChecks,
facilI2pCustomRedirects,
facilLokiRedirectsChecks,
facilLokiCustomRedirects
function init() {
browser.storage.local.get(
[
"disableMaps",
"mapsFrontend",
"protocol",
"protocolFallback",
"facilNormalRedirectsChecks",
"facilNormalCustomRedirects",
"facilTorRedirectsChecks",
"facilTorCustomRedirects",
"facilI2pRedirectsChecks",
"facilI2pCustomRedirects",
"facilLokiRedirectsChecks",
"facilLokiCustomRedirects",
],
r => {
disableMaps = r.disableMaps
mapsFrontend = r.mapsFrontend
protocol = r.protocol
protocolFallback = r.protocolFallback
facilNormalRedirectsChecks = r.facilNormalRedirectsChecks
facilNormalCustomRedirects = r.facilNormalCustomRedirects
facilTorRedirectsChecks = r.facilTorRedirectsChecks
facilTorCustomRedirects = r.facilTorCustomRedirects
facilI2pRedirectsChecks = r.facilI2pRedirectsChecks
facilI2pCustomRedirects = r.facilI2pCustomRedirects
facilLokiRedirectsChecks = r.facilLokiRedirectsChecks
facilLokiCustomRedirects = r.facilLokiCustomRedirects
}
)
}
init()
browser.storage.onChanged.addListener(init)
function redirect(url, initiator) {
if (disableMaps) return
if (initiator && initiator.host === "earth.google.com") return
if (!url.href.match(targets)) return
const mapCentreRegex = /@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/
const dataLatLngRegex = /!3d(-?[0-9]{1,}.[0-9]{1,})!4d(-?[0-9]{1,}.[0-9]{1,})/
const placeRegex = /\/place\/(.*)\//
const travelModes = {
driving: "fossgis_osrm_car",
walking: "fossgis_osrm_foot",
bicycling: "fossgis_osrm_bike",
transit: "fossgis_osrm_car", // not implemented on OSM, default to car.
}
const travelModesFacil = {
driving: "car",
walking: "pedestrian",
bicycling: "bicycle",
transit: "car", // not implemented on Facil, default to car.
}
const osmLayers = {
none: "S",
transit: "T",
traffic: "S", // not implemented on OSM, default to standard.
bicycling: "C",
}
function addressToLatLng(address) {
const xmlhttp = new XMLHttpRequest()
xmlhttp.open("GET", `https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`, false)
xmlhttp.send()
if (xmlhttp.status === 200) {
const json = JSON.parse(xmlhttp.responseText)[0]
if (json) {
console.log("json", json)
return [`${json.lat},${json.lon}`, `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}`]
}
}
console.info("Error: Status is " + xmlhttp.status)
}
let instancesList
switch (mapsFrontend) {
case "osm":
instancesList = [...redirects.osm.normal]
break
case "facil":
switch (protocol) {
case "loki":
instancesList = [...facilLokiRedirectsChecks, ...facilLokiCustomRedirects]
break
case "i2p":
instancesList = [...facilI2pRedirectsChecks, ...facilI2pCustomRedirects]
break
case "tor":
instancesList = [...facilTorRedirectsChecks, ...facilTorCustomRedirects]
}
if ((instancesList == "" && protocolFallback) || protocol == "normal") {
instancesList = [...facilNormalRedirectsChecks, ...facilNormalCustomRedirects]
}
}
const randomInstance = utils.getRandomInstance(instancesList)
let mapCentre = "#"
let prefs = {}
if (url.pathname.match(mapCentreRegex)) {
// Set map centre if present
var [, lat, lon, zoom] = url.pathname.match(mapCentreRegex)
} else if (url.searchParams.has("center")) {
var [lat, lon] = url.searchParams.get("center").split(",")
var zoom = url.searchParams.get("zoom") ?? "17"
}
if (lat && lon && zoom) {
if (mapsFrontend == "osm") mapCentre = `#map=${zoom}/${lat}/${lon}`
if (mapsFrontend == "facil") mapCentre = `#${zoom}/${lat}/${lon}`
}
if (url.searchParams.get("layer")) prefs.layers = osmLayers[url.searchParams.get("layer")]
if (url.pathname.includes("/embed")) {
// Handle Google Maps Embed API
// https://www.google.com/maps/embed/v1/place?key=AIzaSyD4iE2xVSpkLLOXoyqT-RuPwURN3ddScAI&q=Eiffel+Tower,Paris+France
console.log("embed life")
let query = ""
if (url.searchParams.has("q")) query = url.searchParams.get("q")
else if (url.searchParams.has("query")) query = url.searchParams.has("query")
else if (url.searchParams.has("pb"))
try {
query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1]
} catch (error) {
console.error(error)
} // Unable to find map marker in URL.
let [coords, boundingbox] = addressToLatLng(query)
prefs.bbox = boundingbox
prefs.marker = coords
prefs.layer = "mapnik"
let prefsEncoded = new URLSearchParams(prefs).toString()
if (mapsFrontend == "osm") return `${randomInstance}/export/embed.html?${prefsEncoded}`
if (mapsFrontend == "facil") return `${randomInstance}/#q=${query}`
} else if (url.pathname.includes("/dir")) {
// Handle Google Maps Directions
// https://www.google.com/maps/dir/?api=1&origin=Space+Needle+Seattle+WA&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling
let travMod = url.searchParams.get("travelmode")
if (url.searchParams.has("travelmode")) prefs.engine = travelModes[travMod]
let orgVal = url.searchParams.get("origin")
let destVal = url.searchParams.get("destination")
let org
addressToLatLng(orgVal, a => (org = a))
let dest
addressToLatLng(destVal, a => (dest = a))
prefs.route = `${org};${dest}`
let prefsEncoded = new URLSearchParams(prefs).toString()
if (mapsFrontend == "osm") return `${randomInstance}/directions?${prefsEncoded}${mapCentre}`
if (mapsFrontend == "facil") return `${randomInstance}/#q=${orgVal}%20to%20${destVal}%20by%20${travelModesFacil[travMod]}`
} else if (url.pathname.includes("data=") && url.pathname.match(dataLatLngRegex)) {
// Get marker from data attribute
// https://www.google.com/maps/place/41%C2%B001'58.2%22N+40%C2%B029'18.2%22E/@41.032833,40.4862063,17z/data=!3m1!4b1!4m6!3m5!1s0x0:0xf64286eaf72fc49d!7e2!8m2!3d41.0328329!4d40.4883948
console.log("data life")
let [, mlat, mlon] = url.pathname.match(dataLatLngRegex)
if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}`
if (mapsFrontend == "facil") return `${randomInstance}/#q=${mlat}%2C${mlon}`
} else if (url.searchParams.has("ll")) {
// Get marker from ll param
// https://maps.google.com/?ll=38.882147,-76.99017
console.log("ll life")
const [mlat, mlon] = url.searchParams.get("ll").split(",")
if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}`
if (mapsFrontend == "facil") return `${randomInstance}/#q=${mlat}%2C${mlon}`
} else if (url.searchParams.has("viewpoint")) {
// Get marker from viewpoint param.
// https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.857832,2.295226&heading=-45&pitch=38&fov=80
console.log("viewpoint life")
const [mlat, mlon] = url.searchParams.get("viewpoint").split(",")
if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}`
if (mapsFrontend == "facil") return `${randomInstance}/#q=${mlat}%2C${mlon}`
} else {
// Use query as search if present.
console.log("normal life")
let query
if (url.searchParams.has("q")) query = url.searchParams.get("q")
else if (url.searchParams.has("query")) query = url.searchParams.get("query")
else if (url.pathname.match(placeRegex)) query = url.pathname.match(placeRegex)[1]
let prefsEncoded = new URLSearchParams(prefs).toString()
if (query) {
if (mapsFrontend == "osm") return `${randomInstance}/search?query="${query}${mapCentre}&${prefsEncoded}`
if (mapsFrontend == "facil") return `${randomInstance}/${mapCentre}/Mpnk/${query}`
}
}
let prefsEncoded = new URLSearchParams(prefs).toString()
console.log("mapCentre", mapCentre)
console.log("prefs", prefs)
console.log("prefsEncoded", prefsEncoded)
if (mapsFrontend == "osm") return `${randomInstance}/${mapCentre}&${prefsEncoded}`
if (mapsFrontend == "facil") return `${randomInstance}/${mapCentre}/Mpnk`
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
facilNormalRedirectsChecks = [...redirects.facil.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = facilNormalRedirectsChecks.indexOf(instance)
if (a > -1) facilNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableMaps: false,
mapsFrontend: "osm",
mapsRedirects: redirects,
facilNormalRedirectsChecks,
facilNormalCustomRedirects: [],
facilTorRedirectsChecks: [...redirects.facil.tor],
facilTorCustomRedirects: [],
facilI2pRedirectsChecks: [...redirects.facil.i2p],
facilI2pCustomRedirects: [],
facilLokiRedirectsChecks: [...redirects.facil.loki],
facilLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
initDefaults,
}

View File

@ -1,227 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [
// /(?:.*\.)*(?<!(link\.|cdn\-images\-\d+\.))medium\.com(\/.*)?$/,
/^medium\.com/,
/.*\.medium\.com/,
// // Other domains of medium blogs, source(s): https://findingtom.com/best-medium-blogs-to-follow/#1-forge
/^towardsdatascience\.com/,
/^uxdesign\.cc/,
/^uxplanet\.org/,
/^betterprogramming\.pub/,
/^aninjusticemag\.com/,
/^betterhumans\.pub/,
/^psiloveyou\.xyz/,
/^entrepreneurshandbook\.co/,
/^blog\.coinbase\.com/,
/^ levelup\.gitconnected\.com /,
/^javascript\.plainenglish\.io /,
/^blog\.bitsrc\.io /,
/^ itnext\.io /,
/^codeburst\.io /,
/^infosecwriteups\.com /,
/^ blog\.devgenius.io /,
/^ writingcooperative\.com /,
]
const frontends = new Array("scribe")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.scribe = val
scribeNormalRedirectsChecks = [...redirects.scribe.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = scribeNormalRedirectsChecks.indexOf(instance)
if (a > -1) scribeNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
mediumRedirects: redirects,
scribeNormalRedirectsChecks,
scribeTorRedirectsChecks: [...redirects.scribe.tor],
scribeI2pRedirectsChecks: [...redirects.scribe.i2p],
scribeLokiRedirectsChecks: [...redirects.scribe.loki],
},
() => resolve()
)
})
)
}
let disableMedium,
mediumRedirects,
scribeNormalRedirectsChecks,
scribeNormalCustomRedirects,
scribeTorRedirectsChecks,
scribeTorCustomRedirects,
scribeI2pCustomRedirects,
scribeLokiCustomRedirects,
protocol,
protocolFallback
function init() {
return new Promise(resolve => {
browser.storage.local.get(
[
"disableMedium",
"mediumRedirects",
"scribeNormalRedirectsChecks",
"scribeNormalCustomRedirects",
"scribeTorRedirectsChecks",
"scribeTorCustomRedirects",
"scribeI2pCustomRedirects",
"scribeLokiCustomRedirects",
"protocol",
"protocolFallback",
],
r => {
disableMedium = r.disableMedium
mediumRedirects = r.mediumRedirects
scribeNormalRedirectsChecks = r.scribeNormalRedirectsChecks
scribeNormalCustomRedirects = r.scribeNormalCustomRedirects
scribeTorRedirectsChecks = r.scribeTorRedirectsChecks
scribeTorCustomRedirects = r.scribeTorCustomRedirects
scribeI2pCustomRedirects = r.scribeI2pCustomRedirects
scribeLokiCustomRedirects = r.scribeLokiCustomRedirects
protocol = r.protocol
protocolFallback = r.protocolFallback
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function redirect(url, type, initiator, disableOverride) {
if (disableMedium && !disableOverride) return
if (url.pathname == "/" && !disableOverride) return
if (type != "main_frame" && "sub_frame" && "xmlhttprequest" && "other") return
if (
initiator &&
[...mediumRedirects.scribe.normal, ...mediumRedirects.scribe.tor, ...scribeNormalCustomRedirects, ...scribeTorCustomRedirects, ...scribeI2pCustomRedirects, ...scribeLokiCustomRedirects].includes(
initiator.origin
)
)
return
if (!targets.some(rx => rx.test(url.host))) return
if (/^\/(@[a-zA-Z.]{0,}(\/|)$)/.test(url.pathname)) return
let instancesList = []
if (protocol == "loki") instancesList = [...scribeLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...scribeI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...scribeTorRedirectsChecks, ...scribeTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...scribeNormalRedirectsChecks, ...scribeNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
const randomInstance = utils.getRandomInstance(instancesList)
return `${randomInstance}${url.pathname}${url.search}`
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableMedium && !disableOverride) {
resolve()
return
}
let protocolHost = utils.protocolHost(url)
const all = [
...mediumRedirects.scribe.tor,
...mediumRedirects.scribe.normal,
...scribeNormalCustomRedirects,
...scribeTorCustomRedirects,
...scribeI2pCustomRedirects,
...scribeLokiCustomRedirects,
]
if (!all.includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...scribeLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...scribeI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...scribeTorRedirectsChecks, ...scribeTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...scribeNormalRedirectsChecks, ...scribeNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
scribeNormalRedirectsChecks = [...redirects.scribe.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = scribeNormalRedirectsChecks.indexOf(instance)
if (a > -1) scribeNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableMedium: false,
mediumRedirects: redirects,
scribeNormalRedirectsChecks,
scribeNormalCustomRedirects: [],
scribeTorRedirectsChecks: [...redirects.scribe.tor],
scribeTorCustomRedirects: [],
scribeI2pRedirectsChecks: [...redirects.scribe.i2p],
scribeI2pCustomRedirects: [],
scribeLokiRedirectsChecks: [...redirects.scribe.loki],
scribeLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
switchInstance,
initDefaults,
}

View File

@ -1,209 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const frontends = new Array("simpleertube")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.simpleertube = val
simpleertubeNormalRedirectsChecks = [...redirects.simpleertube.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = simpleertubeNormalRedirectsChecks.indexOf(instance)
if (a > -1) simpleertubeNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
peertubeRedirects: redirects,
simpleertubeNormalRedirectsChecks,
simpleertubeTorRedirectsChecks: [...redirects.simpleertube.tor],
simpleertubeI2pRedirectsChecks: [...redirects.simpleertube.i2p],
simpleertubeLokiRedirectsChecks: [...redirects.simpleertube.loki],
},
() => resolve()
)
})
)
}
let disablePeertubeTargets,
peertubeRedirects,
simpleertubeNormalRedirectsChecks,
simpleertubeNormalCustomRedirects,
simpleertubeTorRedirectsChecks,
simpleertubeTorCustomRedirects,
simpleertubeI2pRedirectsChecks,
simpleertubeI2pCustomRedirects,
simpleertubeLokiRedirectsChecks,
simpleertubeLokiCustomRedirects,
peerTubeTargets,
protocol,
protocolFallback
function init() {
return new Promise(resolve => {
browser.storage.local.get(
[
"disablePeertubeTargets",
"peertubeRedirects",
"simpleertubeNormalRedirectsChecks",
"simpleertubeNormalCustomRedirects",
"simpleertubeTorRedirectsChecks",
"simpleertubeTorCustomRedirects",
"simpleertubeI2pRedirectsChecks",
"simpleertubeI2pCustomRedirects",
"simpleertubeLokiRedirectsChecks",
"simpleertubeLokiCustomRedirects",
"peerTubeTargets",
"protocol",
"protocolFallback",
],
r => {
disablePeertubeTargets = r.disablePeertubeTargets
peertubeRedirects = r.peertubeRedirects
simpleertubeNormalRedirectsChecks = r.simpleertubeNormalRedirectsChecks
simpleertubeNormalCustomRedirects = r.simpleertubeNormalCustomRedirects
simpleertubeTorRedirectsChecks = r.simpleertubeTorRedirectsChecks
simpleertubeTorCustomRedirects = r.simpleertubeTorCustomRedirects
simpleertubeI2pRedirectsChecks = r.simpleertubeI2pRedirectsChecks
simpleertubeI2pCustomRedirects = r.simpleertubeI2pCustomRedirects
simpleertubeLokiRedirectsChecks = r.simpleertubeLokiRedirectsChecks
simpleertubeLokiCustomRedirects = r.simpleertubeLokiCustomRedirects
peerTubeTargets = r.peerTubeTargets
protocol = r.protocol
protocolFallback = r.protocolFallback
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function all() {
return [
...simpleertubeNormalRedirectsChecks,
...simpleertubeTorRedirectsChecks,
...simpleertubeI2pRedirectsChecks,
...simpleertubeLokiRedirectsChecks,
...simpleertubeNormalCustomRedirects,
...simpleertubeTorCustomRedirects,
...simpleertubeI2pCustomRedirects,
...simpleertubeLokiCustomRedirects,
]
}
function redirect(url, type, initiator, disableOverride) {
if (disablePeertubeTargets && !disableOverride) return
if (initiator && (all().includes(initiator.origin) || peerTubeTargets.includes(initiator.host))) return
let protocolHost = utils.protocolHost(url)
if (!peerTubeTargets.includes(protocolHost)) return
if (type != "main_frame") return
let instancesList = []
if (protocol == "loki") instancesList = [...simpleertubeLokiRedirectsChecks, ...simpleertubeLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...simpleertubeI2pRedirectsChecks, ...simpleertubeI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...simpleertubeTorRedirectsChecks, ...simpleertubeTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...simpleertubeNormalRedirectsChecks, ...simpleertubeNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
const randomInstance = utils.getRandomInstance(instancesList)
if (url.host == "search.joinpeertube.org" || url.host == "sepiasearch.org") return randomInstance
return `${randomInstance}/${url.host}${url.pathname}${url.search}`
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disablePeertubeTargets && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...simpleertubeLokiRedirectsChecks, ...simpleertubeLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...simpleertubeI2pRedirectsChecks, ...simpleertubeI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...simpleertubeTorRedirectsChecks, ...simpleertubeTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...simpleertubeNormalRedirectsChecks, ...simpleertubeNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
simpleertubeNormalRedirectsChecks = [...redirects.simpleertube.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = simpleertubeNormalRedirectsChecks.indexOf(instance)
if (a > -1) simpleertubeNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
peerTubeTargets: ["https://search.joinpeertube.org", ...dataJson.peertube],
disablePeertubeTargets: true,
peertubeRedirects: redirects,
simpleertubeNormalRedirectsChecks,
simpleertubeNormalCustomRedirects: [],
simpleertubeTorRedirectsChecks: [...redirects.simpleertube.tor],
simpleertubeTorCustomRedirects: [],
simpleertubeI2pRedirectsChecks: [...redirects.simpleertube.i2p],
simpleertubeI2pCustomRedirects: [],
simpleertubeLokiRedirectsChecks: [...redirects.simpleertube.loki],
simpleertubeLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
switchInstance,
redirect,
initDefaults,
}

View File

@ -1,205 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}(www\.|)quora\.com.*/]
let redirects = {}
const frontends = new Array("quetre")
const protocols = new Array("normal", "tor", "i2p", "loki")
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.quetre = val
quetreNormalRedirectsChecks = [...redirects.quetre.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = quetreNormalRedirectsChecks.indexOf(instance)
if (a > -1) quetreNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
quoraRedirects: redirects,
quetreNormalRedirectsChecks,
quetreTorRedirectsChecks: [...redirects.quetre.tor],
quetreI2pRedirectsChecks: [...redirects.quetre.i2p],
quetreLokiRedirectsChecks: [...redirects.quetre.loki],
},
() => resolve()
)
})
)
}
let disableQuora,
protocol,
protocolFallback,
quoraRedirects,
quetreNormalRedirectsChecks,
quetreNormalCustomRedirects,
quetreTorRedirectsChecks,
quetreTorCustomRedirects,
quetreI2pCustomRedirects,
quetreLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableQuora",
"protocol",
"protocolFallback",
"quoraRedirects",
"quetreNormalRedirectsChecks",
"quetreNormalCustomRedirects",
"quetreTorRedirectsChecks",
"quetreTorCustomRedirects",
"quetreI2pCustomRedirects",
"quetreLokiCustomRedirects",
],
r => {
disableQuora = r.disableQuora
protocol = r.protocol
protocolFallback = r.protocolFallback
quoraRedirects = r.quoraRedirects
quetreNormalRedirectsChecks = r.quetreNormalRedirectsChecks
quetreNormalCustomRedirects = r.quetreNormalCustomRedirects
quetreTorRedirectsChecks = r.quetreTorRedirectsChecks
quetreTorCustomRedirects = r.quetreTorCustomRedirects
quetreI2pCustomRedirects = r.quetreI2pCustomRedirects
quetreLokiCustomRedirects = r.quetreLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function redirect(url, type, initiator, disableOverride) {
if (disableQuora && !disableOverride) return
if (url.pathname == "/" && !disableOverride) return
if (type != "main_frame") return
const all = [...quoraRedirects.quetre.normal, ...quetreNormalCustomRedirects]
if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return
if (!targets.some(rx => rx.test(url.href))) return
let instancesList = []
if (protocol == "loki") instancesList = [...quetreLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...quetreI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...quetreTorRedirectsChecks, ...quetreTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...quetreNormalRedirectsChecks, ...quetreNormalCustomRedirects]
}
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
return `${randomInstance}${url.pathname}`
}
function reverse(url) {
return new Promise(async resolve => {
await init()
let protocolHost = utils.protocolHost(url)
const all = [...quoraRedirects.quetre.normal, ...quoraRedirects.quetre.tor, ...quetreNormalCustomRedirects, ...quetreTorCustomRedirects, ...quetreI2pCustomRedirects, ...quetreLokiCustomRedirects]
if (!all.includes(protocolHost)) {
resolve()
return
}
resolve(`https://quora.com${url.pathname}${url.search}`)
})
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableQuora && !disableOverride) {
resolve()
return
}
let protocolHost = utils.protocolHost(url)
const all = [...quoraRedirects.quetre.tor, ...quoraRedirects.quetre.normal, ...quetreNormalCustomRedirects, ...quetreTorCustomRedirects, ...quetreI2pCustomRedirects, ...quetreLokiCustomRedirects]
if (!all.includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...quetreLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...quetreI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...quetreTorRedirectsChecks, ...quetreTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...quetreNormalRedirectsChecks, ...quetreNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
quetreNormalRedirectsChecks = [...redirects.quetre.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = quetreNormalRedirectsChecks.indexOf(instance)
if (a > -1) quetreNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableQuora: false,
quoraRedirects: redirects,
quetreNormalRedirectsChecks,
quetreNormalCustomRedirects: [],
quetreTorRedirectsChecks: [...redirects.quetre.tor],
quetreTorCustomRedirects: [],
quetreI2pRedirectsChecks: [...redirects.quetre.i2p],
quetreI2pCustomRedirects: [],
quetreLokiRedirectsChecks: [...redirects.quetre.loki],
quetreLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
reverse,
switchInstance,
initDefaults,
}

View File

@ -1,402 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}(www\.|old\.|np\.|new\.|amp\.|)reddit\.com/, /^https?:\/{2}(i\.|preview\.)redd\.it/]
let redirects = {}
const frontends = new Array("libreddit", "teddit")
const protocols = new Array("normal", "tor", "i2p", "loki")
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects = val
libredditNormalRedirectsChecks = [...redirects.libreddit.normal]
tedditNormalRedirectsChecks = [...redirects.teddit.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = libredditNormalRedirectsChecks.indexOf(instance)
if (a > -1) libredditNormalRedirectsChecks.splice(a, 1)
const b = tedditNormalRedirectsChecks.indexOf(instance)
if (b > -1) tedditNormalRedirectsChecks.splice(b, 1)
}
browser.storage.local.set(
{
redditRedirects: redirects,
libredditNormalRedirectsChecks,
libredditTorRedirectsChecks: [...redirects.libreddit.tor],
libredditI2pRedirectsChecks: [...redirects.libreddit.i2p],
libredditLokiRedirectsChecks: [...redirects.libreddit.loki],
tedditNormalRedirectsChecks,
tedditTorRedirectsChecks: [...redirects.teddit.tor],
tedditI2pRedirectsChecks: [...redirects.teddit.i2p],
tedditLokiRedirectsChecks: [...redirects.teddit.loki],
},
() => resolve()
)
})
)
}
let disableReddit,
redditFrontend,
redditRedirects,
protocol,
protocolFallback,
libredditNormalRedirectsChecks,
libredditNormalCustomRedirects,
libredditTorRedirectsChecks,
libredditTorCustomRedirects,
libredditI2pCustomRedirects,
libredditLokiCustomRedirects,
tedditNormalRedirectsChecks,
tedditNormalCustomRedirects,
tedditTorRedirectsChecks,
tedditTorCustomRedirects,
tedditI2pCustomRedirects,
tedditLokiCustomRedirects
function init() {
return new Promise(resolve => {
browser.storage.local.get(
[
"disableReddit",
"redditFrontend",
"redditRedirects",
"protocol",
"protocolFallback",
"libredditNormalRedirectsChecks",
"libredditNormalCustomRedirects",
"libredditTorRedirectsChecks",
"libredditTorCustomRedirects",
"libredditI2pCustomRedirects",
"libredditLokiCustomRedirects",
"tedditNormalRedirectsChecks",
"tedditNormalCustomRedirects",
"tedditTorRedirectsChecks",
"tedditTorCustomRedirects",
"tedditI2pCustomRedirects",
"tedditLokiCustomRedirects",
],
r => {
disableReddit = r.disableReddit
redditFrontend = r.redditFrontend
redditRedirects = r.redditRedirects
protocol = r.protocol
protocolFallback = r.protocolFallback
libredditNormalRedirectsChecks = r.libredditNormalRedirectsChecks
libredditNormalCustomRedirects = r.libredditNormalCustomRedirects
libredditTorRedirectsChecks = r.libredditTorRedirectsChecks
libredditTorCustomRedirects = r.libredditTorCustomRedirects
libredditI2pCustomRedirects = r.libredditI2pCustomRedirects
libredditLokiCustomRedirects = r.libredditLokiCustomRedirects
tedditNormalRedirectsChecks = r.tedditNormalRedirectsChecks
tedditNormalCustomRedirects = r.tedditNormalCustomRedirects
tedditTorRedirectsChecks = r.tedditTorRedirectsChecks
tedditTorCustomRedirects = r.tedditTorCustomRedirects
tedditI2pCustomRedirects = r.tedditI2pCustomRedirects
tedditLokiCustomRedirects = r.tedditLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function initLibredditCookies(test, from) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(from)
if (
![
...libredditNormalRedirectsChecks,
...libredditTorRedirectsChecks,
...libredditNormalCustomRedirects,
...libredditTorCustomRedirects,
...libredditI2pCustomRedirects,
...libredditLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...libredditLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...libredditI2pCustomRedirects]
else if (protocol == "tor") checkedInstances = [...libredditTorRedirectsChecks, ...libredditTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...libredditNormalRedirectsChecks, ...libredditNormalCustomRedirects]
}
await utils.copyCookie("libreddit", from, checkedInstances, "theme")
await utils.copyCookie("libreddit", from, checkedInstances, "front_page")
await utils.copyCookie("libreddit", from, checkedInstances, "layout")
await utils.copyCookie("libreddit", from, checkedInstances, "wide")
await utils.copyCookie("libreddit", from, checkedInstances, "post_sort")
await utils.copyCookie("libreddit", from, checkedInstances, "comment_sort")
await utils.copyCookie("libreddit", from, checkedInstances, "show_nsfw")
await utils.copyCookie("libreddit", from, checkedInstances, "autoplay_videos")
await utils.copyCookie("libreddit", from, checkedInstances, "use_hls")
await utils.copyCookie("libreddit", from, checkedInstances, "hide_hls_notification")
await utils.copyCookie("libreddit", from, checkedInstances, "subscriptions")
await utils.copyCookie("libreddit", from, checkedInstances, "filters")
}
resolve(true)
})
}
function initTedditCookies(test, from) {
return new Promise(async resolve => {
await init()
let protocolHost = utils.protocolHost(from)
if (
![...tedditNormalRedirectsChecks, ...tedditTorRedirectsChecks, ...tedditNormalCustomRedirects, ...tedditTorCustomRedirects, ...tedditI2pCustomRedirects, ...tedditI2pCustomRedirects].includes(
protocolHost
)
)
resolve()
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...tedditLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...tedditI2pCustomRedirects]
else if (protocol == "tor") checkedInstances = [...tedditTorRedirectsChecks, ...tedditTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...tedditNormalRedirectsChecks, ...tedditNormalCustomRedirects]
}
await utils.copyCookie("teddit", from, checkedInstances, "collapse_child_comments")
await utils.copyCookie("teddit", from, checkedInstances, "domain_instagram")
await utils.copyCookie("teddit", from, checkedInstances, "domain_twitter")
await utils.copyCookie("teddit", from, checkedInstances, "domain_youtube")
await utils.copyCookie("teddit", from, checkedInstances, "flairs")
await utils.copyCookie("teddit", from, checkedInstances, "highlight_controversial")
await utils.copyCookie("teddit", from, checkedInstances, "nsfw_enabled")
await utils.copyCookie("teddit", from, checkedInstances, "post_media_max_height")
await utils.copyCookie("teddit", from, checkedInstances, "show_upvoted_percentage")
await utils.copyCookie("teddit", from, checkedInstances, "show_upvotes")
await utils.copyCookie("teddit", from, checkedInstances, "theme")
await utils.copyCookie("teddit", from, checkedInstances, "videos_muted")
}
resolve(true)
})
}
function all() {
return [
...redditRedirects.libreddit.normal,
...redditRedirects.libreddit.tor,
...redditRedirects.teddit.normal,
...redditRedirects.teddit.tor,
...libredditNormalCustomRedirects,
...libredditTorCustomRedirects,
...libredditI2pCustomRedirects,
...libredditLokiCustomRedirects,
...tedditNormalCustomRedirects,
...tedditTorCustomRedirects,
...tedditI2pCustomRedirects,
...tedditLokiCustomRedirects,
]
}
// https://libreddit.exonip.de/vid/1mq8d0ma3yk81/720.mp4
// https://libreddit.exonip.de/img/4v3t1vgvrzk81.png
// https://teddit.net/vids/1mq8d0ma3yk81.mp4
// https://teddit.net/pics/w:null_4v3t1vgvrzk81.png
// redd.it/t5379n
// https://v.redd.it/z08avb339n801/DASH_1_2_M
// https://i.redd.it/bfkhs659tzk81.jpg
function redirect(url, type, initiator, disableOverride) {
if (disableReddit && !disableOverride) return
if (!targets.some(rx => rx.test(url.href))) return
if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
if (!["main_frame", "xmlhttprequest", "other", "image", "media"].includes(type)) return
const bypassPaths = /\/(gallery\/poll\/rpan\/settings\/topics)/
if (url.pathname.match(bypassPaths)) return
let libredditInstancesList = []
let tedditInstancesList = []
if (protocol == "loki") {
libredditInstancesList = [...libredditLokiCustomRedirects]
tedditInstancesList = [...tedditLokiCustomRedirects]
} else if (protocol == "i2p") {
libredditInstancesList = [...libredditI2pCustomRedirects]
tedditInstancesList = [...tedditI2pCustomRedirects]
} else if (protocol == "tor") {
libredditInstancesList = [...libredditTorRedirectsChecks, ...libredditTorCustomRedirects]
tedditInstancesList = [...tedditTorRedirectsChecks, ...tedditTorCustomRedirects]
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
libredditInstancesList = [...libredditNormalRedirectsChecks, ...libredditNormalCustomRedirects]
tedditInstancesList = [...tedditNormalRedirectsChecks, ...tedditNormalCustomRedirects]
}
if (url.host === "i.redd.it") {
if (redditFrontend == "teddit") {
if (tedditInstancesList.length === 0) return
let tedditRandomInstance = utils.getRandomInstance(tedditInstancesList)
return `${tedditRandomInstance}/pics/w:null_${url.pathname.substring(1)}${url.search}`
}
if (redditFrontend == "libreddit") {
if (libredditInstancesList.length === 0) return
let libredditRandomInstance = utils.getRandomInstance(libredditInstancesList)
return `${libredditRandomInstance}/img${url.pathname}${url.search}`
}
} else if (url.host === "redd.it") {
if (redditFrontend == "libreddit" && !url.pathname.match(/^\/+[^\/]+\/+[^\/]/)) {
if (libredditInstancesList.length === 0) return
let libredditRandomInstance = utils.getRandomInstance(libredditInstancesList)
// https://redd.it/foo => https://libredd.it/comments/foo
return `${libredditRandomInstance}/comments${url.pathname}${url.search}`
}
if (redditFrontend == "teddit" && !url.pathname.match(/^\/+[^\/]+\/+[^\/]/)) {
if (tedditInstancesList.length === 0) return
let tedditRandomInstance = utils.getRandomInstance(tedditInstancesList)
// https://redd.it/foo => https://teddit.net/comments/foo
return `${tedditRandomInstance}/comments${url.pathname}${url.search}`
}
} else if (url.host === "preview.redd.it") {
if (redditFrontend == "teddit") return
if (redditFrontend == "libreddit") {
if (libredditInstancesList.length === 0) return
const libredditRandomInstance = utils.getRandomInstance(libredditInstancesList)
return `${libredditRandomInstance}/preview/pre${url.pathname}${url.search}`
}
}
let randomInstance
if (redditFrontend == "libreddit") {
if (libredditInstancesList.length === 0) return
randomInstance = utils.getRandomInstance(libredditInstancesList)
}
if (redditFrontend == "teddit") {
if (tedditInstancesList.length === 0) return
randomInstance = utils.getRandomInstance(tedditInstancesList)
}
return `${randomInstance}${url.pathname}${url.search}`
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableReddit && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (redditFrontend == "libreddit") {
if (protocol == "loki") instancesList = [...libredditLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...libredditI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...libredditTorRedirectsChecks, ...libredditTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...libredditNormalRedirectsChecks, ...libredditNormalCustomRedirects]
}
if ([...redditRedirects.teddit.normal, ...redditRedirects.teddit.tor].includes(protocolHost)) {
url.pathname = url.pathname.replace("/pics/w:null_", "/img/")
}
} else if (redditFrontend == "teddit") {
if (protocol == "loki") instancesList = [...tedditLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...tedditI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...tedditTorRedirectsChecks, ...tedditTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...tedditNormalRedirectsChecks, ...tedditNormalCustomRedirects]
}
if ([...redditRedirects.libreddit.normal, ...redditRedirects.libreddit.tor].includes(protocolHost)) {
url.pathname = url.pathname.replace("/img/", "/pics/w:null_")
}
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (const frontend of frontends) redirects[frontend] = dataJson[frontend]
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
libredditNormalRedirectsChecks = [...redirects.libreddit.normal]
tedditNormalRedirectsChecks = [...redirects.teddit.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = libredditNormalRedirectsChecks.indexOf(instance)
if (a > -1) libredditNormalRedirectsChecks.splice(a, 1)
const b = tedditNormalRedirectsChecks.indexOf(instance)
if (b > -1) tedditNormalRedirectsChecks.splice(b, 1)
}
browser.storage.local.set(
{
disableReddit: false,
redditFrontend: "libreddit",
redditRedirects: redirects,
libredditNormalRedirectsChecks,
libredditNormalCustomRedirects: [],
libredditTorRedirectsChecks: [...redirects.libreddit.tor],
libredditTorCustomRedirects: [],
libredditI2pRedirectsChecks: [...redirects.libreddit.i2p],
libredditI2pCustomRedirects: [],
libredditLokiRedirectsChecks: [...redirects.libreddit.loki],
libredditLokiCustomRedirects: [],
tedditNormalRedirectsChecks,
tedditNormalCustomRedirects: [],
tedditTorRedirectsChecks: [...redirects.teddit.tor],
tedditTorCustomRedirects: [],
tedditI2pRedirectsChecks: [...redirects.teddit.i2p],
tedditI2pCustomRedirects: [],
tedditLokiRedirectsChecks: [...redirects.teddit.loki],
tedditLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
initLibredditCookies,
initTedditCookies,
redirect,
initDefaults,
switchInstance,
}

View File

@ -1,155 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}(www\.|)reuters\.com.*/]
const frontends = new Array("neuters")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.neuters = val
neutersNormalRedirectsChecks = [...redirects.neuters.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = neutersNormalRedirectsChecks.indexOf(instance)
if (a > -1) neutersNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
neutersRedirects: redirects,
neutersNormalRedirectsChecks,
neutersTorRedirectsChecks: [...redirects.neuters.tor],
neutersI2pRedirectsChecks: [...redirects.neuters.i2p],
neutersLokiRedirectsChecks: [...redirects.neuters.loki],
},
() => resolve()
)
})
)
}
let disableReuters,
protocol,
protocolFallback,
reutersRedirects,
neutersNormalRedirectsChecks,
neutersNormalCustomRedirects,
neutersTorRedirectsChecks,
neutersTorCustomRedirects,
neutersI2pCustomRedirects,
neutersLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableReuters",
"protocol",
"protocolFallback",
"reutersRedirects",
"neutersNormalRedirectsChecks",
"neutersNormalCustomRedirects",
"neutersTorRedirectsChecks",
"neutersTorCustomRedirects",
"neutersI2pCustomRedirects",
"neutersLokiCustomRedirects",
],
r => {
disableReuters = r.disableReuters
protocol = r.protocol
protocolFallback = r.protocolFallback
reutersRedirects = r.reutersRedirects
neutersNormalRedirectsChecks = r.neutersNormalRedirectsChecks
neutersNormalCustomRedirects = r.neutersNormalCustomRedirects
neutersTorRedirectsChecks = r.neutersTorRedirectsChecks
neutersTorCustomRedirects = r.neutersTorCustomRedirects
neutersI2pCustomRedirects = r.neutersI2pCustomRedirects
neutersLokiCustomRedirects = r.neutersLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function redirect(url, type, initiator, disableOverride) {
if (disableReuters && !disableOverride) return
if (type != "main_frame") return
const all = [...reutersRedirects.neuters.normal, ...neutersNormalCustomRedirects]
if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return
if (!targets.some(rx => rx.test(url.href))) return
let instancesList = []
if (protocol == "loki") instancesList = [...neutersLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...neutersI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...neutersTorRedirectsChecks, ...neutersTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...neutersNormalRedirectsChecks, ...neutersNormalCustomRedirects]
}
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
// stolen from https://addons.mozilla.org/en-US/firefox/addon/reuters-redirect/
if (url.pathname.startsWith("/article/") || url.pathname.startsWith("/pf/") || url.pathname.startsWith("/arc/") || url.pathname.startsWith("/resizer/")) return null
else if (url.pathname.endsWith("/")) return `${randomInstance}${url.pathname}`
else return `${randomInstance}${url.pathname}/`
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
neutersNormalRedirectsChecks = [...redirects.neuters.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = neutersNormalRedirectsChecks.indexOf(instance)
if (a > -1) neutersNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableReuters: true,
reutersRedirects: redirects,
neutersNormalRedirectsChecks,
neutersNormalCustomRedirects: [],
neutersTorRedirectsChecks: [...redirects.neuters.tor],
neutersTorCustomRedirects: [],
neutersI2pRedirectsChecks: [...redirects.neuters.i2p],
neutersI2pCustomRedirects: [],
neutersLokiRedirectsChecks: [...redirects.neuters.loki],
neutersLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
initDefaults,
}

View File

@ -1,581 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}search\.libredirect\.invalid/]
// Ill optimise all of assets/javascripts at a later date. For now, I'll just add librex and optimse options javascript
const frontends = new Array("searx", "searxng", "whoogle", "librex")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects = val
searxNormalRedirectsChecks = [...redirects.searx.normal]
searxngNormalRedirectsChecks = [...redirects.searxng.normal]
whoogleNormalRedirectsChecks = [...redirects.whoogle.normal]
librexNormalRedirectsChecks = [...redirects.librex.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = searxNormalRedirectsChecks.indexOf(instance)
if (a > -1) searxNormalRedirectsChecks.splice(a, 1)
const b = searxngNormalRedirectsChecks.indexOf(instance)
if (b > -1) searxngNormalRedirectsChecks.splice(b, 1)
const c = whoogleNormalRedirectsChecks.indexOf(instance)
if (c > -1) whoogleNormalRedirectsChecks.splice(c, 1)
const d = librexNormalRedirectsChecks.indexOf(instance)
if (d > -1) librexNormalRedirectsChecks.splice(d, 1)
}
browser.storage.local.set(
{
searchRedirects: redirects,
searxNormalRedirectsChecks,
searxTorRedirectsChecks: [...redirects.searx.tor],
searxI2pRedirectsChecks: [...redirects.searx.i2p],
searxLokiRedirectsChecks: [...redirects.searx.loki],
searxngNormalRedirectsChecks,
searxngTorRedirectsChecks: [...redirects.searxng.tor],
searxngI2pRedirectsChecks: [...redirects.searxng.i2p],
searxngLokiRedirectsChecks: [...redirects.searxng.loki],
whoogleNormalRedirectsChecks,
whoogleTorRedirectsChecks: [...redirects.whoogle.tor],
whoogleI2pRedirectsChecks: [...redirects.whoogle.i2p],
whoogleLokiRedirectsChecks: [...redirects.whoogle.loki],
librexNormalRedirectsChecks,
librexTorRedirectsChecks: [...redirects.librex.tor],
librexI2pRedirectsChecks: [...redirects.librex.i2p],
librexLokiRedirectsChecks: [...redirects.librex.loki],
},
() => resolve()
)
})
)
}
let disableSearch,
searchFrontend,
searchRedirects,
protocol,
protocolFallback,
whoogleNormalRedirectsChecks,
whoogleNormalCustomRedirects,
whoogleTorRedirectsChecks,
whoogleTorCustomRedirects,
whoogleI2pRedirectsChecks,
whoogleI2pCustomRedirects,
whoogleLokiCustomRedirects,
searxNormalRedirectsChecks,
searxNormalCustomRedirects,
searxTorRedirectsChecks,
searxTorCustomRedirects,
searxI2pRedirectsChecks,
searxI2pCustomRedirects,
searxLokiCustomRedirects,
searxngNormalRedirectsChecks,
searxngNormalCustomRedirects,
searxngTorRedirectsChecks,
searxngTorCustomRedirects,
searxngI2pRedirectsChecks,
searxngI2pCustomRedirects,
searxngLokiCustomRedirects,
librexNormalRedirectsChecks,
librexNormalCustomRedirects,
librexTorRedirectsChecks,
librexTorCustomRedirects,
librexI2pRedirectsChecks,
librexI2pCustomRedirects,
librexLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableSearch",
"searchFrontend",
"searchRedirects",
"protocol",
"protocolFallback",
"whoogleNormalRedirectsChecks",
"whoogleNormalCustomRedirects",
"whoogleTorRedirectsChecks",
"whoogleTorCustomRedirects",
"whoogleI2pRedirectsChecks",
"whoogleI2pCustomRedirects",
"whoogleLokiCustomRedirects",
"searxNormalRedirectsChecks",
"searxNormalCustomRedirects",
"searxTorRedirectsChecks",
"searxTorCustomRedirects",
"searxI2pRedirectsChecks",
"searxI2pCustomRedirects",
"searxLokiCustomRedirects",
"searxngNormalRedirectsChecks",
"searxngNormalCustomRedirects",
"searxngTorRedirectsChecks",
"searxngTorCustomRedirects",
"searxngI2pRedirectsChecks",
"searxngI2pCustomRedirects",
"searxngLokiCustomRedirects",
"librexNormalRedirectsChecks",
"librexNormalCustomRedirects",
"librexTorRedirectsChecks",
"librexTorCustomRedirects",
"librexI2pRedirectsChecks",
"librexI2pCustomRedirects",
"librexLokiCustomRedirects",
],
r => {
disableSearch = r.disableSearch
searchFrontend = r.searchFrontend
searchRedirects = r.searchRedirects
protocol = r.protocol
protocolFallback = r.protocolFallback
whoogleNormalRedirectsChecks = r.whoogleNormalRedirectsChecks
whoogleNormalCustomRedirects = r.whoogleNormalCustomRedirects
whoogleTorRedirectsChecks = r.whoogleTorRedirectsChecks
whoogleTorCustomRedirects = r.whoogleTorCustomRedirects
whoogleI2pRedirectsChecks = r.whoogleI2pRedirectsChecks
whoogleI2pCustomRedirects = r.whoogleI2pCustomRedirects
whoogleLokiCustomRedirects = r.whoogleLokiCustomRedirects
searxNormalRedirectsChecks = r.searxNormalRedirectsChecks
searxNormalCustomRedirects = r.searxNormalCustomRedirects
searxTorRedirectsChecks = r.searxTorRedirectsChecks
searxTorCustomRedirects = r.searxTorCustomRedirects
searxI2pRedirectsChecks = r.searxI2pRedirectsChecks
searxI2pCustomRedirects = r.searxI2pCustomRedirects
searxLokiCustomRedirects = r.searxLokiCustomRedirects
searxngNormalRedirectsChecks = r.searxngNormalRedirectsChecks
searxngNormalCustomRedirects = r.searxngNormalCustomRedirects
searxngTorRedirectsChecks = r.searxngTorRedirectsChecks
searxngTorCustomRedirects = r.searxngTorCustomRedirects
searxngI2pRedirectsChecks = r.searxngI2pRedirectsChecks
searxngI2pCustomRedirects = r.searxngI2pCustomRedirects
searxngLokiCustomRedirects = r.searxngLokiCustomRedirects
librexNormalRedirectsChecks = r.librexNormalRedirectsChecks
librexNormalCustomRedirects = r.librexNormalCustomRedirects
librexTorRedirectsChecks = r.librexTorRedirectsChecks
librexTorCustomRedirects = r.librexTorCustomRedirects
librexI2pRedirectsChecks = r.librexI2pRedirectsChecks
librexI2pCustomRedirects = r.librexI2pCustomRedirects
librexLokiCustomRedirects = r.librexLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function initSearxCookies(test, from) {
return new Promise(async resolve => {
await init()
let protocolHost = utils.protocolHost(from)
if (
![
...searxNormalRedirectsChecks,
...searxNormalCustomRedirects,
...searxTorRedirectsChecks,
...searxTorCustomRedirects,
...searxI2pRedirectsChecks,
...searxI2pCustomRedirects,
...searxLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...searxLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...searxI2pCustomRedirects, ...searxI2pRedirectsChecks]
else if (protocol == "tor") checkedInstances = [...searxTorRedirectsChecks, ...searxTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...searxNormalRedirectsChecks, ...searxNormalCustomRedirects]
}
await utils.copyCookie("searx", from, checkedInstances, "advanced_search")
await utils.copyCookie("searx", from, checkedInstances, "autocomplete")
await utils.copyCookie("searx", from, checkedInstances, "categories")
await utils.copyCookie("searx", from, checkedInstances, "disabled_engines")
await utils.copyCookie("searx", from, checkedInstances, "disabled_plugins")
await utils.copyCookie("searx", from, checkedInstances, "doi_resolver")
await utils.copyCookie("searx", from, checkedInstances, "enabled_engines")
await utils.copyCookie("searx", from, checkedInstances, "enabled_plugins")
await utils.copyCookie("searx", from, checkedInstances, "image_proxy")
await utils.copyCookie("searx", from, checkedInstances, "language")
await utils.copyCookie("searx", from, checkedInstances, "locale")
await utils.copyCookie("searx", from, checkedInstances, "method")
await utils.copyCookie("searx", from, checkedInstances, "oscar-style")
await utils.copyCookie("searx", from, checkedInstances, "results_on_new_tab")
await utils.copyCookie("searx", from, checkedInstances, "safesearch")
await utils.copyCookie("searx", from, checkedInstances, "theme")
await utils.copyCookie("searx", from, checkedInstances, "tokens")
}
resolve(true)
})
}
function initSearxngCookies(test, from) {
return new Promise(async resolve => {
await init()
let protocolHost = utils.protocolHost(from)
if (
![
...searxngNormalRedirectsChecks,
...searxngNormalCustomRedirects,
...searxngTorRedirectsChecks,
...searxngTorCustomRedirects,
...searxngI2pRedirectsChecks,
...searxngI2pCustomRedirects,
...searxngLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...searxngLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...searxngI2pCustomRedirects, ...searxngI2pRedirectsChecks]
else if (protocol == "tor") checkedInstances = [...searxngTorRedirectsChecks, ...searxngTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...searxngNormalRedirectsChecks, ...searxngNormalCustomRedirects]
}
await utils.copyCookie("searxng", from, checkedInstances, "autocomplete")
await utils.copyCookie("searxng", from, checkedInstances, "categories")
await utils.copyCookie("searxng", from, checkedInstances, "disabled_engines")
await utils.copyCookie("searxng", from, checkedInstances, "disabled_plugins")
await utils.copyCookie("searxng", from, checkedInstances, "doi_resolver")
await utils.copyCookie("searxng", from, checkedInstances, "enabled_plugins")
await utils.copyCookie("searxng", from, checkedInstances, "enabled_engines")
await utils.copyCookie("searxng", from, checkedInstances, "image_proxy")
await utils.copyCookie("searxng", from, checkedInstances, "infinite_scroll")
await utils.copyCookie("searxng", from, checkedInstances, "language")
await utils.copyCookie("searxng", from, checkedInstances, "locale")
await utils.copyCookie("searxng", from, checkedInstances, "maintab")
await utils.copyCookie("searxng", from, checkedInstances, "method")
await utils.copyCookie("searxng", from, checkedInstances, "query_in_title")
await utils.copyCookie("searxng", from, checkedInstances, "results_on_new_tab")
await utils.copyCookie("searxng", from, checkedInstances, "safesearch")
await utils.copyCookie("searxng", from, checkedInstances, "simple_style")
await utils.copyCookie("searxng", from, checkedInstances, "theme")
await utils.copyCookie("searxng", from, checkedInstances, "tokens")
}
resolve(true)
})
}
function initLibrexCookies(test, from) {
return new Promise(async resolve => {
await init()
let protocolHost = utils.protocolHost(from)
if (
![
...librexNormalRedirectsChecks,
...librexNormalCustomRedirects,
...librexTorRedirectsChecks,
...librexTorCustomRedirects,
...librexI2pRedirectsChecks,
...librexI2pCustomRedirects,
...librexLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...librexLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...librexI2pCustomRedirects, ...librexI2pRedirectsChecks]
else if (protocol == "tor") checkedInstances = [...librexTorRedirectsChecks, ...librexTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...librexNormalRedirectsChecks, ...librexNormalCustomRedirects]
}
await utils.copyCookie("librex", from, checkedInstances, "bibliogram")
await utils.copyCookie("librex", from, checkedInstances, "disable_special")
await utils.copyCookie("librex", from, checkedInstances, "invidious")
await utils.copyCookie("librex", from, checkedInstances, "libreddit")
await utils.copyCookie("librex", from, checkedInstances, "nitter")
await utils.copyCookie("librex", from, checkedInstances, "proxitok")
await utils.copyCookie("librex", from, checkedInstances, "theme")
await utils.copyCookie("librex", from, checkedInstances, "wikiless")
}
resolve(true)
})
}
function redirect(url, disableOverride) {
if (disableSearch && !disableOverride) return
if (!targets.some(rx => rx.test(url.href))) return
if (url.searchParams.has("tbm")) return
if (url.hostname.includes("google") && !url.searchParams.has("q") && url.pathname != "/") return
let randomInstance
let path
if (searchFrontend == "searx") {
let instancesList = []
if (protocol == "loki") instancesList = [...searxLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...searxI2pCustomRedirects, ...searxI2pRedirectsChecks]
else if (protocol == "tor") instancesList = [...searxTorRedirectsChecks, ...searxTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...searxNormalRedirectsChecks, ...searxNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
randomInstance = utils.getRandomInstance(instancesList)
path = "/"
} else if (searchFrontend == "searxng") {
let instancesList = []
if (protocol == "loki") instancesList = [...searxngLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...searxngI2pCustomRedirects, ...searxngI2pRedirectsChecks]
else if (protocol == "tor") instancesList = [...searxngTorRedirectsChecks, ...searxngTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...searxngNormalRedirectsChecks, ...searxngNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
randomInstance = utils.getRandomInstance(instancesList)
path = "/"
} else if (searchFrontend == "whoogle") {
let instancesList = []
if (protocol == "loki") instancesList = [...whoogleLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...whoogleI2pCustomRedirects, ...whoogleI2pRedirectsChecks]
else if (protocol == "tor") instancesList = [...whoogleTorRedirectsChecks, ...whoogleTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...whoogleNormalRedirectsChecks, ...whoogleNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
randomInstance = utils.getRandomInstance(instancesList)
path = "/search"
} else if (searchFrontend == "librex") {
let instancesList = []
if (protocol == "loki") instancesList = [...librexLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...librexI2pCustomRedirects, ...librexI2pRedirectsChecks]
else if (protocol == "tor") instancesList = [...librexTorRedirectsChecks, ...librexTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...librexNormalRedirectsChecks, ...librexNormalCustomRedirects]
}
if (instancesList.length === 0) {
return
}
randomInstance = utils.getRandomInstance(instancesList)
path = "/search.php"
}
if (((url.hostname.includes("google") || url.hostname.includes("bing")) && !url.searchParams.has("q")) || (url.hostname.includes("yandex") && !url.searchParams.has("text"))) path = "/"
let searchQuery = ""
if ((url.hostname.includes("google") || url.hostname.includes("bing") || url.hostname.includes("search.libredirect.invalid")) && url.searchParams.has("q"))
searchQuery = `?q=${encodeURIComponent(url.searchParams.get("q"))}`
if (url.hostname.includes("yandex") && url.searchParams.has("text")) searchQuery = `?q=${url.searchParams.get("text")}`
return `${randomInstance}${path}${searchQuery}`
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableSearch && !disableOverride) {
resolve()
return
}
let protocolHost = utils.protocolHost(url)
if (
![
...searchRedirects.searx.normal,
...searchRedirects.searx.tor,
...searchRedirects.searx.i2p,
...searchRedirects.searxng.normal,
...searchRedirects.searxng.tor,
...searchRedirects.searxng.i2p,
...searchRedirects.whoogle.normal,
...searchRedirects.whoogle.tor,
...searchRedirects.whoogle.i2p,
...searchRedirects.librex.normal,
...searchRedirects.librex.tor,
...searchRedirects.librex.i2p,
...searxNormalCustomRedirects,
...searxTorCustomRedirects,
...searxI2pCustomRedirects,
...searxLokiCustomRedirects,
...searxngNormalCustomRedirects,
...searxngTorCustomRedirects,
...searxngI2pCustomRedirects,
...searxngLokiCustomRedirects,
...whoogleNormalCustomRedirects,
...whoogleTorCustomRedirects,
...whoogleI2pCustomRedirects,
...whoogleLokiCustomRedirects,
...librexNormalCustomRedirects,
...librexTorCustomRedirects,
...librexI2pCustomRedirects,
...librexLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") {
if (searchFrontend == "searx") instancesList = [...searxLokiCustomRedirects]
else if (searchFrontend == "searxng") instancesList = [...searxngLokiCustomRedirects]
else if (searchFrontend == "whoogle") instancesList = [...whoogleLokiCustomRedirects]
else if (searchFrontend == "librex") instancesList = [...librexLokiCustomRedirects]
} else if (protocol == "tor") {
if (searchFrontend == "searx") instancesList = [...searxTorRedirectsChecks, ...searxTorCustomRedirects]
else if (searchFrontend == "searxng") instancesList = [...searxngTorRedirectsChecks, ...searxngTorCustomRedirects]
else if (searchFrontend == "whoogle") instancesList = [...whoogleTorRedirectsChecks, ...whoogleTorCustomRedirects]
else if (searchFrontend == "librex") instancesList = [...librexTorRedirectsChecks, ...librexTorCustomRedirects]
} else if (protocol == "i2p") {
if (searchFrontend == "searx") instancesList = [...searxI2pRedirectsChecks, ...searxI2pCustomRedirects]
else if (searchFrontend == "searxng") instancesList = [...searxngI2pRedirectsChecks, ...searxngI2pCustomRedirects]
else if (searchFrontend == "whoogle") instancesList = [...whoogleI2pRedirectsChecks, ...whoogleI2pCustomRedirects]
else if (searchFrontend == "librex") instancesList = [...librexI2pRedirectsChecks, ...librexI2pCustomRedirects]
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
if (searchFrontend == "searx") instancesList = [...searxNormalRedirectsChecks, ...searxNormalCustomRedirects]
else if (searchFrontend == "searxng") instancesList = [...searxngNormalRedirectsChecks, ...searxngNormalCustomRedirects]
else if (searchFrontend == "whoogle") instancesList = [...whoogleNormalRedirectsChecks, ...whoogleNormalCustomRedirects]
else if (searchFrontend == "librex") instancesList = [...librexNormalRedirectsChecks, ...librexNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
searxNormalRedirectsChecks = [...redirects.searx.normal]
searxngNormalRedirectsChecks = [...redirects.searxng.normal]
whoogleNormalRedirectsChecks = [...redirects.whoogle.normal]
librexNormalRedirectsChecks = [...redirects.librex.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = searxNormalRedirectsChecks.indexOf(instance)
if (a > -1) searxNormalRedirectsChecks.splice(a, 1)
const b = searxngNormalRedirectsChecks.indexOf(instance)
if (b > -1) searxngNormalRedirectsChecks.splice(b, 1)
const c = whoogleNormalRedirectsChecks.indexOf(instance)
if (c > -1) whoogleNormalRedirectsChecks.splice(c, 1)
const d = librexNormalRedirectsChecks.indexOf(instance)
if (d > -1) librexNormalRedirectsChecks.splice(d, 1)
}
browser.storage.local.set(
{
disableSearch: false,
searchFrontend: "searxng",
searchRedirects: redirects,
searxngCustomSettings: false,
whoogleNormalRedirectsChecks,
whoogleNormalCustomRedirects: [],
whoogleTorRedirectsChecks: [...redirects.whoogle.tor],
whoogleTorCustomRedirects: [],
whoogleI2pRedirectsChecks: [...redirects.whoogle.i2p],
whoogleI2pCustomRedirects: [],
whoogleLokiRedirectsChecks: [...redirects.whoogle.loki],
whoogleLokiCustomRedirects: [],
searxNormalRedirectsChecks,
searxNormalCustomRedirects: [],
searxTorRedirectsChecks: [...redirects.searx.tor],
searxTorCustomRedirects: [],
searxI2pRedirectsChecks: [...redirects.searx.i2p],
searxI2pCustomRedirects: [],
searxLokiRedirectsChecks: [...redirects.searx.loki],
searxLokiCustomRedirects: [],
searxngNormalRedirectsChecks,
searxngNormalCustomRedirects: [],
searxngTorRedirectsChecks: [...redirects.searxng.tor],
searxngTorCustomRedirects: [],
searxngI2pRedirectsChecks: [...redirects.searxng.i2p],
searxngI2pCustomRedirects: [],
searxngLokiRedirectsChecks: [...redirects.searxng.loki],
searxngLokiCustomRedirects: [],
librexNormalRedirectsChecks,
librexNormalCustomRedirects: [],
librexTorRedirectsChecks: [...redirects.librex.tor],
librexTorCustomRedirects: [],
librexI2pRedirectsChecks: [...redirects.librex.i2p],
librexI2pCustomRedirects: [],
librexLokiRedirectsChecks: [...redirects.librex.loki],
librexLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
initSearxCookies,
initSearxngCookies,
initLibrexCookies,
redirect,
initDefaults,
switchInstance,
}

View File

@ -1,200 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}send\.libredirect\.invalid\/$/, /^ https ?: \/\/send\.firefox\.com\/$/, /^https?:\/{2}sendfiles\.online\/$/]
const frontends = new Array("send")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.send = val
sendNormalRedirectsChecks = [...redirects.send.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = sendNormalRedirectsChecks.indexOf(instance)
if (a > -1) sendNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
sendTargetsRedirects: redirects,
sendNormalRedirectsChecks,
sendTorRedirectsChecks: [...redirects.send.tor],
sendI2pRedirectsChecks: [...redirects.send.i2p],
sendLokiRedirectsChecks: [...redirects.send.loki],
},
() => resolve()
)
})
)
}
let disableSendTarget,
sendTargetsRedirects,
sendNormalRedirectsChecks,
sendNormalCustomRedirects,
sendTorRedirectsChecks,
sendTorCustomRedirects,
sendI2pCustomRedirects,
sendLokiCustomRedirects,
protocol,
protocolFallback
function init() {
return new Promise(resolve => {
browser.storage.local.get(
[
"disableSendTarget",
"sendTargetsRedirects",
"protocol",
"protocolFallback",
"sendNormalRedirectsChecks",
"sendNormalCustomRedirects",
"sendTorRedirectsChecks",
"sendTorCustomRedirects",
"sendI2pCustomRedirects",
"sendLokiCustomRedirects",
],
r => {
disableSendTarget = r.disableSendTarget
sendTargetsRedirects = r.sendTargetsRedirects
sendNormalRedirectsChecks = r.sendNormalRedirectsChecks
sendNormalCustomRedirects = r.sendNormalCustomRedirects
sendTorRedirectsChecks = r.sendTorRedirectsChecks
sendTorCustomRedirects = r.sendTorCustomRedirects
sendI2pCustomRedirects = r.sendI2pCustomRedirects
sendLokiCustomRedirects = r.sendLokiCustomRedirects
protocol = r.protocol
protocolFallback = r.protocolFallback
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function all() {
return [
...sendTargetsRedirects.send.normal,
...sendTargetsRedirects.send.tor,
...sendNormalCustomRedirects,
...sendTorRedirectsChecks,
...sendTorCustomRedirects,
...sendI2pCustomRedirects,
...sendLokiCustomRedirects,
]
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableSendTarget && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
if (url.pathname != "/") {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...sendLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...sendI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...sendTorRedirectsChecks, ...sendTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...sendNormalRedirectsChecks, ...sendNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function redirect(url, type, initiator, disableOverride) {
if (disableSendTarget && !disableOverride) return
if (type != "main_frame") return
if (initiator && (all().includes(initiator.origin) || targets.includes(initiator.host))) return
if (!targets.some(rx => rx.test(url.href))) return
let instancesList = []
if (protocol == "loki") instancesList = [...sendLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...sendI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...sendTorRedirectsChecks, ...sendTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...sendNormalRedirectsChecks, ...sendNormalCustomRedirects]
}
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
return randomInstance
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
sendNormalRedirectsChecks = [...redirects.send.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = sendNormalRedirectsChecks.indexOf(instance)
if (a > -1) sendNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableSendTarget: false,
sendTargetsRedirects: redirects,
sendNormalRedirectsChecks,
sendNormalCustomRedirects: [],
sendTorRedirectsChecks: [...redirects.send.tor],
sendTorCustomRedirects: [],
sendI2pRedirectsChecks: [...redirects.send.i2p],
sendI2pCustomRedirects: [],
sendLokiRedirectsChecks: [...redirects.send.loki],
sendLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
switchInstance,
initDefaults,
}

View File

@ -0,0 +1,759 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
let config, options, redirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(["options", "redirects"], r => {
options = r.options
redirects = r.redirects
fetch("/config/config.json")
.then(response => response.text())
.then(configData => {
config = JSON.parse(configData)
resolve()
})
})
})
}
init()
browser.storage.onChanged.addListener(init)
function fetchFrontendInstanceList(service, frontend, redirects, options, config) {
let tmp = []
if (config.services[service].frontends[frontend].instanceList) {
for (const network in config.networks) {
tmp.push(...redirects[network], ...options[frontend][network].custom)
}
} else if (config.services[service].frontends[frontend].singleInstance) tmp = config.services[service].frontends[frontend].singleInstance
return tmp
}
function all(service, frontend, options, config, redirects) {
let instances = []
if (!frontend) {
for (const frontend in config.services[service].frontends) {
instances.push(...fetchFrontendInstanceList(service, frontend, redirects[frontend], options, config))
}
} else {
instances.push(...fetchFrontendInstanceList(service, frontend, redirects[frontend], options, config))
}
return instances
}
function regexArray(service, url, config) {
let targets
if (config.services[service].targets == "datajson") {
browser.storage.local.get("targets", r => {
targets = r.targets[service]
})
} else {
targets = config.services[service].targets
}
for (const targetString in targets) {
const target = new RegExp(targets[targetString])
if (target.test(url.href)) return true
}
return false
}
function redirect(url, type, initiator, forceRedirection) {
if (type != "main_frame" && type != "sub_frame") return
let randomInstance
let frontend
for (const service in config.services) {
if (!forceRedirection && !options[service].enabled) continue
if (config.services[service].embeddable && type != options[service].redirectType && options[service].redirectType != "both") continue
if (!config.services[service].embeddable && type != "main_frame") continue
// let targets = new RegExp(config.services[service].targets.join("|"), "i")
if (!regexArray(service, url, config)) continue
// if (initiator) {
// console.log(initiator.host)
// if (targets.test(initiator.host)) continue
// //if (all(service, null, options, config, redirects).includes(initiator.origin) && reverse(initiator) == url) return "BYPASSTAB"
// }
if (Object.keys(config.services[service].frontends).length > 1) {
if (type == "sub_frame" && config.services[service].embeddable && !config.services[service].frontends[options[service].frontend].embeddable) frontend = options[service].embedFrontend
else frontend = options[service].frontend
} else frontend = Object.keys(config.services[service].frontends)[0]
if (config.services[service].frontends[frontend].instanceList) {
let instanceList = [...options[frontend][options.network].enabled, ...options[frontend][options.network].custom]
if (instanceList.length === 0 && options.networkFallback) instanceList = [...options[frontend].clearnet.enabled, ...options[frontend].clearnet.custom]
if (instanceList.length === 0) return
randomInstance = utils.getRandomInstance(instanceList)
} else if (config.services[service].frontends[frontend].singleInstance) randomInstance = config.services[service].frontends[frontend].singleInstance
break
}
if (!frontend) return
// Here is a (temperory) space for defining constants required in 2 or more switch cases.
// When possible, try have the two switch cases share all their code as done with searx and searxng.
// Do not do that when they do not share 100% of their code.
const mapCentreRegex = /@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/
const dataLatLngRegex = /!3d(-?[0-9]{1,}.[0-9]{1,})!4d(-?[0-9]{1,}.[0-9]{1,})/
const placeRegex = /\/place\/(.*)\//
function convertMapCentre() {
let [lat, lon, zoom] = [null, null, null]
if (url.pathname.match(mapCentreRegex)) {
// Set map centre if present
;[lat, lon, zoom] = url.pathname.match(mapCentreRegex)
} else if (url.searchParams.has("center")) {
;[lat, lon] = url.searchParams.get("center").split(",")
zoom = url.searchParams.get("zoom") ?? "17"
}
return [zoom, lon, lat]
}
switch (frontend) {
// This is where all instance-specific code must be ran to convert the service url to one that can be understood by the frontend.
case "beatbump":
return `${randomInstance}${url.pathname}${url.search}`
.replace("/watch?v=", "/listen?id=")
.replace("/channel/", "/artist/")
.replace("/playlist?list=", "/playlist/VL")
.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/") + "?filter=all")
case "hyperpipe":
return `${randomInstance}${url.pathname}${url.search}`.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/"))
case "bibliogram":
const reservedPaths = ["u", "p", "privacy"]
if (url.pathname === "/" || reservedPaths.includes(url.pathname.split("/")[1])) return `${randomInstance}${url.pathname}${url.search}`
if (url.pathname.startsWith("/reel") || url.pathname.startsWith("/tv")) return `${randomInstance}/p${url.pathname.replace(/\/reel|\/tv/i, "")}${url.search}`
else return `${randomInstance}/u${url.pathname}${url.search}` // Likely a user profile, redirect to '/u/...'
case "lbryDesktop":
return url.href.replace(/^https?:\/{2}odysee\.com\//, "lbry://").replace(/:(?=[a-zA-Z0-9])/g, "#")
case "neuters":
if (url.pathname.startsWith("/article/") || url.pathname.startsWith("/pf/") || url.pathname.startsWith("/arc/") || url.pathname.startsWith("/resizer/")) return null
else if (url.pathname.endsWith("/")) return `${randomInstance}${url.pathname}`
else return `${randomInstance}${url.pathname}/`
case "searx":
case "searxng":
return `${randomInstance}/?q=${encodeURIComponent(url.searchParams.get("q"))}`
case "whoogle":
return `${randomInstance}/search${encodeURIComponent(url.searchParams.get("q"))}`
case "librex":
return `${randomInstance}/search.php?q=${encodeURIComponent(url.searchParams.get("q"))}`
case "send":
return randomInstance
case "nitter":
let search = new URLSearchParams(url.search)
search.delete("ref_src")
search.delete("ref_url")
search = search.toString()
if (search !== "") search = `?${search}`
if (url.host.split(".")[0] === "pbs" || url.host.split(".")[0] === "video") {
try {
const [, id, format, extra] = search.match(/(.*)\?format=(.*)&(.*)/)
const query = encodeURIComponent(`${id}.${format}?${extra}`)
return `${randomInstance}/pic${url.pathname}${query}`
} catch {
return `${randomInstance}/pic${url.pathname}${search}`
}
}
if (url.pathname.split("/").includes("tweets")) return `${randomInstance}${url.pathname.replace("/tweets", "")}${search}`
if (url.host == "t.co") return `${randomInstance}/t.co${url.pathname}`
return `${randomInstance}${url.pathname}${search}`
case "yattee":
return url.href.replace(/^https?:\/{2}/, "yattee://")
case "freetube":
return `freetube://https://youtu.be${url.pathname}${url.search}`.replace(/watch\?v=/, "")
case "simplyTranslate":
return `${randomInstance}/${url.search}`
case "libreTranslate":
return `${randomInstance}/${url.search}`
.replace(/(?<=\/?)sl/, "source")
.replace(/(?<=&)tl/, "target")
.replace(/(?<=&)text/, "q")
case "osm": {
if (initiator && initiator.host === "earth.google.com") return
const travelModes = {
driving: "fossgis_osrm_car",
walking: "fossgis_osrm_foot",
bicycling: "fossgis_osrm_bike",
transit: "fossgis_osrm_car", // not implemented on OSM, default to car.
}
function addressToLatLng(address) {
const xmlhttp = new XMLHttpRequest()
xmlhttp.open("GET", `https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`, false)
xmlhttp.send()
if (xmlhttp.status === 200) {
const json = JSON.parse(xmlhttp.responseText)[0]
if (json) {
console.log("json", json)
return [`${json.lat},${json.lon}`, `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}`]
}
}
console.info("Error: Status is " + xmlhttp.status)
}
let mapCentre = "#"
let prefs = {}
const mapCentreData = convertMapCentre()
if (mapCentreData[0] && mapCentreData[1] && mapCentreData[2]) mapCentre = `#map=${mapCentreData[0]}/${mapCentreData[1]}/${mapCentreData[2]}`
if (url.searchParams.get("layer")) prefs.layers = osmLayers[url.searchParams.get("layer")]
if (url.pathname.includes("/embed")) {
// Handle Google Maps Embed API
// https://www.google.com/maps/embed/v1/place?key=AIzaSyD4iE2xVSpkLLOXoyqT-RuPwURN3ddScAI&q=Eiffel+Tower,Paris+France
//console.log("embed life")
let query = ""
if (url.searchParams.has("q")) query = url.searchParams.get("q")
else if (url.searchParams.has("query")) query = url.searchParams.has("query")
else if (url.searchParams.has("pb"))
try {
query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1]
} catch (error) {
console.error(error)
} // Unable to find map marker in URL.
let [coords, boundingbox] = addressToLatLng(query)
prefs.bbox = boundingbox
prefs.marker = coords
prefs.layer = "mapnik"
let prefsEncoded = new URLSearchParams(prefs).toString()
return `${randomInstance}/export/embed.html?${prefsEncoded}`
} else if (url.pathname.includes("/dir")) {
// Handle Google Maps Directions
// https://www.google.com/maps/dir/?api=1&origin=Space+Needle+Seattle+WA&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling
let travMod = url.searchParams.get("travelmode")
if (url.searchParams.has("travelmode")) prefs.engine = travelModes[travMod]
let orgVal = url.searchParams.get("origin")
let destVal = url.searchParams.get("destination")
let org = addressToLatLng(orgVal)
let dest = addressToLatLng(destVal)
prefs.route = `${org};${dest}`
let prefsEncoded = new URLSearchParams(prefs).toString()
return `${randomInstance}/directions?${prefsEncoded}${mapCentre}`
} else if (url.pathname.includes("data=") && url.pathname.match(dataLatLngRegex)) {
// Get marker from data attribute
// https://www.google.com/maps/place/41%C2%B001'58.2%22N+40%C2%B029'18.2%22E/@41.032833,40.4862063,17z/data=!3m1!4b1!4m6!3m5!1s0x0:0xf64286eaf72fc49d!7e2!8m2!3d41.0328329!4d40.4883948
//console.log("data life")
let [, mlat, mlon] = url.pathname.match(dataLatLngRegex)
return `${randomInstance}/search?query=${mlat}%2C${mlon}`
} else if (url.searchParams.has("ll")) {
// Get marker from ll param
// https://maps.google.com/?ll=38.882147,-76.99017
//console.log("ll life")
const [mlat, mlon] = url.searchParams.get("ll").split(",")
return `${randomInstance}/search?query=${mlat}%2C${mlon}`
} else if (url.searchParams.has("viewpoint")) {
// Get marker from viewpoint param.
// https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.857832,2.295226&heading=-45&pitch=38&fov=80
//console.log("viewpoint life")
const [mlat, mlon] = url.searchParams.get("viewpoint").split(",")
return `${randomInstance}/search?query=${mlat}%2C${mlon}`
} else {
// Use query as search if present.
//console.log("normal life")
let query
if (url.searchParams.has("q")) query = url.searchParams.get("q")
else if (url.searchParams.has("query")) query = url.searchParams.get("query")
else if (url.pathname.match(placeRegex)) query = url.pathname.match(placeRegex)[1]
let prefsEncoded = new URLSearchParams(prefs).toString()
if (query) return `${randomInstance}/search?query="${query}${mapCentre}&${prefsEncoded}`
}
let prefsEncoded = new URLSearchParams(prefs).toString()
console.log("mapCentre", mapCentre)
console.log("prefs", prefs)
console.log("prefsEncoded", prefsEncoded)
return `${randomInstance}/${mapCentre}&${prefsEncoded}`
}
case "facil": {
if (initiator && initiator.host === "earth.google.com") return
const travelModes = {
driving: "car",
walking: "pedestrian",
bicycling: "bicycle",
transit: "car", // not implemented on Facil, default to car.
}
const mapCentreData = convertMapCentre()
let mapCentre = "#"
if (mapCentreData[0] && mapCentreData[1] && mapCentreData[2]) mapCentre = `#${mapCentreData[0]}/${mapCentreData[1]}/${mapCentreData[2]}`
if (url.pathname.includes("/embed")) {
// Handle Google Maps Embed API
// https://www.google.com/maps/embed/v1/place?key=AIzaSyD4iE2xVSpkLLOXoyqT-RuPwURN3ddScAI&q=Eiffel+Tower,Paris+France
//console.log("embed life")
let query = ""
if (url.searchParams.has("q")) query = url.searchParams.get("q")
else if (url.searchParams.has("query")) query = url.searchParams.has("query")
else if (url.searchParams.has("pb"))
try {
query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1]
} catch (error) {
console.error(error)
} // Unable to find map marker in URL.
return `${randomInstance}/#q=${query}`
} else if (url.pathname.includes("/dir")) {
// Handle Google Maps Directions
// https://www.google.com/maps/dir/?api=1&origin=Space+Needle+Seattle+WA&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling
let travMod = url.searchParams.get("travelmode")
let orgVal = url.searchParams.get("origin")
let destVal = url.searchParams.get("destination")
return `${randomInstance}/#q=${orgVal}%20to%20${destVal}%20by%20${travelModes[travMod]}`
} else if (url.pathname.includes("data=") && url.pathname.match(dataLatLngRegex)) {
// Get marker from data attribute
// https://www.google.com/maps/place/41%C2%B001'58.2%22N+40%C2%B029'18.2%22E/@41.032833,40.4862063,17z/data=!3m1!4b1!4m6!3m5!1s0x0:0xf64286eaf72fc49d!7e2!8m2!3d41.0328329!4d40.4883948
//console.log("data life")
let [, mlat, mlon] = url.pathname.match(dataLatLngRegex)
return `${randomInstance}/#q=${mlat}%2C${mlon}`
} else if (url.searchParams.has("ll")) {
// Get marker from ll param
// https://maps.google.com/?ll=38.882147,-76.99017
//console.log("ll life")
const [mlat, mlon] = url.searchParams.get("ll").split(",")
return `${randomInstance}/#q=${mlat}%2C${mlon}`
} else if (url.searchParams.has("viewpoint")) {
// Get marker from viewpoint param.
// https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.857832,2.295226&heading=-45&pitch=38&fov=80
//console.log("viewpoint life")
const [mlat, mlon] = url.searchParams.get("viewpoint").split(",")
return `${randomInstance}/#q=${mlat}%2C${mlon}`
} else {
// Use query as search if present.
//console.log("normal life")
let query
if (url.searchParams.has("q")) query = url.searchParams.get("q")
else if (url.searchParams.has("query")) query = url.searchParams.get("query")
else if (url.pathname.match(placeRegex)) query = url.pathname.match(placeRegex)[1]
if (query) return `${randomInstance}/${mapCentre}/Mpnk/${query}`
}
}
case "wikiless":
let GETArguments = []
if (url.search.length > 0) {
let search = url.search.substring(1) //get rid of '?'
let argstrings = search.split("&")
for (let i = 0; i < argstrings.length; i++) {
let args = argstrings[i].split("=")
GETArguments.push([args[0], args[1]])
}
}
let link = `${randomInstance}${url.pathname}`
let urlSplit = url.host.split(".")
if (urlSplit[0] != "wikipedia" && urlSplit[0] != "www") {
if (urlSplit[0] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])
else GETArguments.push(["lang", urlSplit[0]])
if (urlSplit[1] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])
// wikiless doesn't have mobile view support yet
}
for (let i = 0; i < GETArguments.length; i++) link += (i == 0 ? "?" : "&") + GETArguments[i][0] + "=" + GETArguments[i][1]
return link
case "lingva":
let params_arr = url.search.split("&")
params_arr[0] = params_arr[0].substring(1)
let params = {}
for (let i = 0; i < params_arr.length; i++) {
let pair = params_arr[i].split("=")
params[pair[0]] = pair[1]
}
if (params.sl && params.tl && params.text) {
return `${randomInstance}/${params.sl}/${params.tl}/${params.text}`
}
return randomInstance
case "breezeWiki":
let wiki = url.hostname.match(/^[a-zA-Z0-9]+(?=\.fandom\.com)/)
if (wiki == "www" || !wiki) wiki = ""
else wiki = "/" + wiki
if (url.href.search(/Special:Search\?query/) > -1) return `${randomInstance}${wiki}${url.pathname}${url.search}`.replace(/Special:Search\?query/, "search?q").replace(/\/wiki/, "")
else return `${randomInstance}${wiki}${url.pathname}${url.search}`
case "rimgo":
if (url.href.search(/^https?:\/{2}(?:[im]\.)?stack\./) > -1) return `${randomInstance}/stack${url.pathname}${url.search}`
else return `${randomInstance}${url.pathname}${url.search}`
default:
return `${randomInstance}${url.pathname}${url.search}`
}
}
function computeService(url, returnFrontend) {
return new Promise(resolve => {
fetch("/config/config.json")
.then(response => response.text())
.then(configData => {
const config = JSON.parse(configData)
browser.storage.local.get(["redirects", "options"], r => {
const redirects = r.redirects
const options = r.options
for (const service in config.services) {
if (regexArray(service, url, config)) {
resolve(service)
return
} else {
for (const frontend in config.services[service].frontends) {
if (all(service, frontend, options, config, redirects).includes(utils.protocolHost(url))) {
if (returnFrontend) resolve([service, frontend, utils.protocolHost(url)])
else resolve(service)
return
}
}
}
}
resolve()
})
})
})
}
function switchInstance(url) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(url)
for (const service in config.services) {
if (!all(service, null, options, config, redirects).includes(protocolHost)) continue
let instancesList
if (Object.keys(config.services[service].frontends).length == 1) {
const frontend = Object.keys(config.services[service].frontends)[0]
instancesList = [...options[frontend][options.network].enabled, ...options[frontend][options.network].custom]
if (instancesList.length === 0 && options.networkFallback) instancesList = [...options[frontend].clearnet.enabled, ...options[frontend].clearnet.custom]
} else {
const frontend = options[service].frontend
instancesList = [...options[frontend][options.network].enabled, ...options[frontend][options.network].custom]
if (instancesList.length === 0 && options.networkFallback) instancesList = [...options[frontend].clearnet.enabled, ...options[frontend].clearnet.custom]
}
let oldInstance
const i = instancesList.indexOf(protocolHost)
if (i > -1) {
oldInstance = instancesList[i]
instancesList.splice(i, 1)
}
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
const oldUrl = `${oldInstance}${url.pathname}${url.search}`
// This is to make instance switching work when the instance depends on the pathname, eg https://darmarit.org/searx
// Doesn't work because of .includes array method, not a top priotiry atm
resolve(oldUrl.replace(oldInstance, randomInstance))
return
}
resolve()
})
}
function reverse(url, urlString) {
return new Promise(async resolve => {
await init()
let protocolHost
if (!urlString) protocolHost = utils.protocolHost(url)
else protocolHost = url.match(/https?:\/{2}(?:[^\s\/]+\.)+[a-zA-Z0-9]+/)[0]
for (const service in config.services) {
if (!all(service, null, options, config, redirects).includes(protocolHost)) continue
switch (service) {
case "instagram":
case "youtube":
case "imdb":
case "imgur":
case "tiktok":
case "twitter":
case "reddit":
case "imdb":
case "reuters":
case "quora":
case "medium":
if (!urlString) resolve(config.services[service].url + url.pathname + url.search)
else resolve(url.replace(/https?:\/{2}(?:[^\s\/]+\.)+[a-zA-Z0-9]+/, config.services[service].url))
return
default:
resolve()
return
}
}
resolve()
})
}
function unifyPreferences(url, tabId) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(url)
for (const service in config.services) {
for (const frontend in config.services[service].frontends) {
if (all(service, frontend, options, config, redirects).includes(protocolHost)) {
let instancesList = [...options[frontend][options.network].enabled, ...options[frontend][options.network].custom]
if (options.networkFallback && options.network != "clearnet") instancesList.push(...options[frontend].clearnet.enabled, ...options[frontend].clearnet.custom)
const frontendObject = config.services[service].frontends[frontend]
if ("cookies" in frontendObject.preferences) {
for (const cookie of frontendObject.preferences.cookies) {
await utils.copyCookie(frontendObject, url, instancesList, cookie)
}
}
if ("localstorage" in frontendObject.preferences) {
browser.storage.local.set({ tmp: [frontend, frontendObject.preferences.localstorage] })
browser.tabs.executeScript(tabId, {
file: "/assets/javascripts/get-localstorage.js",
runAt: "document_start",
})
for (const instance of instancesList)
browser.tabs.create({ url: instance }, tab =>
browser.tabs.executeScript(tab.id, {
file: "/assets/javascripts/set-localstorage.js",
runAt: "document_start",
})
)
}
/*
if ("indexeddb" in frontendObject.preferences) {
}
if ("token" in frontendObject.preferences) {
}
*/
resolve(true)
return
}
}
}
})
}
async function setRedirects(redirects) {
fetch("/config/config.json")
.then(response => response.text())
.then(configData => {
//browser.storage.local.get(["options", "blacklists"], async r => {
//const options = r.options
const config = JSON.parse(configData)
let targets = {}
for (const service in config.services) {
if (config.services[service].targets == "datajson") {
targets[service] = redirects[service]
}
/*
for (const frontend in config.services[service].frontends) {
if (config.services[service].frontends[frontend].instanceList) {
for (const network in config.networks) {
options[frontend][network].enabled = redirects[frontend][network]
}
for (const blacklist in r.blacklists) {
for (const instance of blacklist) {
let i = options[frontend].clearnet.enabled.indexOf(instance)
if (i > -1) options[frontend].clearnet.enabled.splice(i, 1)
}
}
}
}
*/
// The above will be implemented with https://github.com/libredirect/libredirect/issues/334
}
browser.storage.local.set({ redirects, targets /*, options*/ })
//})
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(data => {
fetch("/config/config.json")
.then(response => response.text())
.then(configData => {
browser.storage.local.get(["options", "blacklists"], r => {
let redirects = JSON.parse(data)
let options = r.options
let targets = {}
let config = JSON.parse(configData)
const localstorage = {}
const latency = {}
for (const service in config.services) {
options[service] = {}
if (config.services[service].targets == "datajson") targets[service] = redirects[service]
for (const defaultOption in config.services[service].options) options[service][defaultOption] = config.services[service].options[defaultOption]
for (const frontend in config.services[service].frontends) {
if (config.services[service].frontends[frontend].instanceList) {
options[frontend] = {}
for (const network in config.networks) {
options[frontend][network] = {}
options[frontend][network].enabled = JSON.parse(data)[frontend][network]
options[frontend][network].custom = []
}
for (const blacklist in r.blacklists) {
for (const instance of r.blacklists[blacklist]) {
let i = options[frontend].clearnet.enabled.indexOf(instance)
if (i > -1) options[frontend].clearnet.enabled.splice(i, 1)
}
}
}
}
}
browser.storage.local.set({ redirects, options, targets, latency, localstorage })
resolve()
})
})
})
})
}
function upgradeOptions() {
return new Promise(resolve => {
fetch("/config/config.json")
.then(response => response.text())
.then(configData => {
browser.storage.local.get(null, r => {
let options = r.options
let latency = {}
const config = JSON.parse(configData)
options.exceptions = r.exceptions
if (r.theme != "DEFAULT") options.theme = r.theme
options.popupServices = r.popupFrontends
let tmp = options.popupServices.indexOf("tikTok")
if (tmp > -1) {
options.popupServices.splice(tmp, 1)
options.popupServices.push("tiktok")
}
tmp = options.popupServices.indexOf("sendTarget")
if (tmp > -1) {
options.popupServices.splice(tmp, 1)
options.popupServices.push("sendFiles")
}
options.firstPartyIsolate = r.firstPartyIsolate
options.autoRedirect = r.autoRedirect
switch (r.onlyEmbeddedVideo) {
case "onlyNotEmbedded":
options.youtube.redirectType = "main_frame"
case "onlyEmbedded":
options.youtube.redirectType = "sub_frame"
case "both":
options.youtube.redirectType = "both"
}
for (const service in config.services) {
let oldService
switch (service) {
case "tiktok":
oldService = "tikTok"
break
case "sendFiles":
oldService = "sendTarget"
break
default:
oldService = service
}
options[service].enabled = !r["disable" + utils.camelCase(oldService)]
if (r[oldService + "Frontend"]) {
if (r[oldService + "Frontend"] == "yatte") options[service].frontend = "yattee"
else options[service].frontend = r[oldService + "Frontend"]
}
if (r[oldService + "RedirectType"]) options[service].redirectType = r[oldService + "RedirectType"]
if (r[oldService + "EmbedFrontend"] && (service != "youtube" || r[oldService + "EmbedFrontend"] == "invidious" || r[oldService + "EmbedFrontend"] == "piped"))
options[service].embedFrontend = r[oldService + "EmbedFrontend"]
for (const frontend in config.services[service].frontends) {
if (r[frontend + "Latency"]) latency[frontend] = r[frontend + "Latency"]
for (const network in config.networks) {
let protocol
if (network == "clearnet") protocol = "normal"
else protocol = network
if (r[frontend + utils.camelCase(protocol) + "RedirectsChecks"]) {
options[frontend][network].enabled = r[frontend + utils.camelCase(protocol) + "RedirectsChecks"]
options[frontend][network].custom = r[frontend + utils.camelCase(protocol) + "CustomRedirects"]
}
}
}
}
browser.storage.local.set({ options, latency }, () => resolve())
})
})
})
}
function processUpdate() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(data => {
fetch("/config/config.json")
.then(response => response.text())
.then(configData => {
browser.storage.local.get(["options", "blacklists", "targets"], r => {
let redirects = JSON.parse(data)
let options = r.options
let targets = r.targets
let config = JSON.parse(configData)
for (const service in config.services) {
if (!options[service]) options[service] = {}
if (config.services[service].targets == "datajson") targets[service] = redirects[service]
for (const defaultOption in config.services[service].options) if (!options[service][defaultOption]) options[service][defaultOption] = config.services[service].options[defaultOption]
for (const frontend in config.services[service].frontends) {
if (config.services[service].frontends[frontend].instanceList) {
if (!options[frontend]) options[frontend] = {}
for (const network in config.networks) {
if (!options[frontend][network]) {
options[frontend][network] = {}
options[frontend][network].enabled = JSON.parse(data)[frontend][network]
options[frontend][network].custom = []
if (network == "clearnet") {
for (const blacklist in r.blacklists) {
for (const instance of r.blacklists[blacklist]) {
let i = options[frontend].clearnet.enabled.indexOf(instance)
if (i > -1) options[frontend].clearnet.enabled.splice(i, 1)
}
}
}
}
}
}
}
}
browser.storage.local.set({ redirects, options, targets })
resolve()
})
})
})
})
}
export default {
redirect,
computeService,
switchInstance,
reverse,
unifyPreferences,
setRedirects,
initDefaults,
upgradeOptions,
processUpdate,
}

View File

@ -0,0 +1,13 @@
window.browser = window.browser || window.chrome
browser.storage.local.get(["localstorage", "tmp"], r => {
const localstorageJson = r.localstorage
const frontend = r.tmp[0]
const items = localstorageJson[frontend]
for (const item in items) {
localStorage.setItem(item, items[item])
}
window.close()
})

View File

@ -1,251 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}(www\.|)tiktok\.com.*/]
const frontends = new Array("proxiTok")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.proxiTok = val
proxiTokNormalRedirectsChecks = [...redirects.proxiTok.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = proxiTokNormalRedirectsChecks.indexOf(instance)
if (a > -1) proxiTokNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
tiktokRedirects: redirects,
proxiTokNormalRedirectsChecks,
proxiTokTorRedirectsChecks: [...redirects.proxiTok.tor],
proxiTokI2pRedirectsChecks: [...redirects.proxiTok.i2p],
proxiTokLokiRedirectsChecks: [...redirects.proxiTok.loki],
},
() => resolve()
)
})
)
}
function initProxiTokCookies(test, from) {
return new Promise(async resolve => {
await init()
let protocolHost = utils.protocolHost(from)
if (
![
...proxiTokNormalRedirectsChecks,
...proxiTokNormalCustomRedirects,
...proxiTokTorRedirectsChecks,
...proxiTokTorCustomRedirects,
...proxiTokI2pCustomRedirects,
...proxiTokLokiCustomRedirects,
].includes(protocolHost)
)
resolve()
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...proxiTokI2pCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...proxiTokLokiCustomRedirects]
else if (protocol == "tor") checkedInstances = [...proxiTokTorRedirectsChecks, ...proxiTokTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...proxiTokNormalRedirectsChecks, ...proxiTokNormalCustomRedirects]
}
await utils.copyCookie("proxitok", from, checkedInstances, "theme")
await utils.copyCookie("proxitok", from, checkedInstances, "api-legacy")
}
resolve(true)
})
}
let disableTiktok,
protocol,
protocolFallback,
tiktokRedirects,
proxiTokNormalRedirectsChecks,
proxiTokNormalCustomRedirects,
proxiTokTorRedirectsChecks,
proxiTokTorCustomRedirects,
proxiTokI2pCustomRedirects,
proxiTokLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableTiktok",
"protocol",
"protocolFallback",
"tiktokRedirects",
"proxiTokNormalRedirectsChecks",
"proxiTokNormalCustomRedirects",
"proxiTokTorRedirectsChecks",
"proxiTokTorCustomRedirects",
"proxiTokI2pCustomRedirects",
"proxiTokLokiCustomRedirects",
],
r => {
disableTiktok = r.disableTiktok
protocol = r.protocol
protocolFallback = r.protocolFallback
tiktokRedirects = r.tiktokRedirects
proxiTokNormalRedirectsChecks = r.proxiTokNormalRedirectsChecks
proxiTokNormalCustomRedirects = r.proxiTokNormalCustomRedirects
proxiTokTorRedirectsChecks = r.proxiTokTorRedirectsChecks
proxiTokTorCustomRedirects = r.proxiTokTorCustomRedirects
proxiTokI2pCustomRedirects = r.proxiTokI2pCustomRedirects
proxiTokLokiCustomRedirects = r.proxiTokLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
// https://www.tiktok.com/@keysikaspol/video/7061265241887345946
// https://www.tiktok.com/@keysikaspol
function redirect(url, type, initiator, disableOverride) {
if (disableTiktok && !disableOverride) return
if (type != "main_frame") return
const all = [...tiktokRedirects.proxiTok.normal, ...proxiTokNormalCustomRedirects]
if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return
if (!targets.some(rx => rx.test(url.href))) return
let instancesList = []
if (protocol == "loki") instancesList = [...proxiTokI2pCustomRedirects]
else if (protocol == "i2p") instancesList = [...proxiTokLokiCustomRedirects]
else if (protocol == "tor") instancesList = [...proxiTokTorRedirectsChecks, ...proxiTokTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...proxiTokNormalRedirectsChecks, ...proxiTokNormalCustomRedirects]
}
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
return `${randomInstance}${url.pathname}`
}
function reverse(url) {
return new Promise(async resolve => {
await init()
let protocolHost = utils.protocolHost(url)
const all = [
...tiktokRedirects.proxiTok.normal,
...tiktokRedirects.proxiTok.tor,
...proxiTokNormalCustomRedirects,
...proxiTokTorCustomRedirects,
...proxiTokI2pCustomRedirects,
...proxiTokLokiCustomRedirects,
]
if (!all.includes(protocolHost)) {
resolve()
return
}
resolve(`https://tiktok.com${url.pathname}${url.search}`)
})
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableTiktok && !disableOverride) {
resolve()
return
}
let protocolHost = utils.protocolHost(url)
const all = [
...tiktokRedirects.proxiTok.tor,
...tiktokRedirects.proxiTok.normal,
...proxiTokNormalCustomRedirects,
...proxiTokTorCustomRedirects,
...proxiTokI2pCustomRedirects,
...proxiTokLokiCustomRedirects,
]
if (!all.includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...proxiTokI2pCustomRedirects]
else if (protocol == "i2p") instancesList = [...proxiTokLokiCustomRedirects]
else if (protocol == "tor") instancesList = [...proxiTokTorRedirectsChecks, ...proxiTokTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...proxiTokNormalRedirectsChecks, ...proxiTokNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
proxiTokNormalRedirectsChecks = [...redirects.proxiTok.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = proxiTokNormalRedirectsChecks.indexOf(instance)
if (a > -1) proxiTokNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableTiktok: false,
tiktokRedirects: redirects,
proxiTokNormalRedirectsChecks,
proxiTokNormalCustomRedirects: [],
proxiTokTorRedirectsChecks: [...redirects.proxiTok.tor],
proxiTokTorCustomRedirects: [],
proxiTokI2pRedirectsChecks: [...redirects.proxiTok.i2p],
proxiTokI2pCustomRedirects: [],
proxiTokLokiRedirectsChecks: [...redirects.proxiTok.loki],
proxiTokLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
reverse,
switchInstance,
initProxiTokCookies,
initDefaults,
}

View File

@ -1,10 +0,0 @@
window.browser = window.browser || window.chrome
browser.storage.local.set({
["lingva_chakra-ui-color-mode"]: localStorage.getItem("chakra-ui-color-mode"),
lingva_isauto: localStorage.getItem("isauto"),
lingva_source: localStorage.getItem("source"),
lingva_target: localStorage.getItem("target"),
})
console.log(localStorage.getItem("target"))

View File

@ -1,9 +0,0 @@
window.browser = window.browser || window.chrome
browser.storage.local.get(["lingva_chakra-ui-color-mode", "lingva_isauto", "lingva_source", "lingva_target"], r => {
if (r["lingva_chakra-ui-color-mode"] !== undefined) localStorage.setItem("chakra-ui-color-mode", r["lingva_chakra-ui-color-mode"])
if (r.lingva_isauto !== undefined) localStorage.setItem("isauto", r.lingva_isauto)
if (r.lingva_source !== undefined) localStorage.setItem("source", r.lingva_source)
if (r.lingva_target !== undefined) localStorage.setItem("target", r.lingva_target)
window.close()
})

View File

@ -1,377 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "../utils.js"
const targets = [/^https?:\/{2}translate\.google(\.[a-z]{2,3}){1,2}\//]
const frontends = new Array("simplyTranslate", "lingva")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
let translateDisable,
translateFrontend,
protocol,
protocolFallback,
translateRedirects,
simplyTranslateNormalRedirectsChecks,
simplyTranslateNormalCustomRedirects,
simplyTranslateTorRedirectsChecks,
simplyTranslateTorCustomRedirects,
simplyTranslateI2pRedirectsChecks,
simplyTranslateI2pCustomRedirects,
simplyTranslateLokiRedirectsChecks,
simplyTranslateLokiCustomRedirects,
lingvaNormalRedirectsChecks,
lingvaNormalCustomRedirects,
lingvaTorRedirectsChecks,
lingvaTorCustomRedirects,
lingvaI2pCustomRedirects,
lingvaLokiCustomRedirects
function init() {
return new Promise(resolve => {
browser.storage.local.get(
[
"translateDisable",
"translateFrontend",
"protocol",
"protocolFallback",
"translateRedirects",
"simplyTranslateNormalRedirectsChecks",
"simplyTranslateNormalCustomRedirects",
"simplyTranslateTorRedirectsChecks",
"simplyTranslateTorCustomRedirects",
"simplyTranslateI2pRedirectsChecks",
"simplyTranslateI2pCustomRedirects",
"simplyTranslateLokiRedirectsChecks",
"simplyTranslateLokiCustomRedirects",
"lingvaNormalRedirectsChecks",
"lingvaNormalCustomRedirects",
"lingvaTorRedirectsChecks",
"lingvaTorCustomRedirects",
"lingvaI2pCustomRedirects",
"lingvaLokiCustomRedirects",
],
r => {
translateDisable = r.translateDisable
translateFrontend = r.translateFrontend
protocol = r.protocol
protocolFallback = r.protocolFallback
translateRedirects = r.translateRedirects
simplyTranslateNormalRedirectsChecks = r.simplyTranslateNormalRedirectsChecks
simplyTranslateNormalCustomRedirects = r.simplyTranslateNormalCustomRedirects
simplyTranslateTorRedirectsChecks = r.simplyTranslateTorRedirectsChecks
simplyTranslateTorCustomRedirects = r.simplyTranslateTorCustomRedirects
simplyTranslateI2pRedirectsChecks = r.simplyTranslateI2pRedirectsChecks
simplyTranslateI2pCustomRedirects = r.simplyTranslateI2pCustomRedirects
simplyTranslateLokiRedirectsChecks = r.simplyTranslateLokiRedirectsChecks
simplyTranslateLokiCustomRedirects = r.simplyTranslateLokiCustomRedirects
lingvaNormalRedirectsChecks = r.lingvaNormalRedirectsChecks
lingvaNormalCustomRedirects = r.lingvaNormalCustomRedirects
lingvaTorRedirectsChecks = r.lingvaTorRedirectsChecks
lingvaTorCustomRedirects = r.lingvaTorCustomRedirects
lingvaI2pCustomRedirects = r.lingvaI2pCustomRedirects
lingvaLokiCustomRedirects = r.lingvaLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects = val
simplyTranslateNormalRedirectsChecks = [...redirects.simplyTranslate.normal]
lingvaNormalRedirectsChecks = [...redirects.lingva.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = simplyTranslateNormalCustomRedirects.indexOf(instance)
if (a > -1) simplyTranslateNormalCustomRedirects.splice(a, 1)
const b = lingvaNormalRedirectsChecks.indexOf(instance)
if (b > -1) lingvaNormalRedirectsChecks.splice(b, 1)
}
browser.storage.local.set(
{
translateRedirects: redirects,
simplyTranslateNormalRedirectsChecks,
simplyTranslateTorRedirectsChecks: [...redirects.simplyTranslate.tor],
simplyTranslateI2pRedirectsChecks: [...redirects.simplyTranslate.i2p],
simplyTranslateLokiRedirectsChecks: [...redirects.simplyTranslate.loki],
lingvaNormalRedirectsChecks,
lingvaTorRedirectsChecks: [...redirects.lingva.tor],
lingvaI2pRedirectsChecks: [...redirects.lingva.i2p],
lingvaLokiRedirectsChecks: [...redirects.lingva.loki],
},
() => resolve()
)
})
)
}
function copyPasteLingvaLocalStorage(test, url, tabId) {
return new Promise(async resolve => {
await init()
if (translateDisable || translateFrontend != "lingva") {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (
![...lingvaNormalRedirectsChecks, ...lingvaNormalCustomRedirects, ...lingvaTorRedirectsChecks, ...lingvaTorCustomRedirects, ...lingvaI2pCustomRedirects, ...lingvaLokiCustomRedirects].includes(
protocolHost
)
) {
resolve()
return
}
if (!test) {
browser.tabs.executeScript(tabId, {
file: "/assets/javascripts/translate/get_lingva_preferences.js",
runAt: "document_start",
})
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...lingvaLokiCustomRedirects]
//...lingvaLokiRedirectsChecks,
else if (protocol == "i2p") checkedInstances = [...lingvaI2pCustomRedirects]
//...lingvaI2pRedirectsChecks,
else if (protocol == "tor") checkedInstances = [...lingvaTorRedirectsChecks, ...lingvaTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...lingvaNormalRedirectsChecks, ...lingvaNormalCustomRedirects]
}
const i = checkedInstances.indexOf(protocolHost)
if (i !== -1) checkedInstances.splice(i, 1)
if (checkedInstances.length === 0) {
resolve()
return
}
for (const to of checkedInstances)
browser.tabs.create({ url: to }, tab =>
browser.tabs.executeScript(tab.id, {
file: "/assets/javascripts/translate/set_lingva_preferences.js",
runAt: "document_start",
})
)
}
resolve(true)
})
}
function copyPasteSimplyTranslateCookies(test, from) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(from)
if (
![
...simplyTranslateNormalRedirectsChecks,
...simplyTranslateNormalCustomRedirects,
...simplyTranslateTorRedirectsChecks,
...simplyTranslateTorCustomRedirects,
...simplyTranslateI2pRedirectsChecks,
...simplyTranslateI2pCustomRedirects,
...simplyTranslateLokiRedirectsChecks,
...simplyTranslateLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...simplyTranslateLokiRedirectsChecks, ...simplyTranslateLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...simplyTranslateI2pCustomRedirects, ...simplyTranslateI2pRedirectsChecks]
else if (protocol == "tor") checkedInstances = [...simplyTranslateTorRedirectsChecks, ...simplyTranslateTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...simplyTranslateNormalRedirectsChecks, ...simplyTranslateNormalCustomRedirects]
}
await utils.copyCookie("simplyTranslate", from, checkedInstances, "from_lang")
await utils.copyCookie("simplyTranslate", from, checkedInstances, "to_lang")
await utils.copyCookie("simplyTranslate", from, checkedInstances, "tts_enabled")
await utils.copyCookie("simplyTranslate", from, checkedInstances, "use_text_fields")
}
resolve(true)
})
}
function redirect(url, disableOverride) {
if (translateDisable && !disableOverride) return
if (!targets.some(rx => rx.test(url.href))) return
if (translateFrontend == "simplyTranslate") {
let instancesList = []
if (protocol == "loki") instancesList = [...simplyTranslateLokiRedirectsChecks, ...simplyTranslateLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...simplyTranslateI2pRedirectsChecks, ...simplyTranslateI2pCustomRedirects]
else if (protocol == "tor") instancesList = [...simplyTranslateTorRedirectsChecks, ...simplyTranslateTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...simplyTranslateNormalRedirectsChecks, ...simplyTranslateNormalCustomRedirects]
}
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
return `${randomInstance}/${url.search}`
} else if (translateFrontend == "lingva") {
let params_arr = url.search.split("&")
params_arr[0] = params_arr[0].substring(1)
let params = {}
for (let i = 0; i < params_arr.length; i++) {
let pair = params_arr[i].split("=")
params[pair[0]] = pair[1]
}
let instancesList = []
if (protocol == "loki") instancesList = [...lingvaLokiCustomRedirects]
//...lingvaLokiRedirectsChecks,
else if (protocol == "i2p") instancesList = [...lingvaI2pCustomRedirects] //...lingvaI2pRedirectsChecks,
if (protocol == "tor") instancesList = [...lingvaTorRedirectsChecks, ...lingvaTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...lingvaNormalRedirectsChecks, ...lingvaNormalCustomRedirects]
}
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
if (params.sl && params.tl && params.text) {
return `${randomInstance}/${params.sl}/${params.tl}/${params.text}`
}
return randomInstance
}
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (translateDisable && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (
![
...translateRedirects.simplyTranslate.normal,
...translateRedirects.simplyTranslate.tor,
...translateRedirects.simplyTranslate.i2p,
...translateRedirects.simplyTranslate.loki,
...simplyTranslateNormalCustomRedirects,
...simplyTranslateTorCustomRedirects,
...simplyTranslateI2pCustomRedirects,
...simplyTranslateLokiCustomRedirects,
...translateRedirects.lingva.normal,
...translateRedirects.lingva.tor,
...lingvaNormalCustomRedirects,
...lingvaTorCustomRedirects,
...lingvaI2pCustomRedirects,
...lingvaLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") {
if (translateFrontend == "simplyTranslate") instancesList = [...simplyTranslateLokiRedirectsChecks, ...simplyTranslateLokiCustomRedirects]
else if (translateFrontend == "lingva") instancesList = [...lingvaLokiCustomRedirects] //...lingvaLokiRedirectsChecks,
} else if (protocol == "i2p") {
if (translateFrontend == "simplyTranslate") instancesList = [...simplyTranslateI2pRedirectsChecks, ...simplyTranslateI2pCustomRedirects]
else if (translateFrontend == "lingva") instancesList = [...lingvaI2pCustomRedirects] //...lingvaI2pRedirectsChecks,
} else if (protocol == "tor") {
if (translateFrontend == "simplyTranslate") instancesList = [...simplyTranslateTorRedirectsChecks, ...simplyTranslateTorCustomRedirects]
else if (translateFrontend == "lingva") instancesList = [...lingvaTorRedirectsChecks, ...lingvaTorCustomRedirects]
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
if (translateFrontend == "simplyTranslate") instancesList = [...simplyTranslateNormalRedirectsChecks, ...simplyTranslateNormalCustomRedirects]
else if (translateFrontend == "lingva") instancesList = [...lingvaNormalRedirectsChecks, ...lingvaNormalCustomRedirects]
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
simplyTranslateNormalRedirectsChecks = [...redirects.simplyTranslate.normal]
lingvaNormalRedirectsChecks = [...redirects.lingva.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = simplyTranslateNormalRedirectsChecks.indexOf(instance)
if (a > -1) simplyTranslateNormalRedirectsChecks.splice(a, 1)
const b = lingvaNormalRedirectsChecks.indexOf(instance)
if (b > -1) lingvaNormalRedirectsChecks.splice(b, 1)
}
browser.storage.local.set(
{
translateDisable: false,
translateFrontend: "simplyTranslate",
translateRedirects: redirects,
simplyTranslateNormalRedirectsChecks,
simplyTranslateNormalCustomRedirects: [],
simplyTranslateTorRedirectsChecks: [...redirects.simplyTranslate.tor],
simplyTranslateTorCustomRedirects: [],
simplyTranslateI2pRedirectsChecks: [...redirects.simplyTranslate.i2p],
simplyTranslateI2pCustomRedirects: [],
simplyTranslateLokiRedirectsChecks: [...redirects.simplyTranslate.loki],
simplyTranslateLokiCustomRedirects: [],
lingvaNormalRedirectsChecks,
lingvaNormalCustomRedirects: [],
lingvaTorRedirectsChecks: [...redirects.lingva.tor],
lingvaTorCustomRedirects: [],
lingvaI2pRedirectsChecks: [...redirects.lingva.i2p],
lingvaI2pCustomRedirects: [],
lingvaLokiRedirectsChecks: [...redirects.lingva.loki],
lingvaLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
copyPasteSimplyTranslateCookies,
copyPasteLingvaLocalStorage,
setRedirects,
redirect,
initDefaults,
switchInstance,
}

View File

@ -1,286 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = [/^https?:\/{2}(www\.|mobile\.|)twitter\.com/, /^https?:\/{2}(pbs\.|video\.|)twimg\.com/, /^https?:\/{2}platform\.twitter\.com\/embed/, /^https?:\/{2}t\.co/]
const frontends = new Array("nitter")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "authenticateBlackList", "offlineBlackList"], r => {
redirects.nitter = val
nitterNormalRedirectsChecks = [...redirects.nitter.normal]
for (const instance of [...r.cloudflareBlackList, ...r.authenticateBlackList, ...r.offlineBlackList]) {
let i = nitterNormalRedirectsChecks.indexOf(instance)
if (i > -1) nitterNormalRedirectsChecks.splice(i, 1)
}
browser.storage.local.set(
{
twitterRedirects: redirects,
nitterNormalRedirectsChecks,
nitterTorRedirectsChecks: [...redirects.nitter.tor],
nitterI2pRedirectsChecks: [...redirects.nitter.i2p],
nitterLokiRedirectsChecks: [...redirects.nitter.loki],
},
() => resolve()
)
})
)
}
let disableTwitter,
protocol,
protocolFallback,
twitterRedirects,
twitterRedirectType,
nitterNormalRedirectsChecks,
nitterNormalCustomRedirects,
nitterTorRedirectsChecks,
nitterTorCustomRedirects,
nitterI2pCustomRedirects,
nitterLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableTwitter",
"protocol",
"protocolFallback",
"twitterRedirects",
"twitterRedirectType",
"nitterNormalRedirectsChecks",
"nitterNormalCustomRedirects",
"nitterTorRedirectsChecks",
"nitterTorCustomRedirects",
"nitterI2pCustomRedirects",
"nitterLokiCustomRedirects",
],
r => {
disableTwitter = r.disableTwitter
protocol = r.protocol
protocolFallback = r.protocolFallback
twitterRedirects = r.twitterRedirects
twitterRedirectType = r.twitterRedirectType
nitterNormalRedirectsChecks = r.nitterNormalRedirectsChecks
nitterNormalCustomRedirects = r.nitterNormalCustomRedirects
nitterTorRedirectsChecks = r.nitterTorRedirectsChecks
nitterTorCustomRedirects = r.nitterTorCustomRedirects
nitterI2pCustomRedirects = r.nitterI2pCustomRedirects
nitterLokiCustomRedirects = r.nitterLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function all() {
return [...nitterNormalRedirectsChecks, ...nitterTorRedirectsChecks, ...nitterNormalCustomRedirects, ...nitterTorCustomRedirects, ...nitterI2pCustomRedirects, ...nitterLokiCustomRedirects]
}
function redirect(url, type, initiator, disableOverride) {
if (disableTwitter && !disableOverride) return
if (!targets.some(rx => rx.test(url.href))) return
if (url.pathname.split("/").includes("home")) return
if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
if (twitterRedirectType == "main_frame" && type != "main_frame") return
let instancesList = []
if (protocol == "loki") instancesList = [...nitterI2pCustomRedirects]
else if (protocol == "i2p") instancesList = [...nitterLokiCustomRedirects]
else if (protocol == "tor") instancesList = [...nitterTorRedirectsChecks, ...nitterTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...nitterNormalRedirectsChecks, ...nitterNormalCustomRedirects]
}
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
// https://pbs.twimg.com/profile_images/648888480974508032/66_cUYfj_400x400.jpg
let search = new URLSearchParams(url.search)
search.delete("ref_src")
search.delete("ref_url")
search = search.toString()
if (search !== "") search = `?${search}`
if (url.host.split(".")[0] === "pbs" || url.host.split(".")[0] === "video") {
const [, id, format, extra] = search.match(/(.*)\?format=(.*)&(.*)/)
const query = encodeURIComponent(`${id}.${format}?${extra}`)
return `${randomInstance}/pic${search}${query}`
}
if (url.pathname.split("/").includes("tweets")) {
return `${randomInstance}${url.pathname.replace("/tweets", "")}${search}`
}
if (url.host == "t.co") {
return `${randomInstance}/t.co${url.pathname}`
}
return `${randomInstance}${url.pathname}${search}`
}
function reverse(url) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
resolve(`https://twitter.com${url.pathname}${url.search}`)
})
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableTwitter && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...nitterI2pCustomRedirects]
else if (protocol == "i2p") instancesList = [...nitterLokiCustomRedirects]
else if (protocol == "tor") instancesList = [...nitterTorRedirectsChecks, ...nitterTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...nitterNormalRedirectsChecks, ...nitterNormalCustomRedirects]
}
let index = instancesList.indexOf(protocolHost)
if (index > -1) instancesList.splice(index, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function removeXFrameOptions(e) {
if (e.type != "sub_frame") return
let url = new URL(e.url)
let protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) return
let isChanged = false
for (const i in e.responseHeaders) {
if (e.responseHeaders[i].name == "x-frame-options") {
e.responseHeaders.splice(i, 1)
isChanged = true
} else if (e.responseHeaders[i].name == "content-security-policy") {
e.responseHeaders.splice(i, 1)
isChanged = true
}
}
if (isChanged) return { responseHeaders: e.responseHeaders }
}
function initNitterCookies(test, from) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(from)
if (!all().includes(protocolHost)) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...nitterI2pCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...nitterLokiCustomRedirects]
else if (protocol == "tor") checkedInstances = [...nitterTorRedirectsChecks, ...nitterTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...nitterNormalRedirectsChecks, ...nitterNormalCustomRedirects]
}
await utils.copyCookie("nitter", from, checkedInstances, "theme")
await utils.copyCookie("nitter", from, checkedInstances, "infiniteScroll")
await utils.copyCookie("nitter", from, checkedInstances, "stickyProfile")
await utils.copyCookie("nitter", from, checkedInstances, "bidiSupport")
await utils.copyCookie("nitter", from, checkedInstances, "hideTweetStats")
await utils.copyCookie("nitter", from, checkedInstances, "hideBanner")
await utils.copyCookie("nitter", from, checkedInstances, "hidePins")
await utils.copyCookie("nitter", from, checkedInstances, "hideReplies")
await utils.copyCookie("nitter", from, checkedInstances, "squareAvatars")
await utils.copyCookie("nitter", from, checkedInstances, "mp4Playback")
await utils.copyCookie("nitter", from, checkedInstances, "hlsPlayback")
await utils.copyCookie("nitter", from, checkedInstances, "proxyVideos")
await utils.copyCookie("nitter", from, checkedInstances, "muteVideos")
await utils.copyCookie("nitter", from, checkedInstances, "autoplayGifs")
await utils.copyCookie("nitter", from, checkedInstances, "replaceInstagram")
await utils.copyCookie("nitter", from, checkedInstances, "replaceReddit")
await utils.copyCookie("nitter", from, checkedInstances, "replaceTwitter")
await utils.copyCookie("nitter", from, checkedInstances, "replaceYouTube")
}
resolve(true)
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "authenticateBlackList", "offlineBlackList"], async r => {
nitterNormalRedirectsChecks = [...redirects.nitter.normal]
for (const instance of [...r.cloudflareBlackList, ...r.authenticateBlackList, ...r.offlineBlackList]) {
let i = nitterNormalRedirectsChecks.indexOf(instance)
if (i > -1) nitterNormalRedirectsChecks.splice(i, 1)
}
browser.storage.local.set(
{
disableTwitter: false,
twitterRedirects: redirects,
twitterRedirectType: "both",
nitterNormalRedirectsChecks,
nitterNormalCustomRedirects: [],
nitterTorRedirectsChecks: [...redirects.nitter.tor],
nitterTorCustomRedirects: [],
nitterI2pRedirectsChecks: [...redirects.nitter.i2p],
nitterI2pCustomRedirects: [],
nitterLokiRedirectsChecks: [...redirects.nitter.loki],
nitterLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
redirect,
switchInstance,
reverse,
removeXFrameOptions,
initNitterCookies,
initDefaults,
}

View File

@ -1,75 +1,29 @@
window.browser = window.browser || window.chrome
import twitterHelper from "./twitter.js"
import youtubeHelper from "./youtube/youtube.js"
import instagramHelper from "./instagram.js"
import mediumHelper from "./medium.js"
import redditHelper from "./reddit.js"
import searchHelper from "./search.js"
import translateHelper from "./translate/translate.js"
import wikipediaHelper from "./wikipedia.js"
import peertubeHelper from "./peertube.js"
import lbryHelper from "./lbry.js"
import sendTargetsHelper from "./sendTargets.js"
import tiktokHelper from "./tiktok.js"
import quoraHelper from "./quora.js"
import libremdbHelper from "./imdb.js"
import imgurHelper from "./imgur.js"
import reutersHelper from "./reuters.js"
import youtubeMusicHelper from "./youtubeMusic.js"
import mapsHelper from "./maps.js"
import localise from "./localise.js"
import servicesHelper from "./services.js"
function getRandomInstance(instances) {
return instances[~~(instances.length * Math.random())]
}
function camelCase(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
let cloudflareBlackList = []
let authenticateBlackList = []
let offlineBlackList = []
async function initBlackList() {
return new Promise(resolve => {
browser.storage.local.get(["cloudflareBlackList", "authenticateBlackList", "offlineBlackList"], r => {
cloudflareBlackList = r.cloudflareBlackList
authenticateBlackList = r.authenticateBlackList
offlineBlackList = r.offlineBlackList
})
if (cloudflareBlackList.length == 0) {
fetch("/instances/blacklist.json")
.then(response => response.text())
.then(data => {
cloudflareBlackList = JSON.parse(data).cloudflare
authenticateBlackList = JSON.parse(data).authenticate
offlineBlackList = JSON.parse(data).offline
})
}
resolve()
})
}
function updateBlackList() {
return new Promise(async resolve => {
let http = new XMLHttpRequest()
let fallback = new XMLHttpRequest()
http.open("GET", "https://codeberg.org/LibRedirect/libredirect/raw/branch/master/src/instances/blacklist.json", false)
http.send(null)
if (http.status != 200) {
fallback.open("GET", "https://raw.githubusercontent.com/libredirect/libredirect/master/src/instances/blacklist.json", false)
fallback.send(null)
if (fallback.status === 200) {
http = fallback
} else {
fetch("/instances/blacklist.json")
.then(response => response.text())
.then(data => {
cloudflareBlackList = JSON.parse(data).cloudflare
authenticateBlackList = JSON.parse(data).authenticate
offlineBlackList = JSON.parse(data).offline
resolve()
return
}
}
const blackList = JSON.parse(http.responseText)
browser.storage.local.set({
cloudflareBlackList: blackList.cloudflare,
authenticateBlackList: blackList.authenticate,
offlineBlackList: blackList.offline,
})
;(cloudflareBlackList = blackList.cloudflare), (authenticateBlackList = blackList.authenticate), (offlineBlackList = blackList.offline)
resolve()
})
})
}
@ -77,10 +31,10 @@ function updateInstances() {
return new Promise(async resolve => {
let http = new XMLHttpRequest()
let fallback = new XMLHttpRequest()
http.open("GET", "https://raw.githubusercontent.com/libredirect/libredirect/master/src/instances/data.json", false)
http.open("GET", "https://codeberg.org/LibRedirect/libredirect/raw/branch/master/src/instances/data.json", false)
http.send(null)
if (http.status != 200) {
fallback.open("GET", "https://codeberg.org/LibRedirect/libredirect/raw/branch/master/src/instances/data.json", false)
fallback.open("GET", "https://raw.githubusercontent.com/libredirect/libredirect/master/src/instances/data.json", false)
fallback.send(null)
if (fallback.status === 200) {
http = fallback
@ -89,45 +43,10 @@ function updateInstances() {
return
}
}
await updateBlackList()
await initBlackList()
const instances = JSON.parse(http.responseText)
await youtubeHelper.setRedirects({
invidious: instances.invidious,
piped: instances.piped,
pipedMaterial: instances.pipedMaterial,
cloudtube: instances.cloudtube,
})
await twitterHelper.setRedirects(instances.nitter)
await instagramHelper.setRedirects(instances.bibliogram)
await redditHelper.setRedirects({
libreddit: instances.libreddit,
teddit: instances.teddit,
})
await translateHelper.setRedirects({
simplyTranslate: instances.simplyTranslate,
lingva: instances.lingva,
})
await searchHelper.setRedirects({
searx: instances.searx,
searxng: instances.searxng,
whoogle: instances.whoogle,
librex: instances.librex,
})
await wikipediaHelper.setRedirects(instances.wikiless)
await mediumHelper.setRedirects(instances.scribe)
await quoraHelper.setRedirects(instances.quetre)
await libremdbHelper.setRedirects(instances.libremdb)
await sendTargetsHelper.setRedirects(instances.send)
await tiktokHelper.setRedirects(instances.proxiTok)
await lbryHelper.setRedirects(instances.librarian)
await reutersHelper.setRedirects(instances.neuters)
await youtubeMusicHelper.setRedirects({
beatbump: instances.beatbump,
hyperpipe: instances.hyperpipe,
})
await mapsHelper.setRedirects(instances.facil)
await peertubeHelper.setRedirects(instances.simpleertube)
servicesHelper.setRedirects(instances)
console.info("Successfully updated Instances")
resolve(true)
@ -140,72 +59,64 @@ function protocolHost(url) {
return `${url.protocol}//${url.host}`
}
async function processDefaultCustomInstances(target, name, protocol, document) {
function camelCase(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
let latencyKey = `${name}Latency`
async function processDefaultCustomInstances(service, frontend, network, document) {
let instancesLatency
let nameProtocolElement = document.getElementById(name).getElementsByClassName(protocol)[0]
let frontendNetworkElement = document.getElementById(frontend).getElementsByClassName(network)[0]
let nameCustomInstances = []
let nameCheckListElement = nameProtocolElement.getElementsByClassName("checklist")[0]
let frontendCustomInstances = []
let frontendCheckListElement = frontendNetworkElement.getElementsByClassName("checklist")[0]
await initBlackList()
let nameDefaultRedirects
let frontendDefaultRedirects
let redirectsChecks = `${name}${camelCase(protocol)}RedirectsChecks`
let customRedirects = `${name}${camelCase(protocol)}CustomRedirects`
let redirectsKey = `${target}Redirects`
let redirects
let redirects, options
async function getFromStorage() {
return new Promise(async resolve =>
browser.storage.local.get([redirectsChecks, customRedirects, redirectsKey, latencyKey], r => {
nameDefaultRedirects = r[redirectsChecks]
nameCustomInstances = r[customRedirects]
instancesLatency = r[latencyKey] ?? []
redirects = r[redirectsKey]
browser.storage.local.get(["options", "redirects", "latency"], r => {
frontendDefaultRedirects = r.options[frontend][network].enabled
frontendCustomInstances = r.options[frontend][network].custom
options = r.options
instancesLatency = r.latency[frontend] ?? []
redirects = r.redirects
resolve()
})
)
}
await getFromStorage()
if (nameCustomInstances === undefined) console.log(customRedirects)
function calcNameCheckBoxes() {
function calcFrontendCheckBoxes() {
let isTrue = true
for (const item of redirects[name][protocol]) {
if (nameDefaultRedirects === undefined) console.log(name + protocol + " is undefined")
if (!nameDefaultRedirects.includes(item)) {
for (const item of redirects[frontend][network]) {
if (!frontendDefaultRedirects.includes(item)) {
isTrue = false
break
}
}
for (const element of nameCheckListElement.getElementsByTagName("input")) {
element.checked = nameDefaultRedirects.includes(element.className)
for (const element of frontendCheckListElement.getElementsByTagName("input")) {
element.checked = frontendDefaultRedirects.includes(element.className)
}
if (nameDefaultRedirects.length == 0) isTrue = false
nameProtocolElement.getElementsByClassName("toggle-all")[0].checked = isTrue
if (frontendDefaultRedirects.length == 0) isTrue = false
frontendNetworkElement.getElementsByClassName("toggle-all")[0].checked = isTrue
}
nameCheckListElement.innerHTML = [
frontendCheckListElement.innerHTML = [
`<div>
<x data-localise="__MSG_toggleAll__">Toggle All</x>
<input type="checkbox" class="toggle-all"/>
</div>`,
...redirects[name][protocol].map(x => {
...redirects[frontend][network].map(x => {
const cloudflare = cloudflareBlackList.includes(x) ? ' <span style="color:red;">cloudflare</span>' : ""
const authenticate = authenticateBlackList.includes(x) ? ' <span style="color:orange;">authenticate</span>' : ""
const offline = offlineBlackList.includes(x) ? ' <span style="color:grey;">offline</span>' : ""
let ms = instancesLatency[x]
let latencyColor = ms <= 1000 ? "green" : ms <= 2000 ? "orange" : "red"
let latencyColor = ms == -1 ? "red" : ms <= 1000 ? "green" : ms <= 2000 ? "orange" : "red"
let latencyLimit
if (ms == 5000) latencyLimit = "5000ms+"
else if (ms > 5000) latencyLimit = `ERROR: ${ms - 5000}`
else if (ms == -1) latencyLimit = "Server not found"
else latencyLimit = ms + "ms"
const latency = x in instancesLatency ? '<span style="color:' + latencyColor + ';">' + latencyLimit + "</span>" : ""
@ -220,32 +131,33 @@ async function processDefaultCustomInstances(target, name, protocol, document) {
localise.localisePage()
calcNameCheckBoxes()
nameProtocolElement.getElementsByClassName("toggle-all")[0].addEventListener("change", async event => {
if (event.target.checked) nameDefaultRedirects = [...redirects[name][protocol]]
else nameDefaultRedirects = []
calcFrontendCheckBoxes()
frontendNetworkElement.getElementsByClassName("toggle-all")[0].addEventListener("change", async event => {
if (event.target.checked) frontendDefaultRedirects = [...redirects[frontend][network]]
else frontendDefaultRedirects = []
browser.storage.local.set({ [redirectsChecks]: nameDefaultRedirects })
calcNameCheckBoxes()
options[frontend][network].enabled = frontendDefaultRedirects
browser.storage.local.set({ options })
calcFrontendCheckBoxes()
})
for (let element of nameCheckListElement.getElementsByTagName("input")) {
for (let element of frontendCheckListElement.getElementsByTagName("input")) {
if (element.className != "toggle-all")
nameProtocolElement.getElementsByClassName(element.className)[0].addEventListener("change", async event => {
if (event.target.checked) nameDefaultRedirects.push(element.className)
frontendNetworkElement.getElementsByClassName(element.className)[0].addEventListener("change", async event => {
if (event.target.checked) frontendDefaultRedirects.push(element.className)
else {
let index = nameDefaultRedirects.indexOf(element.className)
if (index > -1) nameDefaultRedirects.splice(index, 1)
let index = frontendDefaultRedirects.indexOf(element.className)
if (index > -1) frontendDefaultRedirects.splice(index, 1)
}
browser.storage.local.set({
[redirectsChecks]: nameDefaultRedirects,
})
calcNameCheckBoxes()
options[frontend][network].enabled = frontendDefaultRedirects
browser.storage.local.set({ options })
calcFrontendCheckBoxes()
})
}
function calcNameCustomInstances() {
nameProtocolElement.getElementsByClassName("custom-checklist")[0].innerHTML = nameCustomInstances
function calcFrontendCustomInstances() {
frontendNetworkElement.getElementsByClassName("custom-checklist")[0].innerHTML = frontendCustomInstances
.map(
x => `<div>
${x}
@ -259,28 +171,30 @@ async function processDefaultCustomInstances(target, name, protocol, document) {
)
.join("\n")
for (const item of nameCustomInstances) {
nameProtocolElement.getElementsByClassName(`clear-${item}`)[0].addEventListener("click", async () => {
let index = nameCustomInstances.indexOf(item)
if (index > -1) nameCustomInstances.splice(index, 1)
browser.storage.local.set({ [customRedirects]: nameCustomInstances })
calcNameCustomInstances()
for (const item of frontendCustomInstances) {
frontendNetworkElement.getElementsByClassName(`clear-${item}`)[0].addEventListener("click", async () => {
let index = frontendCustomInstances.indexOf(item)
if (index > -1) frontendCustomInstances.splice(index, 1)
options[frontend][network].custom = frontendCustomInstances
browser.storage.local.set({ options })
calcFrontendCustomInstances()
})
}
}
calcNameCustomInstances()
nameProtocolElement.getElementsByClassName("custom-instance-form")[0].addEventListener("submit", async event => {
calcFrontendCustomInstances()
frontendNetworkElement.getElementsByClassName("custom-instance-form")[0].addEventListener("submit", async event => {
event.preventDefault()
let nameCustomInstanceInput = nameProtocolElement.getElementsByClassName("custom-instance")[0]
let url = new URL(nameCustomInstanceInput.value)
let frontendCustomInstanceInput = frontendNetworkElement.getElementsByClassName("custom-instance")[0]
let url = new URL(frontendCustomInstanceInput.value)
let protocolHostVar = protocolHost(url)
if (nameCustomInstanceInput.validity.valid && !redirects[name][protocol].includes(protocolHostVar)) {
if (!nameCustomInstances.includes(protocolHostVar)) {
nameCustomInstances.push(protocolHostVar)
browser.storage.local.set({ [customRedirects]: nameCustomInstances })
nameCustomInstanceInput.value = ""
if (frontendCustomInstanceInput.validity.valid && !redirects[frontend][network].includes(protocolHostVar)) {
if (!frontendCustomInstances.includes(protocolHostVar)) {
frontendCustomInstances.push(protocolHostVar)
options[frontend][network].custom = frontendCustomInstances
browser.storage.local.set({ options })
frontendCustomInstanceInput.value = ""
}
calcNameCustomInstances()
calcFrontendCustomInstances()
}
})
}
@ -330,43 +244,47 @@ function pingOnce(href) {
async function testLatency(element, instances, frontend) {
return new Promise(async resolve => {
let myList = {}
let latencyThreshold
let redirectsChecks = []
browser.storage.local.get(["latencyThreshold", `${frontend}NormalRedirectsChecks`], r => {
latencyThreshold = r.latencyThreshold
redirectsChecks = r[`${frontend}NormalRedirectsChecks`]
let latencyThreshold, options
browser.storage.local.get(["options"], r => {
latencyThreshold = r.options.latencyThreshold
options = r.options
})
for (const href of instances)
for (const href of instances) {
await ping(href).then(time => {
let color
if (time) {
myList[href] = time
let color
if (time <= 1000) color = "green"
else if (time <= 2000) color = "orange"
else color = "red"
if (time > latencyThreshold) {
redirectsChecks.splice(redirectsChecks.indexOf(href), 1)
if (time > latencyThreshold && options[frontend].clearnet.enabled.includes(href)) {
options[frontend].clearnet.enabled.splice(options[frontend].clearnet.enabled.indexOf(href), 1)
}
browser.storage.local.set({ [`${frontend}NormalRedirectsChecks`]: redirectsChecks })
let text
if (time == 5000) text = "5000ms+"
else if (time > 5000) text = `ERROR: ${time - 5000}`
else text = `${time}ms`
element.innerHTML = `${href}:&nbsp;<span style="color:${color};">${text}</span>`
} else {
myList[href] = -1
color = "red"
element.innerHTML = `${href}:&nbsp;<span style="color:${color};">Server not found</span>`
if (options[frontend].clearnet.enabled.includes(href)) options[frontend].clearnet.enabled.splice(options[frontend].clearnet.enabled.indexOf(href), 1)
}
})
}
browser.storage.local.set({ options })
resolve(myList)
})
}
function copyCookie(frontend, targetUrl, urls, name) {
return new Promise(resolve => {
browser.storage.local.get("firstPartyIsolate", r => {
browser.storage.local.get("options", r => {
let query
if (!r.firstPartyIsolate)
if (!r.options.firstPartyIsolate)
query = {
url: protocolHost(targetUrl),
name: name,
@ -381,7 +299,7 @@ function copyCookie(frontend, targetUrl, urls, name) {
for (const cookie of cookies)
if (cookie.name == name) {
for (const url of urls) {
const setQuery = r.firstPartyIsolate
const setQuery = r.options.firstPartyIsolate
? {
url: url,
name: name,
@ -408,23 +326,21 @@ function copyCookie(frontend, targetUrl, urls, name) {
function getPreferencesFromToken(frontend, targetUrl, urls, name, endpoint) {
return new Promise(resolve => {
browser.storage.local.get("firstPartyIsolate", r => {
const http = new XMLHttpRequest()
const url = `${targetUrl}${endpoint}`
http.open("GET", url, false)
//http.setRequestHeader("Cookie", `${name}=${cookie.value}`)
http.send(null)
const preferences = JSON.parse(http.responseText)
let formdata = new FormData()
for (var key in preferences) formdata.append(key, preferences[key])
for (const url of urls) {
const http = new XMLHttpRequest()
const url = `${targetUrl}${endpoint}`
http.open("GET", url, false)
http.setRequestHeader("Cookie", `${name}=${cookie.value}`)
http.open("POST", `${url}/settings/stay`, false)
http.send(null)
const preferences = JSON.parse(http.responseText)
let formdata = new FormData()
for (var key in preferences) formdata.append(key, preferences[key])
for (const url of urls) {
const http = new XMLHttpRequest()
http.open("POST", `${url}/settings/stay`, false)
http.send(null)
}
resolve()
return
})
}
resolve()
return
})
}
@ -441,13 +357,7 @@ function copyRaw(test, copyRawElement) {
return
}
let newUrl = await youtubeHelper.reverse(url)
if (!newUrl) newUrl = await twitterHelper.reverse(url)
if (!newUrl) newUrl = await instagramHelper.reverse(url)
if (!newUrl) newUrl = await tiktokHelper.reverse(url)
if (!newUrl) newUrl = await quoraHelper.reverse(url)
if (!newUrl) newUrl = await libremdbHelper.reverse(url)
if (!newUrl) newUrl = await imgurHelper.reverse(url)
const newUrl = await servicesHelper.reverse(url)
if (newUrl) {
resolve(newUrl)
@ -466,7 +376,7 @@ function copyRaw(test, copyRawElement) {
})
}
function unify(test) {
function unify() {
return new Promise(resolve => {
browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
let currTab = tabs[0]
@ -479,23 +389,7 @@ function unify(test) {
return
}
let result = await youtubeHelper.copyPasteInvidiousCookies(test, url)
if (!result) result = await youtubeHelper.copyPastePipedLocalStorage(test, url, currTab.id)
if (!result) result = await youtubeHelper.copyPastePipedMaterialLocalStorage(test, url, currTab.id)
if (!result) result = await twitterHelper.initNitterCookies(test, url)
if (!result) result = await redditHelper.initLibredditCookies(test, url)
if (!result) result = await redditHelper.initTedditCookies(test, url)
if (!result) result = await searchHelper.initSearxCookies(test, url)
if (!result) result = await searchHelper.initSearxngCookies(test, url)
if (!result) result = await searchHelper.initLibrexCookies(test, url)
if (!result) result = await tiktokHelper.initProxiTokCookies(test, url)
if (!result) result = await wikipediaHelper.initWikilessCookies(test, url)
if (!result) result = await translateHelper.copyPasteSimplyTranslateCookies(test, url)
if (!result) result = await translateHelper.copyPasteLingvaLocalStorage(test, url)
if (!result) result = await instagramHelper.initBibliogramPreferences(test, url)
resolve(result)
resolve(await servicesHelper.unifyPreferences(url, currTab.id))
}
})
})
@ -513,22 +407,7 @@ function switchInstance(test) {
resolve()
return
}
let newUrl = await youtubeHelper.switchInstance(url, true)
if (!newUrl) newUrl = await twitterHelper.switchInstance(url, true)
if (!newUrl) newUrl = await instagramHelper.switchInstance(url, true)
if (!newUrl) newUrl = await redditHelper.switchInstance(url, true)
if (!newUrl) newUrl = await searchHelper.switchInstance(url, true)
if (!newUrl) newUrl = await translateHelper.switchInstance(url, true)
if (!newUrl) newUrl = await mediumHelper.switchInstance(url, true)
if (!newUrl) newUrl = await quoraHelper.switchInstance(url, true)
if (!newUrl) newUrl = await libremdbHelper.switchInstance(url, true)
if (!newUrl) newUrl = await tiktokHelper.switchInstance(url, true)
if (!newUrl) newUrl = await sendTargetsHelper.switchInstance(url, true)
if (!newUrl) newUrl = await peertubeHelper.switchInstance(url, true)
if (!newUrl) newUrl = await lbryHelper.switchInstance(url, true)
if (!newUrl) newUrl = await imgurHelper.switchInstance(url, true)
if (!newUrl) newUrl = await wikipediaHelper.switchInstance(url, true)
if (!newUrl) newUrl = await youtubeMusicHelper.switchInstance(url, true)
const newUrl = await servicesHelper.switchInstance(url)
if (newUrl) {
if (!test) browser.tabs.update({ url: newUrl })
@ -539,22 +418,26 @@ function switchInstance(test) {
})
}
function latency(name, frontend, document, location) {
function latency(service, frontend, document, location) {
let latencyElement = document.getElementById(`latency-${frontend}`)
let latencyLabel = document.getElementById(`latency-${frontend}-label`)
latencyElement.addEventListener("click", async () => {
let reloadWindow = () => location.reload()
latencyElement.addEventListener("click", reloadWindow)
let key = `${name}Redirects`
browser.storage.local.get(key, r => {
let redirects = r[key]
browser.storage.local.get("redirects", r => {
let redirects = r.redirects
const oldHtml = latencyLabel.innerHTML
latencyLabel.innerHTML = "..."
testLatency(latencyLabel, redirects[frontend].normal, frontend).then(r => {
browser.storage.local.set({ [`${frontend}Latency`]: r })
latencyLabel.innerHTML = oldHtml
processDefaultCustomInstances(name, frontend, "normal", document)
latencyElement.removeEventListener("click", reloadWindow)
testLatency(latencyLabel, redirects[frontend].clearnet, frontend).then(r => {
const frontendLatency = r
browser.storage.local.get("latency", r => {
let latency = r.latency
latency[frontend] = frontendLatency
browser.storage.local.set({ latency })
latencyLabel.innerHTML = oldHtml
processDefaultCustomInstances(service, frontend, "clearnet", document)
latencyElement.removeEventListener("click", reloadWindow)
})
})
})
})
@ -571,4 +454,5 @@ export default {
switchInstance,
copyRaw,
unify,
camelCase,
}

View File

@ -1,247 +0,0 @@
window.browser = window.browser || window.chrome
import utils from "./utils.js"
const targets = /^https?:\/{2}([a-z]+\.)*wikipedia\.org/
const frontends = new Array("wikiless")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects.wikiless = val
wikilessNormalRedirectsChecks = [...redirects.wikiless.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = wikilessNormalRedirectsChecks.indexOf(instance)
if (a > -1) wikilessNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
wikipediaRedirects: redirects,
wikilessNormalRedirectsChecks,
wikilessTorRedirectsChecks: [...redirects.wikiless.tor],
wikilessI2pRedirectsChecks: [...redirects.wikiless.i2p],
wikilessLokiRedirectsChecks: [...redirects.wikiless.loki],
},
() => resolve()
)
})
)
}
let disableWikipedia,
wikipediaRedirects,
protocol,
protocolFallback,
wikilessNormalRedirectsChecks,
wikilessTorRedirectsChecks,
wikilessI2pRedirectsChecks,
wikilessNormalCustomRedirects,
wikilessTorCustomRedirects,
wikilessI2pCustomRedirects,
wikilessLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableWikipedia",
"wikipediaRedirects",
"protocol",
"protocolFallback",
"wikilessNormalRedirectsChecks",
"wikilessTorRedirectsChecks",
"wikilessI2pRedirectsChecks",
"wikilessNormalCustomRedirects",
"wikilessTorCustomRedirects",
"wikilessI2pCustomRedirects",
"wikilessLokiCustomRedirects",
],
r => {
disableWikipedia = r.disableWikipedia
wikipediaRedirects = r.wikipediaRedirects
protocol = r.protocol
protocolFallback = r.protocolFallback
wikilessNormalRedirectsChecks = r.wikilessNormalRedirectsChecks
wikilessTorRedirectsChecks = r.wikilessTorRedirectsChecks
wikilessI2pRedirectsChecks = r.wikilessI2pRedirectsChecks
wikilessNormalCustomRedirects = r.wikilessNormalCustomRedirects
wikilessTorCustomRedirects = r.wikilessTorCustomRedirects
wikilessI2pCustomRedirects = r.wikilessI2pCustomRedirects
wikilessLokiCustomRedirects = r.wikilessLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function initWikilessCookies(test, from) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(from)
const all = [
...wikilessNormalRedirectsChecks,
...wikilessNormalCustomRedirects,
...wikilessTorRedirectsChecks,
...wikilessTorCustomRedirects,
...wikilessI2pRedirectsChecks,
...wikilessI2pCustomRedirects,
...wikilessLokiCustomRedirects,
]
if (!all.includes(protocolHost)) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...wikilessLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...wikilessI2pCustomRedirects, ...wikilessI2pRedirectsChecks]
else if (protocol == "tor") checkedInstances = [...wikilessTorRedirectsChecks, ...wikilessTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...wikilessNormalRedirectsChecks, ...wikilessNormalCustomRedirects]
}
await utils.copyCookie("wikiless", from, checkedInstances, "theme")
await utils.copyCookie("wikiless", from, checkedInstances, "default_lang")
}
resolve(true)
})
}
function redirect(url, disableOverride) {
if (disableWikipedia && !disableOverride) return
if (!targets.test(url.href)) return
let GETArguments = []
if (url.search.length > 0) {
let search = url.search.substring(1) //get rid of '?'
let argstrings = search.split("&")
for (let i = 0; i < argstrings.length; i++) {
let args = argstrings[i].split("=")
GETArguments.push([args[0], args[1]])
}
}
let instancesList = []
if (protocol == "loki") instancesList = [...wikilessLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...wikilessI2pCustomRedirects, ...wikilessI2pRedirectsChecks]
else if (protocol == "tor") instancesList = [...wikilessTorRedirectsChecks, ...wikilessTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...wikilessNormalRedirectsChecks, ...wikilessNormalCustomRedirects]
}
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
let link = `${randomInstance}${url.pathname}`
let urlSplit = url.host.split(".")
if (urlSplit[0] != "wikipedia" && urlSplit[0] != "www") {
if (urlSplit[0] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])
else GETArguments.push(["lang", urlSplit[0]])
if (urlSplit[1] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])
// wikiless doesn't have mobile view support yet
}
for (let i = 0; i < GETArguments.length; i++) link += (i == 0 ? "?" : "&") + GETArguments[i][0] + "=" + GETArguments[i][1]
return link
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableWikipedia && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
const wikipediaList = [
...wikipediaRedirects.wikiless.normal,
...wikipediaRedirects.wikiless.tor,
...wikipediaRedirects.wikiless.i2p,
...wikilessNormalCustomRedirects,
...wikilessTorCustomRedirects,
...wikilessI2pCustomRedirects,
...wikilessLokiCustomRedirects,
]
if (!wikipediaList.includes(protocolHost)) {
resolve()
return
}
let instancesList = []
if (protocol == "loki") instancesList = [...wikilessLokiCustomRedirects]
else if (protocol == "i2p") instancesList = [...wikilessI2pCustomRedirects, ...wikilessI2pRedirectsChecks]
else if (protocol == "tor") instancesList = [...wikilessTorRedirectsChecks, ...wikilessTorCustomRedirects]
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...wikilessNormalRedirectsChecks, ...wikilessNormalCustomRedirects]
}
let index = instancesList.indexOf(protocolHost)
if (index > -1) instancesList.splice(index, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
wikilessNormalRedirectsChecks = [...redirects.wikiless.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = wikilessNormalRedirectsChecks.indexOf(instance)
if (a > -1) wikilessNormalRedirectsChecks.splice(a, 1)
}
browser.storage.local.set(
{
disableWikipedia: true,
wikipediaRedirects: redirects,
wikilessNormalRedirectsChecks,
wikilessNormalCustomRedirects: [],
wikilessTorRedirectsChecks: [...redirects.wikiless.tor],
wikilessTorCustomRedirects: [],
wikilessI2pRedirectsChecks: [...redirects.wikiless.i2p],
wikilessI2pCustomRedirects: [],
wikilessLokiRedirectsChecks: [...redirects.wikiless.loki],
wikilessLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
initWikilessCookies,
redirect,
initDefaults,
switchInstance,
}

View File

@ -1,5 +0,0 @@
window.browser = window.browser || window.chrome
browser.storage.local.set({
pipedMaterial_PREFERENCES: localStorage.getItem("PREFERENCES"),
})

View File

@ -1,22 +0,0 @@
window.browser = window.browser || window.chrome
browser.storage.local.set({
piped_bufferGoal: localStorage.getItem("bufferGoal"),
piped_comments: localStorage.getItem("comments"),
piped_disableLBRY: localStorage.getItem("disableLBRY"),
piped_enabledCodecs: localStorage.getItem("enabledCodecs"),
piped_hl: localStorage.getItem("hl"),
piped_homepage: localStorage.getItem("homepage"),
piped_instance: localStorage.getItem("instance"),
piped_listen: localStorage.getItem("listen"),
piped_minimizeDescription: localStorage.getItem("minimizeDescription"),
piped_playerAutoPlay: localStorage.getItem("playerAutoPlay"),
piped_proxyLBRY: localStorage.getItem("proxyLBRY"),
piped_quality: localStorage.getItem("quality"),
piped_region: localStorage.getItem("region"),
piped_selectedSkip: localStorage.getItem("selectedSkip"),
piped_sponsorblock: localStorage.getItem("sponsorblock"),
piped_theme: localStorage.getItem("theme"),
piped_volume: localStorage.getItem("volume"),
piped_watchHistory: localStorage.getItem("watchHistory"),
})

View File

@ -1,7 +0,0 @@
window.browser = window.browser || window.chrome
browser.storage.local.get("pipedMaterial_PREFERENCES", r => {
if (r.pipedMaterial_PREFERENCES !== undefined) localStorage.setItem("PREFERENCES", r.pipedMaterial_PREFERENCES)
window.close()
})

View File

@ -1,45 +0,0 @@
window.browser = window.browser || window.chrome
browser.storage.local.get(
[
"piped_bufferGoal",
"piped_comments",
"piped_disableLBRY",
"piped_enabledCodecs",
"piped_homepage",
"piped_instance",
"piped_listen",
"piped_minimizeDescription",
"piped_playerAutoPlay",
"piped_proxyLBRY",
"piped_quality",
"piped_region",
"piped_selectedSkip",
"piped_sponsorblock",
"piped_theme",
"piped_volume",
"piped_watchHistory",
],
r => {
if (r.piped_bufferGoal !== undefined) localStorage.setItem("bufferGoal", r.piped_bufferGoal)
if (r.piped_comments !== undefined) localStorage.setItem("comments", r.piped_comments)
if (r.piped_disableLBRY !== undefined) localStorage.setItem("disableLBRY", r.piped_disableLBRY)
if (r.piped_hl !== undefined) localStorage.setItem("hl", r.piped_hl)
if (r.piped_enabledCodecs !== undefined) localStorage.setItem("enabledCodecs", r.piped_enabledCodecs)
if (r.piped_homepage !== undefined) localStorage.setItem("homepage", r.piped_homepage)
if (r.piped_instance !== undefined) localStorage.setItem("instance", r.piped_instance)
if (r.piped_listen !== undefined) localStorage.setItem("listen", r.piped_listen)
if (r.piped_minimizeDescription !== undefined) localStorage.setItem("minimizeDescription", r.piped_minimizeDescription)
if (r.piped_playerAutoPlay !== undefined) localStorage.setItem("playerAutoPlay", r.piped_playerAutoPlay)
if (r.piped_proxyLBRY !== undefined) localStorage.setItem("proxyLBRY", r.piped_proxyLBRY)
if (r.piped_quality !== undefined) localStorage.setItem("quality", r.piped_quality)
if (r.piped_region !== undefined) localStorage.setItem("region", r.piped_region)
if (r.piped_selectedSkip !== undefined) localStorage.setItem("selectedSkip", r.piped_selectedSkip)
if (r.piped_sponsorblock !== undefined) localStorage.setItem("sponsorblock", r.piped_sponsorblock)
if (r.piped_theme !== undefined) localStorage.setItem("theme", r.piped_theme)
if (r.piped_volume !== undefined) localStorage.setItem("volume", r.piped_volume)
if (r.piped_watchHistory !== undefined) localStorage.setItem("watchHistory", r.piped_watchHistory)
window.close()
}
)

View File

@ -1,797 +0,0 @@
"use strict"
window.browser = window.browser || window.chrome
import utils from "../utils.js"
const targets = [
/^https?:\/{2}(www\.|music\.|m\.|)youtube\.com(\/.*|$)/,
/^https?:\/{2}img\.youtube\.com\/vi\/.*\/..*/, // https://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api
/^https?:\/{2}(i|s)\.ytimg\.com\/vi\/.*\/..*/,
/^https?:\/{2}(www\.|music\.|)youtube\.com\/watch\?v\=..*/,
/^https?:\/{2}youtu\.be\/..*/,
/^https?:\/{2}(www\.|)(youtube|youtube-nocookie)\.com\/embed\/..*/,
]
const frontends = new Array("invidious", "piped", "pipedMaterial", "cloudtube")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects = val
invidiousNormalRedirectsChecks = [...redirects.invidious.normal]
pipedNormalRedirectsChecks = [...redirects.piped.normal]
pipedMaterialNormalRedirectsChecks = [...redirects.pipedMaterial.normal]
cloudtubeNormalRedirectsChecks = [...redirects.cloudtube.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = invidiousNormalRedirectsChecks.indexOf(instance)
if (a > -1) invidiousNormalRedirectsChecks.splice(a, 1)
const b = pipedNormalRedirectsChecks.indexOf(instance)
if (b > -1) pipedNormalRedirectsChecks.splice(b, 1)
const c = pipedMaterialNormalRedirectsChecks.indexOf(instance)
if (c > -1) pipedMaterialNormalRedirectsChecks.splice(c, 1)
const d = cloudtubeNormalRedirectsChecks.indexOf(instance)
if (c > -1) cloudtubeNormalRedirectsChecks.splice(d, 1)
}
browser.storage.local.set(
{
youtubeRedirects: redirects,
invidiousNormalRedirectsChecks,
invidiousTorRedirectsChecks: [...redirects.invidious.tor],
invidiousI2pRedirectsChecks: [...redirects.invidious.i2p],
invidiousLokiRedirectsChecks: [...redirects.invidious.loki],
pipedNormalRedirectsChecks,
pipedTorRedirectsChecks: [...redirects.piped.tor],
pipedI2pRedirectsChecks: [...redirects.piped.i2p],
pipedLokiRedirectsChecks: [...redirects.piped.loki],
pipedMaterialNormalRedirectsChecks,
pipedMaterialTorRedirectsChecks: [...redirects.pipedMaterial.tor],
pipedMaterialI2pRedirectsChecks: [...redirects.pipedMaterial.i2p],
pipedMaterialLokiRedirectsChecks: [...redirects.pipedMaterial.loki],
cloudtubeNormalRedirectsChecks,
cloudtubeTorRedirectsChecks: [...redirects.cloudtube.tor],
cloudtubeI2pRedirectsChecks: [...redirects.cloudtube.i2p],
cloudtubeLokiRedirectsChecks: [...redirects.cloudtube.loki],
},
() => resolve()
)
})
)
}
let disableYoutube,
onlyEmbeddedVideo,
youtubeFrontend,
protocol,
protocolFallback,
youtubeEmbedFrontend,
youtubeRedirects,
invidiousNormalRedirectsChecks,
invidiousNormalCustomRedirects,
invidiousTorRedirectsChecks,
invidiousTorCustomRedirects,
invidiousI2pRedirectsChecks,
invidiousI2pCustomRedirects,
invidiousLokiRedirectsChecks,
invidiousLokiCustomRedirects,
pipedNormalRedirectsChecks,
pipedNormalCustomRedirects,
pipedTorRedirectsChecks,
pipedTorCustomRedirects,
pipedI2pRedirectsChecks,
pipedI2pCustomRedirects,
pipedLokiRedirectsChecks,
pipedLokiCustomRedirects,
pipedMaterialNormalRedirectsChecks,
pipedMaterialNormalCustomRedirects,
pipedMaterialTorRedirectsChecks,
pipedMaterialTorCustomRedirects,
pipedMaterialI2pRedirectsChecks,
pipedMaterialI2pCustomRedirects,
pipedMaterialLokiRedirectsChecks,
pipedMaterialLokiCustomRedirects,
cloudtubeNormalRedirectsChecks,
cloudtubeNormalCustomRedirects,
cloudtubeTorRedirectsChecks,
cloudtubeTorCustomRedirects,
cloudtubeI2pRedirectsChecks,
cloudtubeI2pCustomRedirects,
cloudtubeLokiRedirectsChecks,
cloudtubeLokiCustomRedirects
function init() {
return new Promise(resolve => {
browser.storage.local.get(
[
"disableYoutube",
"onlyEmbeddedVideo",
"youtubeFrontend",
"protocol",
"protocolFallback",
"youtubeEmbedFrontend",
"youtubeRedirects",
"invidiousNormalRedirectsChecks",
"invidiousNormalCustomRedirects",
"invidiousTorRedirectsChecks",
"invidiousTorCustomRedirects",
"invidiousI2pRedirectsChecks",
"invidiousI2pCustomRedirects",
"invidiousLokiRedirectsChecks",
"invidiousLokiCustomRedirects",
"pipedNormalRedirectsChecks",
"pipedNormalCustomRedirects",
"pipedTorRedirectsChecks",
"pipedTorCustomRedirects",
"pipedI2pRedirectsChecks",
"pipedI2pCustomRedirects",
"pipedLokiRedirectsChecks",
"pipedLokiCustomRedirects",
"pipedMaterialNormalRedirectsChecks",
"pipedMaterialNormalCustomRedirects",
"pipedMaterialTorRedirectsChecks",
"pipedMaterialTorCustomRedirects",
"pipedMaterialI2pRedirectsChecks",
"pipedMaterialI2pCustomRedirects",
"pipedMaterialLokiRedirectsChecks",
"pipedMaterialLokiCustomRedirects",
"cloudtubeNormalRedirectsChecks",
"cloudtubeNormalCustomRedirects",
"cloudtubeTorRedirectsChecks",
"cloudtubeTorCustomRedirects",
"cloudtubeI2pRedirectsChecks",
"cloudtubeI2pCustomRedirects",
"cloudtubeLokiRedirectsChecks",
"cloudtubeLokiCustomRedirects",
],
r => {
disableYoutube = r.disableYoutube
onlyEmbeddedVideo = r.onlyEmbeddedVideo
youtubeFrontend = r.youtubeFrontend
protocol = r.protocol
protocolFallback = r.protocolFallback
youtubeEmbedFrontend = r.youtubeEmbedFrontend
youtubeRedirects = r.youtubeRedirects
invidiousNormalRedirectsChecks = r.invidiousNormalRedirectsChecks
invidiousNormalCustomRedirects = r.invidiousNormalCustomRedirects
invidiousTorRedirectsChecks = r.invidiousTorRedirectsChecks
invidiousTorCustomRedirects = r.invidiousTorCustomRedirects
invidiousI2pRedirectsChecks = r.invidiousI2pRedirectsChecks
invidiousI2pCustomRedirects = r.invidiousI2pCustomRedirects
invidiousLokiRedirectsChecks = r.invidiousLokiRedirectsChecks
invidiousLokiCustomRedirects = r.invidiousLokiCustomRedirects
pipedNormalRedirectsChecks = r.pipedNormalRedirectsChecks
pipedNormalCustomRedirects = r.pipedNormalCustomRedirects
pipedTorRedirectsChecks = r.pipedTorRedirectsChecks
pipedTorCustomRedirects = r.pipedTorCustomRedirects
pipedI2pRedirectsChecks = r.pipedI2pRedirectsChecks
pipedI2pCustomRedirects = r.pipedI2pCustomRedirects
pipedLokiRedirectsChecks = r.pipedLokiRedirectsChecks
pipedLokiCustomRedirects = r.pipedLokiCustomRedirects
pipedMaterialNormalRedirectsChecks = r.pipedMaterialNormalRedirectsChecks
pipedMaterialNormalCustomRedirects = r.pipedMaterialNormalCustomRedirects
pipedMaterialTorRedirectsChecks = r.pipedMaterialTorRedirectsChecks
pipedMaterialTorCustomRedirects = r.pipedMaterialTorCustomRedirects
pipedMaterialI2pRedirectsChecks = r.pipedMaterialI2pRedirectsChecks
pipedMaterialI2pCustomRedirects = r.pipedMaterialI2pCustomRedirects
pipedMaterialLokiRedirectsChecks = r.pipedMaterialLokiRedirectsChecks
pipedMaterialLokiCustomRedirects = r.pipedMaterialLokiCustomRedirects
cloudtubeNormalRedirectsChecks = r.cloudtubeNormalRedirectsChecks
cloudtubeNormalCustomRedirects = r.cloudtubeNormalCustomRedirects
cloudtubeTorRedirectsChecks = r.cloudtubeTorRedirectsChecks
cloudtubeTorCustomRedirects = r.cloudtubeTorCustomRedirects
cloudtubeI2pRedirectsChecks = r.cloudtubeI2pRedirectsChecks
cloudtubeI2pCustomRedirects = r.cloudtubeI2pCustomRedirects
cloudtubeLokiRedirectsChecks = r.cloudtubeLokiRedirectsChecks
cloudtubeLokiCustomRedirects = r.cloudtubeLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function all() {
return [
...youtubeRedirects.invidious.normal,
...youtubeRedirects.invidious.tor,
...youtubeRedirects.invidious.i2p,
...youtubeRedirects.invidious.loki,
...youtubeRedirects.piped.normal,
...youtubeRedirects.piped.tor,
...youtubeRedirects.piped.i2p,
...youtubeRedirects.piped.loki,
...youtubeRedirects.pipedMaterial.normal,
...youtubeRedirects.pipedMaterial.tor,
...youtubeRedirects.pipedMaterial.i2p,
...youtubeRedirects.pipedMaterial.loki,
...youtubeRedirects.cloudtube.normal,
...youtubeRedirects.cloudtube.tor,
...youtubeRedirects.cloudtube.i2p,
...youtubeRedirects.cloudtube.loki,
...invidiousNormalCustomRedirects,
...invidiousTorCustomRedirects,
...invidiousI2pCustomRedirects,
...invidiousLokiCustomRedirects,
...pipedNormalCustomRedirects,
...pipedTorCustomRedirects,
...pipedI2pCustomRedirects,
...pipedLokiCustomRedirects,
...pipedMaterialNormalCustomRedirects,
...pipedMaterialTorCustomRedirects,
...pipedMaterialI2pCustomRedirects,
...pipedMaterialLokiCustomRedirects,
...cloudtubeNormalCustomRedirects,
...cloudtubeTorCustomRedirects,
...cloudtubeI2pCustomRedirects,
...cloudtubeLokiCustomRedirects,
]
}
function calculateFrontend(type) {
switch (type) {
case "main_frame":
return youtubeFrontend
case "sub_frame":
return youtubeEmbedFrontend
}
}
function getInstanceList(type) {
let instancesList = []
switch (calculateFrontend(type)) {
case "invidious":
switch (protocol) {
case "loki":
instancesList = [...invidiousLokiRedirectsChecks, ...invidiousLokiCustomRedirects]
break
case "i2p":
instancesList = [...invidiousI2pRedirectsChecks, ...invidiousI2pCustomRedirects]
break
case "tor":
instancesList = [...invidiousTorRedirectsChecks, ...invidiousTorCustomRedirects]
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...invidiousNormalRedirectsChecks, ...invidiousNormalCustomRedirects]
}
break
case "piped":
switch (protocol) {
case "loki":
instancesList = [...pipedLokiRedirectsChecks, ...pipedLokiCustomRedirects]
break
case "i2p":
instancesList = [...pipedI2pRedirectsChecks, ...pipedI2pCustomRedirects]
break
case "tor":
instancesList = [...pipedTorRedirectsChecks, ...pipedTorCustomRedirects]
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...pipedNormalRedirectsChecks, ...pipedNormalCustomRedirects]
}
break
case "pipedMaterial":
switch (protocol) {
case "loki":
instancesList = [...pipedMaterialLokiRedirectsChecks, ...pipedMaterialLokiCustomRedirects]
break
case "i2p":
instancesList = [...pipedMaterialI2pRedirectsChecks, ...pipedMaterialI2pCustomRedirects]
break
case "tor":
instancesList = [...pipedMaterialTorRedirectsChecks, ...pipedMaterialTorCustomRedirects]
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...pipedMaterialNormalRedirectsChecks, ...pipedMaterialNormalCustomRedirects]
}
case "cloudtube":
switch (protocol) {
case "loki":
instancesList = [...cloudtubeLokiRedirectsChecks, ...cloudtubeLokiCustomRedirects]
break
case "i2p":
instancesList = [...cloudtubeI2pRedirectsChecks, ...cloudtubeI2pCustomRedirects]
break
case "tor":
instancesList = [...cloudtubeTorRedirectsChecks, ...cloudtubeTorCustomRedirects]
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
instancesList = [...cloudtubeNormalRedirectsChecks, ...cloudtubeNormalCustomRedirects]
}
}
return instancesList
}
function redirect(url, type, tabId, initiator, disableOverride) {
if (disableYoutube && !disableOverride) return
if (!targets.some(rx => rx.test(url.href))) return
if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
if (type != ("main_frame" || "sub_frame")) return
if (url.pathname.match(/iframe_api/) || url.pathname.match(/www-widgetapi/)) return // Don't redirect YouTube Player API.
if (onlyEmbeddedVideo == "onlyNotEmbedded" && type == "sub_frame") return
if (type == "main_frame") {
switch (youtubeFrontend) {
case "yatte":
return url.href.replace(/^https?:\/{2}/, "yattee://")
case "freetube":
if (url.host === "youtu.be") return `freetube://https://youtube.com/watch?v=${url.pathname.slice(1)}&${url.search.slice(1)}`
return `freetube://https://youtube.com${url.pathname}${url.search}`
}
}
const instanceList = getInstanceList(type)
try {
if (instanceList.length >= 1) {
const randomInstance = utils.getRandomInstance(instanceList)
return `${randomInstance}${url.pathname}${url.search}`
}
} catch {
return
}
}
function reverse(url) {
return new Promise(async resolve => {
await init()
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
resolve(`https://youtube.com${url.pathname}${url.search}`)
})
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableYoutube && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
let instancesList = []
switch (protocol) {
case "loki":
switch (youtubeFrontend) {
case "invidious":
instancesList = [...invidiousLokiRedirectsChecks, ...invidiousLokiCustomRedirects]
break
case "piped":
instancesList = [...pipedLokiRedirectsChecks, ...pipedLokiCustomRedirects]
break
case "pipedMaterial":
instancesList = [...pipedMaterialLokiRedirectsChecks, ...pipedMaterialLokiCustomRedirects]
break
case "cloudtube":
instancesList = [...cloudtubeLokiRedirectsChecks, ...cloudtubeLokiCustomRedirects]
}
break
case "i2p":
switch (youtubeFrontend) {
case "invidious":
instancesList = [...invidiousI2pRedirectsChecks, ...invidiousI2pCustomRedirects]
break
case "piped":
instancesList = [...pipedI2pRedirectsChecks, ...pipedI2pCustomRedirects]
break
case "pipedMaterial":
instancesList = [...pipedMaterialI2pRedirectsChecks, ...pipedMaterialI2pCustomRedirects]
break
case "cloudtube":
instancesList = [...cloudtubeI2pRedirectsChecks, ...cloudtubeI2pCustomRedirects]
}
break
case "tor":
switch (youtubeFrontend) {
case "invidious":
instancesList = [...invidiousTorRedirectsChecks, ...invidiousTorCustomRedirects]
break
case "piped":
instancesList = [...pipedTorRedirectsChecks, ...pipedTorCustomRedirects]
break
case "pipedMaterial":
instancesList = [...pipedMaterialTorRedirectsChecks, ...pipedMaterialTorCustomRedirects]
break
case "cloudtube":
instancesList = [...cloudtubeTorRedirectsChecks, ...cloudtubeTorCustomRedirects]
}
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
switch (youtubeFrontend) {
case "invidious":
instancesList = [...invidiousNormalRedirectsChecks, ...invidiousNormalCustomRedirects]
break
case "piped":
instancesList = [...pipedNormalRedirectsChecks, ...pipedNormalCustomRedirects]
break
case "pipedMaterial":
instancesList = [...pipedMaterialNormalRedirectsChecks, ...pipedMaterialNormalCustomRedirects]
break
case "cloudtube":
instancesList = [...cloudtubeNormalRedirectsChecks, ...cloudtubeNormalCustomRedirects]
}
}
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length == 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
resolve(`${randomInstance}${url.pathname}${url.search}`)
})
}
function initDefaults() {
return new Promise(async resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
invidiousNormalRedirectsChecks = [...redirects.invidious.normal]
pipedNormalRedirectsChecks = [...redirects.piped.normal]
pipedMaterialNormalRedirectsChecks = [...redirects.pipedMaterial.normal]
cloudtubeNormalRedirectsChecks = [...redirects.cloudtube.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = invidiousNormalRedirectsChecks.indexOf(instance)
if (a > -1) invidiousNormalRedirectsChecks.splice(a, 1)
const b = pipedNormalRedirectsChecks.indexOf(instance)
if (b > -1) pipedNormalRedirectsChecks.splice(b, 1)
const c = pipedMaterialNormalRedirectsChecks.indexOf(instance)
if (c > -1) pipedMaterialNormalRedirectsChecks.splice(c, 1)
const d = cloudtubeNormalRedirectsChecks.indexOf(instance)
if (c > -1) cloudtubeNormalRedirectsChecks.splice(d, 1)
}
browser.storage.local.set(
{
disableYoutube: false,
enableYoutubeCustomSettings: false,
onlyEmbeddedVideo: "both",
youtubeRedirects: redirects,
youtubeFrontend: "invidious",
invidiousNormalRedirectsChecks,
invidiousNormalCustomRedirects: [],
invidiousTorRedirectsChecks: [...redirects.invidious.tor],
invidiousTorCustomRedirects: [],
invidiousI2pRedirectsChecks: [...redirects.invidious.i2p],
invidiousI2pCustomRedirects: [],
invidiousLokiRedirectsChecks: [...redirects.invidious.loki],
invidiousLokiCustomRedirects: [],
pipedNormalRedirectsChecks,
pipedNormalCustomRedirects: [],
pipedTorRedirectsChecks: [...redirects.piped.tor],
pipedTorCustomRedirects: [],
pipedI2pRedirectsChecks: [...redirects.piped.i2p],
pipedI2pCustomRedirects: [],
pipedLokiRedirectsChecks: [...redirects.piped.loki],
pipedLokiCustomRedirects: [],
pipedMaterialNormalRedirectsChecks: pipedMaterialNormalRedirectsChecks,
pipedMaterialNormalCustomRedirects: [],
pipedMaterialTorRedirectsChecks: [...redirects.pipedMaterial.tor],
pipedMaterialTorCustomRedirects: [],
pipedMaterialI2pRedirectsChecks: [...redirects.pipedMaterial.i2p],
pipedMaterialI2pCustomRedirects: [],
pipedMaterialLokiRedirectsChecks: [...redirects.pipedMaterial.loki],
pipedMaterialLokiCustomRedirects: [],
cloudtubeNormalRedirectsChecks: cloudtubeNormalRedirectsChecks,
cloudtubeNormalCustomRedirects: [],
cloudtubeTorRedirectsChecks: [...redirects.cloudtube.tor],
cloudtubeTorCustomRedirects: [],
cloudtubeI2pRedirectsChecks: [...redirects.cloudtube.i2p],
cloudtubeI2pCustomRedirects: [],
cloudtubeLokiRedirectsChecks: [...redirects.cloudtube.loki],
cloudtubeLokiCustomRedirects: [],
youtubeEmbedFrontend: "invidious",
},
() => resolve()
)
})
})
})
}
function copyPasteInvidiousCookies(test, from) {
return new Promise(async resolve => {
await init()
if (disableYoutube || youtubeFrontend != "invidious") {
resolve()
return
}
const protocolHost = utils.protocolHost(from)
if (
![
...invidiousNormalRedirectsChecks,
...invidiousTorRedirectsChecks,
...invidiousNormalCustomRedirects,
...invidiousTorCustomRedirects,
...invidiousI2pCustomRedirects,
...invidiousLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
if (!test) {
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...invidiousLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...invidiousI2pCustomRedirects]
else if (protocol == "tor") checkedInstances = [...invidiousTorRedirectsChecks, ...invidiousTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...invidiousNormalRedirectsChecks, ...invidiousNormalCustomRedirects]
}
const i = checkedInstances.indexOf(protocolHost)
if (i !== -1) checkedInstances.splice(i, 1)
await utils.copyCookie("invidious", from, checkedInstances, "PREFS")
}
resolve(true)
})
}
function copyPastePipedLocalStorage(test, url, tabId) {
return new Promise(async resolve => {
await init()
if (disableYoutube || youtubeFrontend != "piped") {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (
![...pipedNormalCustomRedirects, ...pipedNormalRedirectsChecks, ...pipedTorRedirectsChecks, ...pipedTorCustomRedirects, ...pipedI2pCustomRedirects, ...pipedLokiCustomRedirects].includes(
protocolHost
)
) {
resolve()
return
}
if (!test) {
browser.tabs.executeScript(tabId, {
file: "/assets/javascripts/youtube/get_piped_preferences.js",
runAt: "document_start",
})
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...pipedLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...pipedI2pCustomRedirects]
else if (protocol == "tor") checkedInstances = [...pipedTorRedirectsChecks, ...pipedTorCustomRedirects]
if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...pipedNormalCustomRedirects, ...pipedNormalRedirectsChecks]
}
const i = checkedInstances.indexOf(protocolHost)
if (i !== -1) checkedInstances.splice(i, 1)
for (const to of checkedInstances) {
browser.tabs.create({ url: to }, tab =>
browser.tabs.executeScript(tab.id, {
file: "/assets/javascripts/youtube/set_piped_preferences.js",
runAt: "document_start",
})
)
}
}
resolve(true)
})
}
function copyPastePipedMaterialLocalStorage(test, url, tabId) {
return new Promise(async resolve => {
await init()
if (disableYoutube || youtubeFrontend != "pipedMaterial") {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (
![
...pipedMaterialNormalRedirectsChecks,
...pipedMaterialNormalCustomRedirects,
//...pipedMaterialTorRedirectsChecks,
...pipedMaterialTorCustomRedirects,
...pipedMaterialI2pCustomRedirects,
...pipedMaterialLokiCustomRedirects,
].includes(protocolHost)
) {
resolve()
return
}
if (!test) {
browser.tabs.executeScript(tabId, {
file: "/assets/javascripts/youtube/get_pipedMaterial_preferences.js",
runAt: "document_start",
})
let checkedInstances = []
if (protocol == "loki") checkedInstances = [...pipedMaterialLokiCustomRedirects]
else if (protocol == "i2p") checkedInstances = [...pipedMaterialI2pCustomRedirects]
else if (protocol == "tor") checkedInstances = [...pipedMaterialTorCustomRedirects] //...pipedMaterialTorRedirectsChecks,
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
checkedInstances = [...pipedMaterialNormalRedirectsChecks, ...pipedMaterialNormalCustomRedirects]
}
const i = checkedInstances.indexOf(protocolHost)
if (i !== -1) checkedInstances.splice(i, 1)
for (const to of checkedInstances)
browser.tabs.create({ url: to }, tab =>
browser.tabs.executeScript(tab.id, {
file: "/assets/javascripts/youtube/set_pipedMaterial_preferences.js",
runAt: "document_start",
})
)
}
resolve(true)
})
}
function removeXFrameOptions(e) {
let isChanged = false
if (e.type == "main_frame") {
for (const i in e.responseHeaders) {
if (e.responseHeaders[i].name == "content-security-policy") {
let instancesList = []
switch (protocol) {
case "loki":
switch (youtubeFrontend) {
case "invidious":
instancesList = [...invidiousLokiRedirectsChecks, ...invidiousLokiCustomRedirects]
break
case "piped":
instancesList = [...pipedLokiRedirectsChecks, ...pipedLokiCustomRedirects]
break
case "pipedMaterial":
instancesList = [...pipedMaterialLokiRedirectsChecks, ...pipedMaterialLokiCustomRedirects]
break
case "cloudtube":
instancesList = [...cloudtubeLokiRedirectsChecks, ...cloudtubeLokiCustomRedirects]
}
break
case "i2p":
switch (youtubeFrontend) {
case "invidious":
instancesList = [...invidiousI2pRedirectsChecks, ...invidiousI2pCustomRedirects]
break
case "piped":
instancesList = [...pipedI2pRedirectsChecks, ...pipedI2pCustomRedirects]
break
case "pipedMaterial":
instancesList = [...pipedMaterialI2pRedirectsChecks, ...pipedMaterialI2pCustomRedirects]
break
case "cloudtube":
instancesList = [...cloudtubeI2pRedirectsChecks, ...cloudtubeI2pCustomRedirects]
}
break
case "tor":
switch (youtubeFrontend) {
case "invidious":
instancesList = [...invidiousTorRedirectsChecks, ...invidiousTorCustomRedirects]
break
case "piped":
instancesList = [...pipedTorRedirectsChecks, ...pipedTorCustomRedirects]
break
case "pipedMaterial":
instancesList = [...pipedMaterialTorRedirectsChecks, ...pipedMaterialTorCustomRedirects]
break
case "cloudtube":
instancesList = [...cloudtubeTorRedirectsChecks, ...cloudtubeTorCustomRedirects]
}
}
if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
switch (youtubeFrontend) {
case "invidious":
instancesList = [...invidiousNormalRedirectsChecks, ...invidiousNormalCustomRedirects]
break
case "piped":
instancesList = [...pipedNormalRedirectsChecks, ...pipedNormalCustomRedirects]
break
case "pipedMaterial":
instancesList = [...pipedMaterialNormalRedirectsChecks, ...pipedMaterialNormalCustomRedirects]
break
case "cloudtube":
instancesList = [...cloudtubeNormalRedirectsChecks, ...cloudtubeNormalCustomRedirects]
}
}
let securityPolicyList = e.responseHeaders[i].value.split(";")
for (const i in securityPolicyList) securityPolicyList[i] = securityPolicyList[i].trim()
let newSecurity = ""
for (const item of securityPolicyList) {
if (item.trim() == "") continue
let regex = item.match(/([a-z-]{0,}) (.*)/)
if (regex == null) continue
let [, key, vals] = regex
if (key == "frame-src") vals = vals + " " + instancesList.join(" ")
newSecurity += key + " " + vals + "; "
}
e.responseHeaders[i].value = newSecurity
isChanged = true
}
}
} else if (e.type == "sub_frame") {
const url = new URL(e.url)
const protocolHost = utils.protocolHost(url)
if (all().includes(protocolHost)) {
for (const i in e.responseHeaders) {
if (e.responseHeaders[i].name == "x-frame-options") {
e.responseHeaders.splice(i, 1)
isChanged = true
} else if (e.responseHeaders[i].name == "content-security-policy") {
e.responseHeaders.splice(i, 1)
isChanged = true
}
}
}
}
if (isChanged) return { responseHeaders: e.responseHeaders }
}
export default {
setRedirects,
copyPastePipedLocalStorage,
copyPastePipedMaterialLocalStorage,
copyPasteInvidiousCookies,
redirect,
reverse,
switchInstance,
initDefaults,
removeXFrameOptions,
}

View File

@ -1,332 +0,0 @@
"use strict"
import utils from "./utils.js"
window.browser = window.browser || window.chrome
const targets = [/^https?:\/{2}music\.youtube\.com(\/.*|$)/]
const frontends = new Array("beatbump", "hyperpipe")
const protocols = new Array("normal", "tor", "i2p", "loki")
let redirects = {}
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = {}
for (let x = 0; x < protocols.length; x++) {
redirects[frontends[i]][protocols[x]] = []
}
}
function setRedirects(val) {
return new Promise(resolve =>
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
redirects = val
beatbumpNormalRedirectsChecks = [...redirects.beatbump.normal]
hyperpipeNormalRedirectsChecks = [...redirects.hyperpipe.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = beatbumpNormalRedirectsChecks.indexOf(instance)
if (a > -1) beatbumpNormalRedirectsChecks.splice(a, 1)
const b = hyperpipeNormalRedirectsChecks.indexOf(instance)
if (b > -1) hyperpipeNormalRedirectsChecks.splice(b, 1)
}
browser.storage.local.set(
{
youtubeMusicRedirects: redirects,
beatbumpNormalRedirectsChecks,
beatbumpTorRedirectsChecks: [...redirects.beatbump.tor],
beatbumpI2pRedirectsChecks: [...redirects.beatbump.i2p],
beatbumpLokiRedirectsChecks: [...redirects.beatbump.loki],
hyperpipeNormalRedirectsChecks,
hyperpipeTorRedirectsChecks: [...redirects.hyperpipe.tor],
hyperpipeI2pRedirectsChecks: [...redirects.hyperpipe.i2p],
hyperpipeLokiRedirectsChecks: [...redirects.hyperpipe.loki],
},
() => resolve()
)
})
)
}
let disableYoutubeMusic,
youtubeMusicFrontend,
youtubeMusicRedirects,
protocol,
protocolFallback,
beatbumpNormalRedirectsChecks,
beatbumpNormalCustomRedirects,
beatbumpTorRedirectsChecks,
beatbumpTorCustomRedirects,
beatbumpI2pRedirectsChecks,
beatbumpI2pCustomRedirects,
beatbumpLokiRedirectsChecks,
beatbumpLokiCustomRedirects,
hyperpipeNormalRedirectsChecks,
hyperpipeNormalCustomRedirects,
hyperpipeTorRedirectsChecks,
hyperpipeTorCustomRedirects,
hyperpipeI2pRedirectsChecks,
hyperpipeI2pCustomRedirects,
hyperpipeLokiRedirectsChecks,
hyperpipeLokiCustomRedirects
function init() {
return new Promise(async resolve => {
browser.storage.local.get(
[
"disableYoutubeMusic",
"youtubeMusicFrontend",
"youtubeMusicRedirects",
"protocol",
"protocolFallback",
"beatbumpNormalRedirectsChecks",
"beatbumpNormalCustomRedirects",
"beatbumpTorRedirectsChecks",
"beatbumpTorCustomRedirects",
"beatbumpI2pRedirectsChecks",
"beatbumpI2pCustomRedirects",
"beatbumpLokiRedirectsChecks",
"beatbumpLokiCustomRedirects",
"hyperpipeNormalRedirectsChecks",
"hyperpipeNormalCustomRedirects",
"hyperpipeTorRedirectsChecks",
"hyperpipeTorCustomRedirects",
"hyperpipeI2pRedirectsChecks",
"hyperpipeI2pCustomRedirects",
"hyperpipeLokiRedirectsChecks",
"hyperpipeLokiCustomRedirects",
],
r => {
disableYoutubeMusic = r.disableYoutubeMusic
youtubeMusicFrontend = r.youtubeMusicFrontend
youtubeMusicRedirects = r.youtubeMusicRedirects
protocol = r.protocol
protocolFallback = r.protocolFallback
beatbumpNormalRedirectsChecks = r.beatbumpNormalRedirectsChecks
beatbumpNormalCustomRedirects = r.beatbumpNormalCustomRedirects
beatbumpTorRedirectsChecks = r.beatbumpTorRedirectsChecks
beatbumpTorCustomRedirects = r.beatbumpTorCustomRedirects
beatbumpI2pRedirectsChecks = r.beatbumpI2pRedirectsChecks
beatbumpI2pCustomRedirects = r.beatbumpI2pCustomRedirects
beatbumpLokiRedirectsChecks = r.beatbumpLokiRedirectsChecks
beatbumpLokiCustomRedirects = r.beatbumpLokiCustomRedirects
hyperpipeNormalRedirectsChecks = r.hyperpipeNormalRedirectsChecks
hyperpipeNormalCustomRedirects = r.hyperpipeNormalCustomRedirects
hyperpipeTorRedirectsChecks = r.hyperpipeTorRedirectsChecks
hyperpipeTorCustomRedirects = r.hyperpipeTorCustomRedirects
hyperpipeI2pRedirectsChecks = r.hyperpipeI2pRedirectsChecks
hyperpipeI2pCustomRedirects = r.hyperpipeI2pCustomRedirects
hyperpipeLokiRedirectsChecks = r.hyperpipeLokiRedirectsChecks
hyperpipeLokiCustomRedirects = r.hyperpipeLokiCustomRedirects
resolve()
}
)
})
}
init()
browser.storage.onChanged.addListener(init)
function all() {
return [
...beatbumpNormalRedirectsChecks,
...beatbumpNormalCustomRedirects,
...beatbumpTorRedirectsChecks,
...beatbumpTorCustomRedirects,
...beatbumpI2pRedirectsChecks,
...beatbumpI2pCustomRedirects,
...beatbumpLokiRedirectsChecks,
...beatbumpLokiCustomRedirects,
...hyperpipeNormalRedirectsChecks,
...hyperpipeNormalCustomRedirects,
...hyperpipeTorRedirectsChecks,
...hyperpipeTorCustomRedirects,
...hyperpipeI2pRedirectsChecks,
...hyperpipeI2pCustomRedirects,
...hyperpipeLokiRedirectsChecks,
...hyperpipeLokiCustomRedirects,
]
}
function getInstanceList() {
let tmpList = []
switch (youtubeMusicFrontend) {
case "beatbump":
switch (protocol) {
case "loki":
tmpList = [...beatbumpLokiRedirectsChecks, ...beatbumpLokiCustomRedirects]
break
case "i2p":
tmpList = [...beatbumpI2pRedirectsChecks, ...beatbumpI2pCustomRedirects]
break
case "tor":
tmpList = [...beatbumpTorRedirectsChecks, ...beatbumpTorCustomRedirects]
}
if ((tmpList.length === 0 && protocolFallback) || protocol == "normal") {
tmpList = [...beatbumpNormalRedirectsChecks, ...beatbumpNormalCustomRedirects]
}
break
case "hyperpipe":
switch (protocol) {
case "loki":
tmpList = [...hyperpipeLokiRedirectsChecks, ...hyperpipeLokiCustomRedirects]
break
case "i2p":
tmpList = [...hyperpipeI2pRedirectsChecks, ...hyperpipeI2pCustomRedirects]
break
case "tor":
tmpList = [...hyperpipeTorRedirectsChecks, ...hyperpipeTorCustomRedirects]
}
if ((tmpList.length === 0 && protocolFallback) || protocol == "normal") {
tmpList = [...hyperpipeNormalRedirectsChecks, ...hyperpipeNormalCustomRedirects]
}
}
return tmpList
}
function getUrl(randomInstance, url) {
switch (youtubeMusicFrontend) {
case "beatbump":
return `${randomInstance}${url.pathname}${url.search}`
.replace("/watch?v=", "/listen?id=")
.replace("/channel/", "/artist/")
.replace("/playlist?list=", "/playlist/VL")
.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/") + "?filter=song")
case "hyperpipe":
return `${randomInstance}${url.pathname}${url.search}`.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/"))
}
}
/*
Video
https://music.youtube.com/watch?v=_PkGiKBW-DA&list=RDAMVM_PkGiKBW-DA
https://beatbump.ml/listen?id=_PkGiKBW-DA&list=RDAMVM_PkGiKBW-DA
Playlist
https://music.youtube.com/playlist?list=PLqxd0OMLeWy64zlwhjouj92ISc38FbOns
https://music.youtube.com/playlist?list=PLqxd0OMLeWy7lrJSzt9LnOJjbC1IaruPM
https://music.youtube.com/playlist?list=PLQod4DlD72ZMJmOrSNbmEmK_iZ1oXPzKd
https://beatbump.ml/playlist/VLPLqxd0OMLeWy64zlwhjouj92ISc38FbOns
Channel
https://music.youtube.com/channel/UCfgmMDI7T5tOQqjnOBRe_wg
https://beatbump.ml/artist/UCfgmMDI7T5tOQqjnOBRe_wg
Albums
https://music.youtube.com/playlist?list=OLAK5uy_n-9HVh3cryV2gREZM9Sc0JwEKYjjfi0dU
https://music.youtube.com/playlist?list=OLAK5uy_lcr5O1zS8f6WIFI_yxqVp2RK9Dyy2bbw0
https://beatbump.ml/release?id=MPREb_3DURc4yEUtD
https://beatbump.ml/release?id=MPREb_evaZrV1WNdS
https://music.youtube.com/playlist?list=OLAK5uy_n6OHVllUZUCnlIY1m-gUaH8uqkN3Y-Ca8
https://music.youtube.com/playlist?list=OLAK5uy_nBOTxAc3_RGB82-Z54jdARGxGaCYlpngY
https://beatbump.ml/release?id=MPREb_QygdC0wEoLe
https://music.youtube.com/watch?v=R6gSMSYKhKU&list=OLAK5uy_n-9HVh3cryV2gREZM9Sc0JwEKYjjfi0dU
Search
https://music.youtube.com/search?q=test
https://beatbump.ml/search/test?filter=EgWKAQIIAWoKEAMQBBAKEAkQBQ%3D%3D
*/
function redirect(url, type, initiator, disableOverride) {
if (disableYoutubeMusic && !disableOverride) return
if (!targets.some(rx => rx.test(url.href))) return
let instancesList = getInstanceList()
if (instancesList.length === 0) return
const randomInstance = utils.getRandomInstance(instancesList)
return getUrl(randomInstance, url)
}
function switchInstance(url, disableOverride) {
return new Promise(async resolve => {
await init()
if (disableYoutubeMusic && !disableOverride) {
resolve()
return
}
const protocolHost = utils.protocolHost(url)
if (!all().includes(protocolHost)) {
resolve()
return
}
let instancesList = getInstanceList()
const i = instancesList.indexOf(protocolHost)
if (i > -1) instancesList.splice(i, 1)
if (instancesList.length === 0) {
resolve()
return
}
const randomInstance = utils.getRandomInstance(instancesList)
return getUrl(randomInstance, url)
})
}
function initDefaults() {
return new Promise(resolve => {
fetch("/instances/data.json")
.then(response => response.text())
.then(async data => {
let dataJson = JSON.parse(data)
for (let i = 0; i < frontends.length; i++) {
redirects[frontends[i]] = dataJson[frontends[i]]
}
browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
beatbumpNormalRedirectsChecks = [...redirects.beatbump.normal]
hyperpipeNormalRedirectsChecks = [...redirects.hyperpipe.normal]
for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
const a = beatbumpNormalRedirectsChecks.indexOf(instance)
if (a > -1) beatbumpNormalRedirectsChecks.splice(a, 1)
const b = hyperpipeNormalRedirectsChecks.indexOf(instance)
if (b > -1) hyperpipeNormalRedirectsChecks.splice(b, 1)
}
browser.storage.local.set(
{
disableYoutubeMusic: false,
youtubeMusicFrontend: "hyperpipe",
youtubeMusicRedirects: redirects,
beatbumpNormalRedirectsChecks,
beatbumpNormalCustomRedirects: [],
beatbumpTorRedirectsChecks: [...redirects.beatbump.tor],
beatbumpTorCustomRedirects: [],
beatbumpI2pRedirectsChecks: [...redirects.beatbump.i2p],
beatbumpI2pCustomRedirects: [],
beatbumpLokiRedirectsChecks: [...redirects.beatbump.loki],
beatbumpLokiCustomRedirects: [],
hyperpipeNormalRedirectsChecks,
hyperpipeNormalCustomRedirects: [],
hyperpipeTorRedirectsChecks: [...redirects.hyperpipe.tor],
hyperpipeTorCustomRedirects: [],
hyperpipeI2pRedirectsChecks: [...redirects.hyperpipe.i2p],
hyperpipeI2pCustomRedirects: [],
hyperpipeLokiRedirectsChecks: [...redirects.hyperpipe.loki],
hyperpipeLokiCustomRedirects: [],
},
() => resolve()
)
})
})
})
}
export default {
setRedirects,
switchInstance,
redirect,
initDefaults,
}

718
src/config/config.json Normal file
View File

@ -0,0 +1,718 @@
{
"networks": {
"clearnet": {
"tld": "org",
"name": "Clearnet"
},
"tor": {
"tld": "onion",
"name": "Tor"
},
"i2p": {
"tld": "i2p",
"name": "I2P"
},
"loki": {
"tld": "loki",
"name": "Lokinet"
}
},
"services": {
"youtube": {
"frontends": {
"invidious": {
"preferences": {
"cookies": [
"PREFS"
],
"localstorage": [
"dark_mode"
]
},
"name": "Invidious",
"embeddable": true,
"instanceList": true
},
"piped": {
"preferences": {
"localstorage": [
"bufferGoal",
"comments",
"disableLBRY",
"enabledCodecs",
"hl",
"homepage",
"instance",
"listen",
"minimizeDescription",
"playerAutoPlay",
"proxyLBRY",
"quality",
"region",
"selectedSkip",
"sponsorblock",
"theme",
"volume",
"watchHistory",
"localSubscriptions"
]
},
"name": "Piped",
"embeddable": true,
"instanceList": true
},
"pipedMaterial": {
"preferences": {
"localstorage": [
"PREFERENCES"
]
},
"name": "Piped-Material",
"embeddable": false,
"instanceList": true
},
"cloudtube": {
"preferences": {
"token": "token",
"fetchEndpoint": "/api/settings",
"setEndpoint": "/settings"
},
"name": "CloudTube",
"embeddable": false,
"instanceList": true
},
"freetube": {
"name": "FreeTube",
"embeddable": false,
"instanceList": false
},
"yattee": {
"name": "Yattee",
"embeddable": false,
"instanceList": false
}
},
"targets": [
"^https?:\\/{2}(?:www\\.|m\\.|)youtube.com(?!iframe_api\\/.*)",
"^https?:\\/{2}img\\.youtube.com\\/vi\\/.*\\/..*",
"^https?:\\/{2}(?:i|s)\\.ytimg.com\\/vi\\/.*\\/..*",
"^https?:\\/{2}(?:www\\.|music\\.|)youtube.com\\/watch?v=..*",
"^https?:\\/{2}youtu\\.be\\/..*",
"^https?:\\/{2}(?:www\\.|)(youtube|youtube-nocookie)\\.com\\/embed\\/..*"
],
"name": "Youtube",
"options": {
"enabled": true,
"redirectType": "both",
"frontend": "invidious",
"embedFrontend": "invidious"
},
"imageType": "png",
"embeddable": true,
"url": "https://youtube.com"
},
"youtubeMusic": {
"frontends": {
"beatbump": {
"preferences": {
"localstorage": [
"settings"
],
"indexeddb": "beatbump"
},
"name": "Beatbump",
"instanceList": true
},
"hyperpipe": {
"preferences": {
"localstorage": [
"api",
"authapi",
"codec",
"locale",
"next",
"pipedapi",
"quality",
"theme",
"vol"
],
"indexeddb": "hyperpipedb"
},
"name": "HyperPipe",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}music\\.youtube\\.com(\\/.*|$)"
],
"name": "YT Music",
"options": {
"enabled": true,
"frontend": "beatbump"
},
"imageType": "png",
"embeddable": false,
"url": "https://music.youtube.com"
},
"twitter": {
"frontends": {
"nitter": {
"preferences": {
"cookies": [
"autoplayGifs",
"bidiSupport",
"hideBanner",
"hidePins",
"hideReplies",
"hideTweetStats",
"hlsPlayback",
"infiniteScroll",
"mp4Playback",
"muteVideos",
"proxyVideos",
"replaceInstagram",
"replaceReddit",
"replaceTwitter",
"replaceYouTube",
"squareAvatars",
"theme"
]
},
"name": "Nitter",
"embeddable": true,
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}(www\\.|mobile\\.|)twitter\\.com",
"^https?:\\/{2}(pbs\\.|video\\.|)twimg\\.com",
"^https?:\\/{2}platform\\.twitter\\.com/embed",
"^https?:\\/{2}t\\.co"
],
"name": "Twitter",
"options": {
"enabled": true,
"redirectType": "both"
},
"imageType": "png",
"embeddable": true,
"url": "https://twitter.com"
},
"instagram": {
"frontends": {
"bibliogram": {
"preferences": {
"token": "token",
"fetchEndpoint": "/settings.json",
"setEndpoint": "/applysettings"
},
"name": "Bibliogram",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}(www\\.)?instagram\\.com\\/p\\/"
],
"name": "Instagram",
"options": {
"enabled": true
},
"imageType": "png",
"embeddable": false,
"url": "https://instagram.com"
},
"tiktok": {
"frontends": {
"proxiTok": {
"preferences": {
"cookies": [
"api-test_endpoints",
"theme"
]
},
"name": "ProxiTok",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}(www\\.|)tiktok\\.com.*"
],
"name": "TikTok",
"options": {
"enabled": true
},
"imageType": "png",
"embeddable": false,
"url": "https://tiktok.com"
},
"reddit": {
"frontends": {
"libreddit": {
"preferences": {
"cookies": [
"theme",
"front_page",
"layout",
"wide",
"post_sort",
"comment_sort",
"show_nsfw",
"autoplay_videos",
"use_hls",
"hide_hls_notification",
"subscriptions",
"filters"
]
},
"name": "Libreddit",
"instanceList": true
},
"teddit": {
"preferences": {
"cookies": [
"collapse_child_comments",
"default_comment_sort",
"domain_instagram",
"domain_twitter",
"domain_youtube",
"flairs",
"highlight_controversial",
"nsfw_enabled",
"post_media_max_height",
"prefer_frontpage",
"show_large_gallery_images",
"show_upvoted_percentage",
"show_upvotes",
"subbed_subreddits",
"theme",
"videos_muted"
]
},
"name": "Teddit",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}(www\\.|old\\.|np\\.|new\\.|amp\\.|)reddit\\.com",
"^https?:\\/{2}(i\\.|preview\\.)redd\\.it"
],
"name": "Reddit",
"options": {
"enabled": true,
"frontend": "libreddit"
},
"imageType": "png",
"embeddable": false,
"url": "https://reddit.com"
},
"imgur": {
"frontends": {
"rimgo": {
"name": "rimgo",
"embeddable": true,
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}([im]\\.)?(stack\\.)?imgur\\.(com|io)(\\/|$)"
],
"name": "Imgur",
"options": {
"enabled": true,
"redirectType": "both"
},
"imageType": "png",
"embeddable": true,
"url": "https://imgur.com"
},
"wikipedia": {
"frontends": {
"wikiless": {
"preferences": {
"cookies": [
"theme",
"default_lang"
]
},
"name": "Wikiless",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}(?:[a-z]+\\.)*wikipedia\\.org"
],
"name": "Wikipedia",
"options": {
"enabled": false
},
"imageType": "svg",
"embeddable": false,
"url": "https://wikipedia.org"
},
"medium": {
"frontends": {
"scribe": {
"name": "Scribe",
"instanceList": true
}
},
"targets": [
"(?:.*\\.)*(?<!(link\\.|cdn\\-images\\-\\d+\\.))medium\\.com(\\/.*)?$",
"^towardsdatascience\\.com",
"^uxdesign\\.cc",
"^uxplanet\\.org",
"^betterprogramming\\.pub",
"^aninjusticemag\\.com",
"^betterhumans\\.pub",
"^psiloveyou\\.xyz",
"^entrepreneurshandbook\\.co",
"^blog\\.coinbase\\.com",
"^levelup\\.gitconnected\\.com",
"^javascript\\.plainenglish\\.io",
"^blog\\.bitsrc\\.io",
"^itnext\\.io",
"^codeburst\\.io",
"^infosecwriteups\\.com",
"^blog\\.devgenius\\.io",
"^writingcooperative\\.com"
],
"name": "Medium",
"options": {
"enabled": true
},
"imageType": "svgMono",
"embeddable": false,
"url": "https://medium.com"
},
"quora": {
"frontends": {
"quetre": {
"preferences": {
"localstorage": [
"theme"
]
},
"name": "Quetre",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}([a-z]+\\.)*quora\\.com"
],
"name": "Quora",
"options": {
"enabled": true
},
"imageType": "png",
"embeddable": false,
"url": "https://quora.com"
},
"imdb": {
"frontends": {
"libremdb": {
"preferences": {
"localstorage": [
"theme"
]
},
"name": "libremdb",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}(?:www\\.|)imdb\\.com\\/title"
],
"name": "IMDb",
"options": {
"enabled": true
},
"imageType": "svg",
"embeddable": false,
"url": "https://imdb.com"
},
"reuters": {
"frontends": {
"neuters": {
"name": "Neuters",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}(www\\.|)reuters\\.com.*"
],
"name": "Reuters",
"options": {
"enabled": false
},
"imageType": "svg",
"embeddable": false,
"url": "https://reuters.com"
},
"fandom": {
"frontends": {
"breezeWiki": {
"name": "BreezeWiki",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}(?:[a-zA-Z0-9]+\\.)?fandom\\.com(?=(?:\\/wiki)|(?:\\/?$))"
],
"name": "Fandom",
"options": {
"enabled": true
},
"imageType": "svg",
"embeddable": false,
"url": "https://fandom.com"
},
"peertube": {
"frontends": {
"simpleertube": {
"name": "SimpleerTube",
"instanceList": true
}
},
"targets": "datajson",
"name": "PeerTube",
"options": {
"enabled": false
},
"imageType": "svg",
"embeddable": false,
"url": "https://joinpeertube.org"
},
"lbry": {
"frontends": {
"librarian": {
"preferences": {
"cookies": [
"nsfw",
"theme"
],
"localstorage": [
"autoplay",
"autoplayNextVid",
"collapseComments",
"plyr",
"sb_categories",
"showRelated"
]
},
"name": "Librarian",
"embeddable": true,
"instanceList": true
},
"lbryDesktop": {
"name": "LBRY Desktop",
"embeddable": false,
"instanceList": false
}
},
"targets": [
"^https?:\\/{2}odysee\\.com",
"^https?:\\/{2}lbry\\.tv"
],
"name": "LBRY",
"options": {
"enabled": true,
"frontend": "librarian",
"redirectType": "both",
"embedFrontend": "librarian"
},
"imageType": "png",
"embeddable": true,
"url": "https://odysee.com"
},
"search": {
"frontends": {
"searx": {
"preferences": {
"cookies": [
"advanced_search",
"autocomplete",
"categories",
"disabled_engines",
"disabled_plugins",
"doi_resolver",
"enabled_engines",
"enabled_plugins",
"image_proxy",
"language",
"locale",
"method",
"oscar-style",
"results_on_new_tab",
"safesearch",
"theme",
"tokens"
]
},
"name": "SearX",
"instanceList": true
},
"searxng": {
"preferences": {
"cookies": [
"autocomplete",
"categories",
"center_alignment",
"disabled_engines",
"disabled_plugins",
"doi_resolver",
"enabled_plugins",
"enabled_engines",
"image_proxy",
"infinite_scroll",
"language",
"locale",
"maintab",
"method",
"query_in_title",
"results_on_new_tab",
"safesearch",
"simple_style",
"theme",
"tokens"
]
},
"name": "SearXNG",
"instanceList": true
},
"whoogle": {
"name": "Whoogle",
"instanceList": true
},
"librex": {
"preferences": {
"cookies": [
"bibliogram",
"disable_frontends",
" disable_special",
"invidious",
"libreddit",
"nitter",
"proxitok",
"save",
"theme",
"wikiless"
]
},
"name": "LibreX",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}search\\.libredirect\\.invalid"
],
"name": "Search",
"options": {
"enabled": true,
"frontend": "searxng"
},
"imageType": "svgMono",
"embeddable": false,
"url": "https://search.libredirect.invalid"
},
"translate": {
"frontends": {
"simplyTranslate": {
"preferences": {
"cookies": [
"from_lang",
"to_lang",
"tts_enabled",
"use_text_fields"
]
},
"name": "SimplyTranslate",
"instanceList": true
},
"lingva": {
"preferences": {
"localstorage": [
"isauto",
"source",
"target",
"chakra-ui-color-mode"
]
},
"name": "Lingva Translate",
"instanceList": true
},
"libreTranslate": {
"name": "LibreTranslate",
"instanceList": true
}
},
"targets": [
"^https?:\\/{2}translate\\.google(\\.[a-z]{2,3}){1,2}\\/",
"^https?:\\/{2}translate\\.libredirect\\.invalid"
],
"name": "Translate",
"options": {
"enabled": true,
"frontend": "simplyTranslate"
},
"imageType": "svgMono",
"embeddable": false,
"url": "https://translate.libredirect.invalid"
},
"maps": {
"frontends": {
"facil": {
"name": "FacilMap",
"instanceList": true
},
"osm": {
"name": "OpenStreetMap",
"instanceList": false,
"singleInstance": "https://www.openstreetmap.org"
}
},
"targets": [
"^https?:\\/{2}maps\\.libredirect\\.invalid",
"^https?:\\/{2}(((www|maps)\\.)?(google\\.).*(\\/maps)|maps\\.(google\\.).*)"
],
"name": "Maps",
"options": {
"enabled": true,
"frontend": "osm"
},
"imageType": "svgMono",
"embeddable": false,
"url": "https://maps.libredirect.invalid"
},
"sendFiles": {
"frontends": {
"send": {
"name": "Send",
"instanceList": "true"
}
},
"targets": [
"^https?:\\/{2}send\\.libredirect\\.invalid",
"^https?:\\/{2}send\\.firefox\\.com\\/?$",
"^https?:\\/{2}sendfiles\\.online\\/?$"
],
"name": "Send Files",
"options": {
"enabled": true
},
"imageType": "svgMono",
"embeddable": false,
"url": "https://send.libredirect.invalid"
}
},
"blacklist": {
"cloudflare": {
"color": "red"
},
"authenticate": {
"color": "orange"
},
"offline": {
"color": "grey"
}
}
}

View File

@ -1,6 +1,6 @@
{
"normal": ["https://beatbump.ml", "https://beatbump.esmailelbob.xyz"],
"tor": ["http://beatbump.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion"],
"clearnet": ["https://beatbump.ml", "https://beatbump.esmailelbob.xyz"],
"tor": ["http://beatbump.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd.onion"],
"i2p": [],
"loki": []
}

View File

@ -1,5 +1,5 @@
{
"normal": ["https://bibliogram.1d4.us", "https://bibliogram.froth.zone", "https://ig.tokhmi.xyz", "https://ig.beparanoid.de", "https://bibliogram.priv.pw"],
"clearnet": ["https://bibliogram.1d4.us", "https://bibliogram.froth.zone", "https://ig.tokhmi.xyz", "https://ig.beparanoid.de", "https://bibliogram.priv.pw"],
"tor": [],
"i2p": [],
"loki": []

View File

@ -7,11 +7,9 @@
"https://piped.moomoo.me",
"https://piped.mha.fi",
"https://de-piped.shimul.me",
"https://pipedus.palash.dev",
"https://watch.whatever.social",
"https://piped.garudalinux.org",
"https://y.rivo.lol",
"https://cringe.whatever.social",
"https://nitter.domain.glass",
"https://birdsite.xanny.family",
"https://notabird.site",
@ -32,15 +30,15 @@
"https://libreddit.domain.glass",
"https://r.nf",
"https://libreddit.hu",
"https://lr.stilic.ml",
"https://reddi.tk",
"https://r.walkx.org",
"https://libreddit.yonalee.eu",
"https://libreddit.winscloud.net",
"https://r.ahwx.org",
"https://reddit.dr460nf1r3.org",
"https://libreddit.encrypted-data.xyz",
"https://libreddit.eu.org",
"https://libreddit.cachyos.org",
"https://futureddit.gq",
"https://libreddit.freedit.eu",
"https://teddit.domain.glass",
"https://teddit.httpjames.space",
"https://teddit.encrypted-data.xyz",
@ -48,11 +46,13 @@
"https://tedd.it",
"https://wiki.privacytools.io",
"https://teddit.rawbit.ninja",
"https://wiki.604kph.xyz",
"https://wiki.privacytools.io",
"https://wikiless.rawbit.ninja",
"https://scribe.rawbit.ninja",
"https://lingva.garudalinux.org",
"https://translate.dr460nf1r3.org",
"https://libretranslate.com",
"https://searx.run",
"https://searx.org",
"https://search.garudalinux.org",
@ -68,31 +68,32 @@
],
"offline": [
"https://invidious.rhyshl.live",
"https://piped.esmailelbob.xyz",
"https://proxitok.odyssey346.dev",
"https://nhanh.cloud",
"https://ntr.odyssey346.dev",
"https://libredd.it",
"https://libreddit.notyourcomputer.net",
"https://futureddit.gq",
"https://teddit.ggc-project.de",
"https://teddit.nautolan.racing",
"https://quetreus.herokuapp.com",
"https://teddit.froth.zone",
"https://teddit.tokhmi.xyz",
"https://wiki.privacytools.io",
"https://quetre.odyssey346.dev",
"https://translate.northboot.xyz",
"https://translate.priv.pw",
"https://st.odyssey346.dev",
"https://translate.projectsegfau.lt",
"https://jsearch.pw",
"https://searx.gnu.style",
"https://searx.semipvt.com",
"https://etsi.me",
"https://search.chemicals-in-the-water.eu",
"https://search.zzls.xyz",
"https://searx.ericaftereric.top",
"https://searx.fmac.xyz",
"https://www.webrats.xyz",
"https://gowogle.voring.me",
"https://whoogle.esmailelbob.xyz",
"https://search.wef.lol",
"https://i.bcow.xyz",
"https://i.actionsack.com",
"https://lbry.bcow.xyz",
"https://beatbump.ml"
"https://beatbump.ml",
"https://bw.odyssey346.dev"
]
}

View File

@ -1,5 +1,5 @@
{
"normal": ["https://tube.cadence.moe"],
"clearnet": ["https://tube.cadence.moe"],
"tor": [],
"i2p": [],
"loki": []

View File

@ -1,6 +1,6 @@
{
"invidious": {
"normal": [
"clearnet": [
"https://yewtu.be",
"https://vid.puffyan.us",
"https://invidious.snopyta.org",
@ -14,34 +14,35 @@
"https://invidious.flokinet.to",
"https://inv.bp.projectsegfau.lt",
"https://inv.vern.cc",
"https://invidious.projectsegfau.lt",
"https://invidious.nerdvpn.de",
"https://invidious.projectsegfau.lt",
"https://invidious.rhyshl.live",
"https://inv.privacy.com.de",
"https://invidious.slipfox.xyz",
"https://invidious.esmailelbob.xyz",
"https://youtube.076.ne.jp",
"https://invidious.weblibre.org",
"https://invidious.namazso.eu"
],
"tor": [
"http://am74vkcrjp2d5v36lcdqgsj2m6x36tbrkhsruoegwfcizzabnfgf5zyd.onion",
"http://inv.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion",
"http://invidious.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd.onion",
"http://euxxcnhsynwmfidvhjf6uzptsmh4dipkmgdmcmxxuo7tunp3ad2jrwyd.onion",
"http://u2cvlit75owumwpy4dj2hsmvkq7nvrclkpht7xgyye2pyoxhpmclkrad.onion",
"http://osbivz6guyeahrwp2lnwyjk2xos342h4ocsxyqrlaopqjuhwn2djiiyd.onion",
"http://grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion",
"http://kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad.onion",
"http://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion",
"http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion",
"http://ng27owmagn5amdm7l5s3rsqxwscl5ynppnis5dqcasogkyxcfqn7psid.onion"
"http://grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion",
"http://osbivz6guyeahrwp2lnwyjk2xos342h4ocsxyqrlaopqjuhwn2djiiyd.onion",
"http://u2cvlit75owumwpy4dj2hsmvkq7nvrclkpht7xgyye2pyoxhpmclkrad.onion",
"http://euxxcnhsynwmfidvhjf6uzptsmh4dipkmgdmcmxxuo7tunp3ad2jrwyd.onion",
"http://invidious.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion",
"http://inv.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion",
"http://am74vkcrjp2d5v36lcdqgsj2m6x36tbrkhsruoegwfcizzabnfgf5zyd.onion",
"http://ng27owmagn5amdm7l5s3rsqxwscl5ynppnis5dqcasogkyxcfqn7psid.onion",
"http://kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad.onion"
],
"i2p": [
"http://verni6dr4qxjgjumnvesxerh5rvhv6oy5ddeibaqy5d7tgbiiyfa.b32.i2p"
],
"i2p": [],
"loki": []
},
"piped": {
"normal": [
"clearnet": [
"https://piped.kavin.rocks",
"https://piped.tokhmi.xyz",
"https://piped.moomoo.me",
@ -57,29 +58,26 @@
"https://piped.esmailelbob.xyz",
"https://piped.projectsegfau.lt",
"https://piped.privacydev.net",
"https://piped.palveluntarjoaja.eu",
"https://piped.smnz.de",
"https://piped.adminforge.de",
"https://watch.whatevertinfoil.de"
"https://watch.whatevertinfoil.de",
"https://piped.qdi.fi"
],
"tor": [],
"i2p": [],
"loki": []
},
"pipedMaterial": {
"normal": [
"https://piped-material.১.net",
"https://piped-material.ftp.sh",
"https://piped-staging.ftp.sh",
"https://ui.piped.১.net",
"https://ng.piped.১.net"
"clearnet": [
"https://piped-material.xn--17b.net",
"https://piped-material.ftp.sh"
],
"tor": [],
"i2p": [],
"loki": []
},
"cloudtube": {
"normal": [
"clearnet": [
"https://tube.cadence.moe"
],
"tor": [],
@ -87,12 +85,11 @@
"loki": []
},
"proxiTok": {
"normal": [
"clearnet": [
"https://proxitok.pabloferreiro.es",
"https://proxitok.pussthecat.org",
"https://tok.habedieeh.re",
"https://proxitok.esmailelbob.xyz",
"https://cringe.whatever.social",
"https://proxitok.dhusch.de",
"https://proxitok.privacydev.net",
"https://proxitok.odyssey346.dev",
@ -100,12 +97,14 @@
"https://tok.adminforge.de",
"https://proxitok.manasiwibi.com"
],
"tor": [],
"tor": [
"http://vywqfflneajejuhg7o5iklqvzemu2fcdrb3gtkvnyqsho6qin5svdsad.onion"
],
"i2p": [],
"loki": []
},
"send": {
"normal": [
"clearnet": [
"https://send.vis.ee",
"https://send.zcyph.cc",
"https://send.turingpoint.de",
@ -129,9 +128,9 @@
"loki": []
},
"nitter": {
"normal": [
"clearnet": [
"https://nitter.net",
"https://nitter.42l.fr",
"https://nitter.lacontrevoie.fr",
"https://nitter.pussthecat.org",
"https://nitter:nitter@nitter.nixnet.services",
"https://nitter.fdn.fr",
@ -207,7 +206,12 @@
"https://nitter.smnz.de",
"https://nitter.twei.space",
"https://nitter.inpt.fr",
"https://nitter.d420.de"
"https://nitter.d420.de",
"https://nitter.caioalonso.com",
"https://nitter.at",
"https://nitter.drivet.xyz",
"https://nitter.pw",
"https://nitter.nicfab.eu"
],
"tor": [
"http://nitter7bryz3jv7e3uekphigvmoyoem4al3fynerxkj22dmoxoq553qd.onion",
@ -233,7 +237,11 @@
"http://wiio4sgs4247brk7hj6qck2jxnvldwfdbguigc5ivpxrsegnliyfvuqd.onion",
"http://qwikxx2erhx6qrymued6ox2qkf2yeogjwypqvzoif4fqkljixasr6oid.onion",
"http://4g47cxugkohbweao2x66nnxxfoe3k7gdfzxej537nhdbwr522sbjxeqd.onion",
"http://tw.lpoaj7z2zkajuhgnlltpeqh3zyq7wk2iyeggqaduhgxhyajtdt2j7wad.onion"
"http://nt.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion",
"http://tw.lpoaj7z2zkajuhgnlltpeqh3zyq7wk2iyeggqaduhgxhyajtdt2j7wad.onion",
"http://r2eqimhkvxboaltbdsectoo3hkf476pyemsdykclexzajbfx5v6ojlyd.onion",
"http://li7snkj6oituazbkr5clmilccwwumhd2dntbhttxomy4dfakeeoar4qd.onion",
"http://a5xyidyppowvblric6k6nixgf2eqwnb7zzeaarj7slqbv7tb6ip5t3ad.onion"
],
"i2p": [
"http://axd6uavsstsrvstva4mzlzh4ct76rc6zdug3nxdgeitrzczhzf4q.b32.i2p",
@ -247,7 +255,7 @@
]
},
"bibliogram": {
"normal": [
"clearnet": [
"https://bibliogram.1d4.us",
"https://bibliogram.froth.zone",
"https://ig.tokhmi.xyz",
@ -259,97 +267,65 @@
"loki": []
},
"libreddit": {
"normal": [
"https://libredd.it",
"clearnet": [
"https://libreddit.spike.codes",
"https://libreddit.dothq.co",
"https://libreddit.kavin.rocks",
"https://reddit.invak.id",
"https://reddit.phii.me",
"https://lr.riverside.rocks",
"https://libreddit.strongthany.cc",
"https://libreddit.database.red",
"https://libreddit.privacy.com.de",
"https://libreddit.domain.glass",
"https://libreddit.sugoma.tk",
"https://libreddit.jamiethalacker.dev",
"https://reddit.artemislena.eu",
"https://r.nf",
"https://libreddit.some-things.org",
"https://reddit.stuehieyr.com",
"https://lr.mint.lgbt",
"https://libreddit.igna.rocks",
"https://libreddit.autarkic.org",
"https://libreddit.flux.industries",
"https://libreddit.drivet.xyz",
"https://lr.oversold.host",
"https://libreddit.de",
"https://libreddit.pussthecat.org",
"https://libreddit.mutahar.rocks",
"https://libreddit.northboot.xyz",
"https://leddit.xyz",
"https://de.leddit.xyz",
"https://lr.cowfee.moe",
"https://libreddit.hu",
"https://libreddit.totaldarkness.net",
"https://libreddit.esmailelbob.xyz",
"https://lr.vern.cc",
"https://libreddit.nl",
"https://lr.stilic.ml",
"https://reddi.tk",
"https://libreddit.bus-hit.me",
"https://libreddit.datatunnel.xyz",
"https://libreddit.crewz.me",
"https://r.walkx.org",
"https://libreddit.kylrth.com",
"https://libreddit.yonalee.eu",
"https://libreddit.winscloud.net",
"https://libreddit.tiekoetter.com",
"https://reddit.rtrace.io",
"https://libreddit.lunar.icu",
"https://libreddit.privacydev.net",
"https://libreddit.notyourcomputer.net",
"https://r.ahwx.org",
"https://bob.fr.to",
"https://reddit.beparanoid.de",
"https://libreddit.dcs0.hu",
"https://reddit.dr460nf1r3.org",
"https://rd.jae.su",
"https://libreddit.mha.fi",
"https://libreddit.foss.wtf",
"https://libreddit.encrypted-data.xyz",
"https://libreddit.eu.org",
"https://l.opnxng.com"
"https://l.opnxng.com",
"https://libreddit.cachyos.org",
"https://rd.funami.tech",
"https://libreddit.projectsegfau.lt",
"https://futureddit.gq",
"https://lr.slipfox.xyz",
"https://libreddit.oxymagnesium.com",
"https://reddit.utsav2.dev",
"https://libreddit.freedit.eu"
],
"tor": [
"http://spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion",
"http://fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion",
"http://kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion",
"http://inytumdgnri7xsqtvpntjevaelxtgbjqkuqhtf6txxhwbll2fwqtakqd.onion",
"http://liredejj74h5xjqr2dylnl5howb2bpikfowqoveub55ru27x43357iid.onion",
"http://kzhfp3nvb4qp575vy23ccbrgfocezjtl5dx66uthgrhu7nscu6rcwjyd.onion",
"http://ecue64ybzvn6vjzl37kcsnwt4ycmbsyf74nbttyg7rkc3t3qwnj7mcyd.onion",
"http://ledditqo2mxfvlgobxnlhrkq4dh34jss6evfkdkb2thlvy6dn4f4gpyd.onion",
"http://libredoxhxwnmsb6dvzzd35hmgzmawsq5i764es7witwhddvpc2razid.onion",
"http://libreddit.2syis2nnyytz6jnusnjurva4swlaizlnleiks5mjp46phuwjbdjqwgqd.onion",
"http://ol5begilptoou34emq2sshf3may3hlblvipdjtybbovpb7c7zodxmtqd.onion",
"http://lbrdtjaj7567ptdd4rv74lv27qhxfkraabnyphgcvptl64ijx2tijwid.onion",
"http://libreddit.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd.onion",
"http://reddit.prnoid54e44a4bduq5due64jkk7wcnkxcp5kv3juncm7veptjcqudgyd.onion",
"http://inz6tbezfwzexva6dize4cqraj2tjdhygxabmcgysccesvw2pybzhbyd.onion",
"http://libreddit.micohauwkjbyw5meacrb4ipicwvwg4xtzl7y7viv53kig2mdcsvwkyyd.onion",
"http://lr.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion"
"http://libreddit.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion",
"http://ojwp2gtj7dq7scd7gnbac6wp53tklgsicteabrnx2pr7zai64wriiaad.onion"
],
"i2p": [],
"loki": []
},
"teddit": {
"normal": [
"clearnet": [
"https://teddit.net",
"https://teddit.ggc-project.de",
"https://teddit.zaggy.nl",
"https://teddit.namazso.eu",
"https://teddit.nautolan.racing",
"https://teddit.tinfoil-hat.net",
"https://teddit.domain.glass",
"https://snoo.ioens.is",
@ -386,11 +362,16 @@
"http://teddit.lpoaj7z2zkajuhgnlltpeqh3zyq7wk2iyeggqaduhgxhyajtdt2j7wad.onion",
"http://24fympskbrdgbf4afuvhqwwl2tv3y2vwxg5t2ktozd4j5b3fob5ntzyd.onion"
],
"i2p": [],
"i2p": [
"http://xugoqcf2pftm76vbznx4xuhrzyb5b6zwpizpnw2hysexjdn5l2tq.b32.i2p",
"http://teddit.i2p",
"http://vzeiwzi7ogwl3ijrfek4fbtwhvamxcpyqoc3s4vcgnhlp54s5clq.b32.i2p",
"http://verncco2oaxjikammz4pi7umzp673cme6zuemx7yeeewspwrw3va.b32.i2p"
],
"loki": []
},
"wikiless": {
"normal": [
"clearnet": [
"https://wikiless.org",
"https://wikiless.sethforprivacy.com",
"https://wiki.604kph.xyz",
@ -423,7 +404,7 @@
"loki": []
},
"scribe": {
"normal": [
"clearnet": [
"https://scribe.rip",
"https://scribe.nixnet.services",
"https://scribe.citizen4.eu",
@ -439,7 +420,7 @@
"loki": []
},
"quetre": {
"normal": [
"clearnet": [
"https://quetre.iket.me",
"https://qr.vern.cc",
"https://quetre.pussthecat.org",
@ -454,17 +435,31 @@
"http://quetre.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion",
"http://qr.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion"
],
"i2p": [],
"i2p": [
"http://vernnflenvsqccuanaun7yydnmturi4jkyxlyzhn6ultpje66c3q.b32.i2p"
],
"loki": []
},
"libremdb": {
"normal": [],
"tor": [],
"i2p": [],
"clearnet": [
"https://libremdb.iket.me",
"https://libremdb.pussthecat.org",
"https://libremdbeu.herokuapp.com",
"https://lmdb.tokhmi.xyz",
"https://libremdb.esmailelbob.xyz",
"https://ld.vern.cc"
],
"tor": [
"http://libremdb.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion",
"http://ld.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion"
],
"i2p": [
"http://vernz3ubrntql4wrgyrssd6u3qzi36zrhz2agbo6vibzbs5olk2q.b32.i2p"
],
"loki": []
},
"simplyTranslate": {
"normal": [
"clearnet": [
"https://simplytranslate.org",
"https://st.tokhmi.xyz",
"https://translate.josias.dev",
@ -499,7 +494,7 @@
]
},
"lingva": {
"normal": [
"clearnet": [
"https://lingva.ml",
"https://translate.igna.ooo",
"https://lingva.pussthecat.org",
@ -514,8 +509,26 @@
"i2p": [],
"loki": []
},
"libreTranslate": {
"clearnet": [
"https://libretranslate.com",
"https://libretranslate.de",
"https://translate.argosopentech.com",
"https://translate.api.skitzen.com",
"https://translate.fortytwo-it.com",
"https://translate.terraprint.co",
"https://lt.vern.cc"
],
"tor": [
"http://lt.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion"
],
"i2p": [
"http://vernf45n7mxwqnp5riaax7p67pwcl7wcefdcnqqvim7ckdx4264a.b32.i2p"
],
"loki": []
},
"searx": {
"normal": [
"clearnet": [
"https://dynabyte.ca",
"https://jsearch.pw",
"https://search.ethibox.fr",
@ -532,6 +545,7 @@
"https://searx.nakhan.net",
"https://searx.netzspielplatz.de",
"https://searx.nixnet.services",
"https://searx.rimkus.it",
"https://searx.ru",
"https://searx.run",
"https://searx.semipvt.com",
@ -554,13 +568,12 @@
],
"tor": [
"http://3afisqjw2rxm6z7mmstyt5rx75qfqrgxnkzftknbp2vhipr2nrmrjdyd.onion",
"http://w5rl6wsd7mzj4bdkbuqvzidet5osdsm5jhg2f7nvfidakfq5exda5wid.onion",
"http://privateoz3u5utrimal2edr56j3r5caakektxxgixigdkycuxigvquid.onion",
"http://yra4tke2pwcnatxjkufpw6kvebu3h3ti2jca2lcdpgx3mpwol326lzid.onion",
"http://z5vawdol25vrmorm4yydmohsd4u6rdoj2sylvoi3e3nqvxkvpqul7bqd.onion",
"http://searxdr3pqz4nydgnqocsia2xbywptxbkympa2emn7zlgggrir4bkfad.onion",
"http://zbuc3bbzbfdqqo2x46repx2ddajbha6fpsjeeptjhhhhzji3zopxdqyd.onion",
"http://f4qfqajszpx5b7itzxt6mb7kj4ktpgbdq7lq6xaiqyqx6a7de3epptad.onion",
"http://searxfilowxokbogygrigir4wqxfxqzuxofxgdon7dg6rsii4yxzytyd.onion"
"http://searx.micohauwkjbyw5meacrb4ipicwvwg4xtzl7y7viv53kig2mdcsvwkyyd.onion"
],
"i2p": [
"http://ransack.i2p",
@ -569,11 +582,10 @@
"loki": []
},
"searxng": {
"normal": [
"clearnet": [
"https://darmarit.org/searx",
"https://de.xcxc.ml",
"https://etsi.me",
"https://icanfindit.online",
"https://jackgoss.xyz",
"https://metasearch.nl",
"https://northboot.xyz",
@ -583,6 +595,7 @@
"https://priv.au",
"https://privatus.live",
"https://s.frlt.one",
"https://s.trung.fun",
"https://s.zhaocloud.net",
"https://saber.tk",
"https://search.0relay.com",
@ -628,13 +641,13 @@
"https://searx.orion-hub.fr",
"https://searx.priv.pw",
"https://searx.prvcy.eu",
"https://searx.rimkus.it",
"https://searx.sethforprivacy.com",
"https://searx.sev.monster",
"https://searx.slipfox.xyz/searx",
"https://searx.tiekoetter.com",
"https://searx.zcyph.cc",
"https://searxng.nicfab.it",
"https://searxng.dupa.edu.pl",
"https://searxng.nicfab.eu",
"https://searxng.zackptg5.com",
"https://serx.ml",
"https://sh0.it",
@ -648,14 +661,15 @@
"https://xo.wtf"
],
"tor": [
"http://w5rl6wsd7mzj4bdkbuqvzidet5osdsm5jhg2f7nvfidakfq5exda5wid.onion",
"http://4n53nafyi77iplnbrpmxnp3x4exbswwxigujaxy3b37fvr7bvlopxeyd.onion",
"http://privateoz3u5utrimal2edr56j3r5caakektxxgixigdkycuxigvquid.onion",
"http://b6sxmon57qza6dt36li7huabie5ntrvjr4q5rc2vvbn4hqvzd4phrvyd.onion",
"http://searxngg6zleq6ceboe5ltkyo4hyrb3aaycrgzmrljv3jjlb5vcytead.onion",
"http://gbat2pbpg7ys3fi3pbp64667tt5x66mg45xok35bxdw7v55brm7a27yd.onion",
"http://b2c7fvbhnfvwnl6oh2tydhzfx4i37kmmrycq42heqbbe7wovq3uzenid.onion",
"http://searxdr3pqz4nydgnqocsia2xbywptxbkympa2emn7zlgggrir4bkfad.onion",
"http://searx.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion",
"http://searx.micohauwkjbyw5meacrb4ipicwvwg4xtzl7y7viv53kig2mdcsvwkyyd.onion",
"http://searxfilowxokbogygrigir4wqxfxqzuxofxgdon7dg6rsii4yxzytyd.onion",
"http://searx.privpw3tndpkw6pnp3g727zfgfdzbu3k6a7chv226s3xymv2p4eiuqyd.onion",
"http://rq2w52kyrif3xpfihkgjnhqm3a5aqhoikpv72z3drpjglfzc2wr5z4yd.onion",
"http://fub6vgedgeadlu3ctskrpkcqjruh76tckwtj5swfhyblgml2tzgzckqd.onion/searx",
@ -667,7 +681,7 @@
"loki": []
},
"whoogle": {
"normal": [
"clearnet": [
"https://gowogle.voring.me",
"https://s.tokhmi.xyz",
"https://search.albony.xyz",
@ -687,10 +701,11 @@
"loki": []
},
"librex": {
"normal": [
"clearnet": [
"https://librex.beparanoid.de",
"https://librex.extravi.dev",
"https://search.davidovski.xyz",
"https://librex.kitscomputer.tk",
"https://search.funami.tech",
"https://librex.catalyst.sx",
"https://search.madreyk.xyz",
@ -698,8 +713,7 @@
],
"tor": [
"http://librex.2356uhnbpv5nk3bni5bv6jg2cd6lgj664kwx3lhyelstpttpyv4kk2qd.onion",
"http://ncblhz7q4sfbf755bdbhebfzxcpypz7ewafgi4agatecojz7pln4i3id.onion",
"http://librex.so2mpiyfo4cje7bof5v52y3cvjyo2haxpqfvut4sr6gj2ul4mddx2jid.onion"
"http://ncblhz7q4sfbf755bdbhebfzxcpypz7ewafgi4agatecojz7pln4i3id.onion"
],
"i2p": [
"http://rra33hiaf6nmby7jfpqe2gqmng3jnzkvbu2n7jgce7vbhoyuhzya.b32.i2p"
@ -707,7 +721,7 @@
"loki": []
},
"rimgo": {
"normal": [
"clearnet": [
"https://i.bcow.xyz",
"https://rimgo.pussthecat.org",
"https://rimgo.totaldarkness.net",
@ -729,7 +743,7 @@
"loki": []
},
"librarian": {
"normal": [
"clearnet": [
"https://lbry.bcow.xyz",
"https://odysee.076.ne.jp",
"https://librarian.pussthecat.org",
@ -752,7 +766,7 @@
"loki": []
},
"neuters": {
"normal": [
"clearnet": [
"https://neuters.de"
],
"tor": [],
@ -760,18 +774,18 @@
"loki": []
},
"beatbump": {
"normal": [
"clearnet": [
"https://beatbump.ml",
"https://beatbump.esmailelbob.xyz"
],
"tor": [
"http://beatbump.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion"
"http://beatbump.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd.onion"
],
"i2p": [],
"loki": []
},
"hyperpipe": {
"normal": [
"clearnet": [
"https://hyperpipe.surge.sh",
"https://hyperpipe.esmailelbob.xyz",
"https://listen.whatever.social",
@ -784,7 +798,7 @@
"loki": []
},
"facil": {
"normal": [
"clearnet": [
"https://facilmap.org"
],
"tor": [],
@ -792,7 +806,7 @@
"loki": []
},
"simpleertube": {
"normal": [
"clearnet": [
"https://tube.simple-web.org",
"https://simpleertube.esmailelbob.xyz",
"https://stube.tokhmi.xyz",
@ -802,11 +816,30 @@
"i2p": [],
"loki": []
},
"breezeWiki": {
"clearnet": [
"https://breezewiki.com",
"https://breezewiki.pussthecat.org",
"https://bw.odyssey346.dev",
"https://bw.vern.cc",
"https://breezewiki.esmailelbob.xyz"
],
"tor": [],
"i2p": [],
"loki": []
},
"peertube": [
"https://search.joinpeertube.org",
"https://video.bmu.cloud",
"https://freedomadultgames.video",
"https://tbh.co-shaoghal.net",
"https://tube.kansanvalta.org",
"https://ytube.retronerd.at",
"https://tube.media-techport.de",
"https://notobono.de",
"https://video.vegafjord.me",
"https://peertube-us.howlround.com",
"https://peertube-eu.howlround.com",
"https://guntube.net",
"https://pt.freedomwolf.cc",
"https://vr360tube.online",
"https://bodavr.com",
@ -818,7 +851,6 @@
"https://videos.im.allmendenetz.de",
"https://tube.cyberia.club",
"https://casstream.nohost.me",
"https://peertube.as62430.net",
"https://peertube.askan.info",
"https://apertatube.net",
"https://beetoons.tv",
@ -834,7 +866,6 @@
"https://tube-test.apps.education.fr",
"https://tube-sciences-technologies.apps.education.fr",
"https://tube-institutionnel.apps.education.fr",
"https://trutube.online",
"https://tube-cycle-3.apps.education.fr",
"https://video.manicphase.me",
"https://tubulus.openlatin.org",
@ -855,7 +886,6 @@
"https://tube.reseau-canope.fr",
"https://frentube.myyouniverse.observer",
"https://tube-maternelle.apps.education.fr",
"https://peertube.onionstorm.net",
"https://dev.dollarvigilante.tv",
"https://video.trankil.info",
"https://video.uriopss-pdl.fr",
@ -863,13 +893,11 @@
"https://video.3cmr.fr",
"https://peertube.miguelcr.me",
"https://video.thinkof.name",
"https://video.comun.al",
"https://video.occm.cc",
"https://tube-action-educative.apps.education.fr",
"https://jahve.pl",
"https://videos.yesil.club",
"https://peertube.adjutor.xyz",
"https://peertube.terranout.mine.nu",
"https://tube.hunterjozwiak.com",
"https://tube-numerique-educatif.apps.education.fr",
"https://tube.itsg.host",
@ -904,7 +932,6 @@
"https://seka.pona.la",
"https://syop.tv",
"https://watch.thelema.social",
"https://tube.miegl.cz",
"https://mov.clov.fr",
"https://video.vaku.org.ua",
"https://videos.trom.lt",
@ -938,13 +965,10 @@
"https://videos.tormentasolar.win",
"https://tube.nestor.coop",
"https://live.oldskool.fi",
"https://dytube.com",
"https://tube.thierrytalbert.fr",
"https://peertube.informaction.info",
"https://tube.ac-amiens.fr",
"https://tube.alado.space",
"https://tube.network.europa.eu",
"https://vnchich.com",
"https://pt.maciej.website",
"https://peertube.frontmediatique.fr",
"https://peertube.bgzashtita.es",
@ -970,16 +994,13 @@
"https://ocfedtest.hosted.spacebear.ee",
"https://video.lono.space",
"https://mirrored.rocks",
"https://videopen.net",
"https://demo.lioncast.org",
"https://peertube.get-racing.de",
"https://pierre.tube",
"https://mirametube.fr",
"https://vidz.dou.bet",
"https://videos.redeyes.site",
"https://video.hostpath.de",
"https://free-streams.com",
"https://tube.pawelko.net",
"https://video.livecchi.cloud",
"https://peertube.gsugambit.com",
"https://pt.nospy.net",
@ -989,19 +1010,15 @@
"https://videos-passages.huma-num.fr",
"https://video.linc.systems",
"https://video.sftblw.moe",
"https://peertube.dsmouse.net",
"https://ptube.horsentiers.fr",
"https://video.cnt.social",
"https://tube.03281.fspfc.org",
"https://tube.linc.systems",
"https://peertube.ketchup.noho.st",
"https://yt.x1337x.fr",
"https://videos.rabbit-company.com",
"https://video.paradigmthreat.net",
"https://video.lincolncyber.com",
"https://vid.twhtv.club",
"https://video.retroedge.tech",
"https://truvitv.com",
"https://pt.ilyamikcoder.com",
"https://peertube.sensin.eu",
"https://video.sadmin.io",
@ -1023,8 +1040,6 @@
"https://video.snug.moe",
"https://video.avant-le-strike.buzz",
"https://videos.ritimo.org",
"https://videos.ephphatha.church",
"https://video.cerclearistote.com",
"https://video.greenmycity.eu",
"https://przej.me",
"https://pt.mezzo.moe",
@ -1036,7 +1051,6 @@
"https://bee-tube.fr",
"https://vid.prometheus.systems",
"https://tube.nx12.net",
"https://redundant2.peertube.support",
"https://peertube.ignifi.me",
"https://tv.based.quest",
"https://peertube.beardedtek.com",
@ -1055,7 +1069,6 @@
"https://peertube.chatinbit.com",
"https://peertube.ffs2play.fr",
"https://peertube.swarm.solvingmaz.es",
"https://film.node9.org",
"https://peertube.mi-site.net",
"https://raptube.antipub.org",
"https://video.cm-en-transition.fr",
@ -1071,7 +1084,6 @@
"https://peertube.revelin.fr",
"https://peertube.ti-fr.com",
"https://video.turbo.chat",
"https://peertube.am-networks.fr",
"https://video.chbmeyer.de",
"https://video.rs-einrich.de",
"https://p2ptv.ru",
@ -1089,7 +1101,6 @@
"https://polskijutub.mkljczk.pl",
"https://peertube.noussommes.org",
"https://exode.me",
"https://megatube.lilomoino.fr",
"https://video.anartist.org",
"https://peertube.home.x0r.fr",
"https://peertube.marud.fr",
@ -1131,7 +1142,6 @@
"https://tube.childrenshealthdefense.eu",
"https://stream.litera.tools",
"https://peertube.kriom.net",
"https://peertube.grosist.fr",
"https://peertube.gemlog.ca",
"https://nettube.uc-netcorsoft.de",
"https://live.solari.com",
@ -1142,7 +1152,6 @@
"https://www.orion-hub.fr",
"https://tv.orion-serv.fr",
"https://video.interru.io",
"https://tube.cnr.it",
"https://peertube.dtmf.ca",
"https://tube.ponsonaille.fr",
"https://tube.int5.net",
@ -1160,12 +1169,9 @@
"https://video.antopie.org",
"https://vtr.chikichiki.tube",
"https://fedimovie.com",
"https://videos.thinkerview.com",
"https://tube.doctors4covidethics.org",
"https://yoba.tv",
"https://tube.mediainformationcenter.de",
"https://peertube.communecter.org",
"https://peertube.librosphere.fr",
"https://queermotion.org",
"https://video.audiovisuel-participatif.org",
"https://peertube.vip",
@ -1188,7 +1194,6 @@
"https://video.windfluechter.org",
"https://pocketnetpeertube10.nohost.me",
"https://tube.io18.top",
"https://peertube.remerge.net",
"https://tube.geekyboo.net",
"https://notretube.asselma.eu",
"https://canal.facil.services",
@ -1296,7 +1301,6 @@
"https://peertube.alpharius.io",
"https://ptb.lunarviews.net",
"https://ovaltube.codinglab.ch",
"https://video.wilkie.how",
"https://videos.ahp-numerique.fr",
"https://auf1.eu",
"https://tube.toontoet.nl",
@ -1389,7 +1393,6 @@
"https://video.lespoesiesdheloise.fr",
"https://peertube.luga.at",
"https://peertube.roflcopter.fr",
"https://ptube.rousset.nom.fr",
"https://peertube.swrs.net",
"https://tube.shanti.cafe",
"https://videos.cloudron.io",
@ -1426,7 +1429,6 @@
"https://videos.john-livingston.fr",
"https://melsungen.peertube-host.de",
"https://evangelisch.video",
"https://tube.anufrij.de",
"https://videos.mastodont.cat",
"https://media.undeadnetwork.de",
"https://tube.dragonpsi.xyz",
@ -1477,8 +1479,6 @@
"https://video.mycrowd.ca",
"https://kodcast.com",
"https://video.altertek.org",
"https://ruraletv.ovh",
"https://videos.weblib.re",
"https://tube.oisux.org",
"https://peertube.louisematic.site",
"https://clap.nerv-project.eu",
@ -1496,7 +1496,6 @@
"https://fotogramas.politicaconciencia.org",
"https://peertube.pl",
"https://peertube.manalejandro.com",
"https://www4.mir.inter21.net",
"https://video.csc49.fr",
"https://tube.wolfe.casa",
"https://video.dresden.network",
@ -1520,14 +1519,12 @@
"https://tube.nox-rhea.org",
"https://peertube.securitymadein.lu",
"https://tube.rita.moe",
"https://tuktube.com",
"https://mytube.kn-cloud.de",
"https://tube.nuagelibre.fr",
"https://video.nogafam.es",
"https://peertube.stream",
"https://videos.leslionsfloorball.fr",
"https://player.ojamajo.moe",
"https://ftsi.ru",
"https://video.cigliola.com",
"https://xxx.noho.st",
"https://peertube.stefofficiel.me",
@ -1621,7 +1618,6 @@
"https://peertube.debian.social",
"https://tube.piweb.be",
"https://peertube.su",
"https://video.hackers.town",
"https://tube.fdn.fr",
"https://peertube.demonix.fr",
"https://videos.hauspie.fr",
@ -1667,7 +1663,6 @@
"https://video.vny.fr",
"https://peervideo.club",
"https://tube.taker.fr",
"https://peertube.co.uk",
"https://video.fitchfamily.org",
"https://video.fdlibre.eu",
"https://peer.philoxweb.be",

View File

@ -1,5 +1,5 @@
{
"normal": ["https://facilmap.org"],
"clearnet": ["https://facilmap.org"],
"tor": [],
"i2p": [],
"loki": []

View File

@ -1,36 +1,57 @@
# Note: Run this script from the root of the repo
import traceback
import logging
import requests
import json
from urllib.parse import urlparse
from bs4 import BeautifulSoup
import re
from colorama import Fore, Back, Style
from urllib.parse import urlparse
from colorama import Fore, Style
import socket
import subprocess
mightyList = {}
config = {}
startRegex = "https?:\/{2}(?:[^\s\/]+\.)+"
startRegex = r"https?:\/{2}(?:[^\s\/]+\.)+"
endRegex = "(?:\/[^\s\/]+)*\/?"
torRegex = startRegex + "onion" + endRegex
i2pRegex = startRegex + "i2p" + endRegex
lokiRegex = startRegex + "loki" + endRegex
authRegex = "https?:\/{2}\S+:\S+@(?:[^\s\/]+\.)+[a-zA-Z0-9]+" + endRegex
authRegex = r"https?:\/{2}\S+:\S+@(?:[^\s\/]+\.)+[a-zA-Z0-9]+" + endRegex
with open('./src/config/config.json', 'rt') as tmp:
config['networks'] = json.load(tmp)['networks']
def filterLastSlash(urlList):
tmp = {}
for x in urlList:
tmp[x] = {}
for y in urlList[x]:
tmp[x][y] = []
for z in urlList[x][y]:
if z.endswith('/'):
tmp[x][y].append(z[:-1])
print(Fore.YELLOW + "Fixed " + Style.RESET_ALL + z)
for frontend in urlList:
tmp[frontend] = {}
for network in urlList[frontend]:
tmp[frontend][network] = []
for url in urlList[frontend][network]:
if url.endswith('/'):
tmp[frontend][network].append(url[:-1])
print(Fore.YELLOW + "Fixed " + Style.RESET_ALL + url)
else:
tmp[x][y].append(z)
tmp[frontend][network].append(url)
return tmp
def idnaEncode(urlList):
tmp = {}
for frontend in urlList:
tmp[frontend] = {}
for network in urlList[frontend]:
tmp[frontend][network] = []
for url in urlList[frontend][network]:
try:
encodedUrl = url.encode("idna").decode("utf8")
tmp[frontend][network].append(encodedUrl)
if (encodedUrl != url):
print(Fore.YELLOW + "Fixed " + Style.RESET_ALL + url)
except Exception:
tmp[frontend][network].append(url)
return tmp
@ -58,7 +79,7 @@ def is_cloudflare(url):
instance_ip = socket.gethostbyname(urlparse(url).hostname)
if instance_ip is None:
return False
except:
except Exception:
return False
instance_bin = ip2bin(instance_ip)
@ -85,10 +106,11 @@ def is_authenticate(url):
if 'www-authenticate' in r.headers:
print(url + ' requires ' + Fore.RED + 'authentication' + Style.RESET_ALL)
return True
except:
except Exception:
return False
return False
def is_offline(url):
try:
r = requests.get(url, timeout=5)
@ -99,298 +121,229 @@ def is_offline(url):
return True
else:
return False
except:
except Exception:
return False
def fetchCache(frontend, name):
with open('./src/instances/data.json') as file:
mightyList[frontend] = json.load(file)[frontend]
print(Fore.YELLOW + 'Failed' + Style.RESET_ALL + ' to fetch ' + name)
def fetchFromFile(frontend, name):
with open('./src/instances/' + frontend + '.json') as file:
mightyList[frontend] = json.load(file)
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + name)
def fetchJsonList(frontend, name, url, urlItem, jsonObject):
try:
r = requests.get(url)
rJson = json.loads(r.text)
if jsonObject:
rJson = rJson['instances']
_list = {}
for network in config['networks']:
_list[network] = []
if type(urlItem) == dict:
for item in rJson:
for network in config['networks']:
if urlItem[network] is not None:
if urlItem[network] in item and item[urlItem[network]] is not None:
if item[urlItem[network]].strip() != '':
_list[network].append(item[urlItem[network]])
else:
for item in rJson:
tmpItem = item
if urlItem is not None:
tmpItem = item[urlItem]
if tmpItem.strip() == '':
continue
elif re.search(torRegex, tmpItem):
_list['tor'].append(tmpItem)
elif re.search(i2pRegex, tmpItem):
_list['i2p'].append(tmpItem)
elif re.search(lokiRegex, tmpItem):
_list['loki'].append(tmpItem)
else:
_list['clearnet'].append(tmpItem)
mightyList[frontend] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + name)
except Exception:
fetchCache(frontend, name)
logging.error(traceback.format_exc())
def fetchRegexList(frontend, name, url, regex):
try:
r = requests.get(url)
_list = {}
for network in config['networks']:
_list[network] = []
tmp = re.findall(regex, r.text)
for item in tmp:
if item.strip() == "":
continue
elif re.search(torRegex, item):
_list['tor'].append(item)
elif re.search(i2pRegex, item):
_list['i2p'].append(item)
elif re.search(lokiRegex, item):
_list['loki'].append(item)
else:
_list['clearnet'].append(item)
mightyList[frontend] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + name)
except Exception:
fetchCache(frontend, name)
logging.error(traceback.format_exc())
def fetchTextList(frontend, name, url, prepend):
try:
r = requests.get(url)
tmp = r.text.strip().split('\n')
_list = {}
for network in config['networks']:
_list[network] = []
for item in tmp:
item = prepend + item
if re.search(torRegex, item):
_list['tor'].append(item)
elif re.search(i2pRegex, item):
_list['i2p'].append(item)
elif re.search(lokiRegex, item):
_list['loki'].append(item)
else:
_list['clearnet'].append(item)
mightyList[frontend] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + name)
except Exception:
fetchCache(frontend, name)
logging.error(traceback.format_exc())
def invidious():
r = requests.get('https://api.invidious.io/instances.json')
rJson = json.loads(r.text)
invidiousList = {}
invidiousList['normal'] = []
invidiousList['tor'] = []
invidiousList['i2p'] = []
invidiousList['loki'] = []
for instance in rJson:
if instance[1]['type'] == 'https':
invidiousList['normal'].append(instance[1]['uri'])
elif instance[1]['type'] == 'onion':
invidiousList['tor'].append(instance[1]['uri'])
mightyList['invidious'] = invidiousList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Invidious')
name = 'Invidious'
frontend = 'invidious'
url = 'https://api.invidious.io/instances.json'
try:
_list = {}
_list['clearnet'] = []
_list['tor'] = []
_list['i2p'] = []
_list['loki'] = []
r = requests.get(url)
rJson = json.loads(r.text)
for instance in rJson:
if instance[1]['type'] == 'https':
_list['clearnet'].append(instance[1]['uri'])
elif instance[1]['type'] == 'onion':
_list['tor'].append(instance[1]['uri'])
elif instance[1]['type'] == 'i2p':
_list['i2p'].append(instance[1]['uri'])
mightyList[frontend] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + name)
except Exception:
fetchCache(frontend, name)
logging.error(traceback.format_exc())
def piped():
r = requests.get(
'https://raw.githubusercontent.com/wiki/TeamPiped/Piped/Instances.md')
frontend = 'piped'
name = 'Piped'
try:
_list = {}
_list['clearnet'] = []
_list['tor'] = []
_list['i2p'] = []
_list['loki'] = []
r = requests.get(
'https://raw.githubusercontent.com/wiki/TeamPiped/Piped/Instances.md')
tmp = re.findall(
'(?:[^\s\/]+\.)+[a-zA-Z]+ (?:\(Official\) )?\| (https:\/{2}(?:[^\s\/]+\.)+[a-zA-Z]+) \| ', r.text)
_list = {}
_list['normal'] = []
_list['tor'] = []
_list['i2p'] = []
_list['loki'] = []
for item in tmp:
try:
url = requests.get(item, timeout=5).url
if url.strip("/") == item:
tmp = re.findall(
r'(?:[^\s\/]+\.)+[a-zA-Z]+ (?:\(Official\) )?\| (https:\/{2}(?:[^\s\/]+\.)+[a-zA-Z]+) \| ', r.text)
for item in tmp:
try:
url = requests.get(item, timeout=5).url
if url.strip("/") == item:
continue
else:
_list['clearnet'].append(url)
except Exception:
logging.error(traceback.format_exc())
continue
else:
_list['normal'].append(url)
except:
continue
mightyList['piped'] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Piped')
mightyList[frontend] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + name)
except Exception:
fetchCache(frontend, name)
logging.error(traceback.format_exc())
def pipedMaterial():
r = requests.get(
'https://raw.githubusercontent.com/mmjee/Piped-Material/master/README.md')
tmp = re.findall(
r"\| (https?:\/{2}(?:\S+\.)+[a-zA-Z0-9]*) +\|", r.text)
pipedMaterialList = {}
pipedMaterialList['normal'] = []
pipedMaterialList['tor'] = []
pipedMaterialList['i2p'] = []
pipedMaterialList['loki'] = []
for item in tmp:
pipedMaterialList['normal'].append(item)
mightyList['pipedMaterial'] = pipedMaterialList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'pipedMaterial')
fetchRegexList('pipedMaterial', 'Piped-Material', 'https://raw.githubusercontent.com/mmjee/Piped-Material/master/README.md', r"\| (https?:\/{2}(?:\S+\.)+[a-zA-Z0-9]*) +\| Production")
def cloudtube():
json_object = json.dumps(mightyList, ensure_ascii=False, indent=2)
with open('./src/instances/cloudtube.json') as file:
mightyList['cloudtube'] = json.load(file)
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'CloudTube')
fetchFromFile('cloudtube', 'Cloudtube')
def proxitok():
r = requests.get(
'https://raw.githubusercontent.com/wiki/pablouser1/ProxiTok/Public-instances.md')
tmp = re.findall(
r"\| \[.*\]\(([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)*\|*[A-Z]{0,}.*\|.*\|", r.text)
proxiTokList = {}
proxiTokList['normal'] = []
proxiTokList['tor'] = []
proxiTokList['i2p'] = []
proxiTokList['loki'] = []
for item in tmp:
proxiTokList['normal'].append(re.sub(r'/$', '', item))
mightyList['proxiTok'] = proxiTokList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'ProxiTok')
fetchRegexList('proxiTok', 'ProxiTok', 'https://raw.githubusercontent.com/wiki/pablouser1/ProxiTok/Public-instances.md', r"\| \[.*\]\(([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)(?: \(Official\))? +\|(?:(?: [A-Z]*.*\|.*\|)|(?:$))")
def send():
r = requests.get(
'https://gitlab.com/timvisee/send-instances/-/raw/master/README.md')
tmp = re.findall(
r"- ([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z0-9]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)*\|*[A-Z]{0,}", r.text)
sendList = {}
sendList['normal'] = []
sendList['tor'] = []
sendList['i2p'] = []
sendList['loki'] = []
for item in tmp:
sendList['normal'].append(item)
mightyList['send'] = sendList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Send')
fetchRegexList('send', 'Send', 'https://gitlab.com/timvisee/send-instances/-/raw/master/README.md', r"- ([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z0-9]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)*\|*[A-Z]{0,}")
def nitter():
r = requests.get('https://raw.githubusercontent.com/wiki/zedeus/nitter/Instances.md')
tmp = re.findall(
r"(?:(?:\| \[(?:\S+\.)+[a-zA-Z]+\]\((https?:\/{2}(?:\S+\.)+[a-zA-Z]+)\/?\) (?:\((?:\S+ ?\S*)\) )? *\| [^❌]{1,3} +\|(?:(?:\n)|(?: (?:❌)|(?: ✅)|(?: ❓)|(?: \[))))|(?:- \[(?:\S+\.)+(?:(?:i2p)|(?:loki))\]\((https?:\/{2}(?:\S+\.)(?:(?:i2p)|(?:loki)))\/?\)))", r.text)
nitterList = {}
nitterList['normal'] = []
nitterList['tor'] = []
nitterList['i2p'] = []
nitterList['loki'] = []
for item in tmp:
for i in item:
if i == '':
continue
else:
item = i
if re.search(torRegex, item):
nitterList['tor'].append(item)
elif re.search(i2pRegex, item):
nitterList['i2p'].append(item)
elif re.search(lokiRegex, item):
nitterList['loki'].append(item)
else:
nitterList['normal'].append(item)
mightyList['nitter'] = nitterList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Nitter')
fetchRegexList('nitter', 'Nitter', 'https://raw.githubusercontent.com/wiki/zedeus/nitter/Instances.md', r"(?:(?:\| )|(?:- ))\[(?:(?:\S+\.)+[a-zA-Z0-9]+)\/?\]\((https?:\/{2}(?:\S+\.)+[a-zA-Z0-9]+)\/?\)(?:(?: (?:\((?:\S+ ?\S*)\) )? *\| [^❌]{1,4} +\|(?:(?:\n)|(?: ❌)|(?: ✅)|(?: ❓)|(?: \[)))|(?:\n))")
def bibliogram():
json_object = json.dumps(mightyList, ensure_ascii=False, indent=2)
with open('./src/instances/bibliogram.json') as file:
mightyList['bibliogram'] = json.load(file)
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Bibliogram')
fetchFromFile('bibliogram', 'Bibliogram')
def libreddit():
r = requests.get(
'https://github.com/libbacon/libreddit-instances/raw/master/instances.json')
rJson = json.loads(r.text)
libredditList = {}
libredditList['normal'] = []
libredditList['tor'] = []
libredditList['i2p'] = []
libredditList['loki'] = []
if 'instances' not in rJson:
mightyList['libreddit'] = libredditList
print(Fore.RED + 'Failed to fetch ' + Style.RESET_ALL + 'LibReddit')
return
for item in rJson['instances']:
if 'url' in item:
url = item['url']
libredditList['normal'].append(url)
elif 'onion' in item:
onion = item['onion']
libredditList['tor'].append(onion)
elif 'i2p' in item:
i2p = item['i2p']
libredditList['i2p'].append(i2p)
mightyList['libreddit'] = libredditList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'LibReddit')
fetchJsonList('libreddit', 'Libreddit', 'https://github.com/libbacon/libreddit-instances/raw/master/instances.json', {'clearnet': 'url', 'tor': 'onion', 'i2p': 'i2p', 'loki': None}, True)
def teddit():
r = requests.get(
'https://codeberg.org/teddit/teddit/raw/branch/main/instances.json')
rJson = json.loads(r.text)
tedditList = {}
tedditList['normal'] = []
tedditList['tor'] = []
tedditList['i2p'] = []
tedditList['loki'] = []
for item in rJson:
url = item['url']
if url != '':
tedditList['normal'].append(url)
if 'onion' in item:
onion = item['onion']
if onion != '':
tedditList['tor'].append(onion)
mightyList['teddit'] = tedditList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Teddit')
fetchJsonList('teddit', 'Teddit', 'https://codeberg.org/teddit/teddit/raw/branch/main/instances.json', {'clearnet': 'url', 'tor': 'onion', 'i2p': 'i2p', 'loki': None}, False)
def wikiless():
r = requests.get('https://wikiless.org/instances.json')
rJson = json.loads(r.text)
wikilessList = {}
wikilessList['normal'] = []
wikilessList['tor'] = []
wikilessList['i2p'] = []
wikilessList['loki'] = []
for item in rJson:
if 'url' in item:
if item['url'].strip() != "":
wikilessList['normal'].append(item['url'])
if 'onion' in item:
if item['onion'].strip() != "":
wikilessList['tor'].append(item['onion'])
if 'i2p' in item:
if item['i2p'].strip() != "":
wikilessList['i2p'].append(item['i2p'])
mightyList['wikiless'] = wikilessList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Wikiless')
fetchJsonList('wikiless', 'Wikiless', 'https://wikiless.org/instances.json', {'clearnet': 'url', 'tor': 'onion', 'i2p': 'i2p', 'loki': None}, False)
def scribe():
r = requests.get(
'https://git.sr.ht/~edwardloveall/scribe/blob/main/docs/instances.json')
rJson = json.loads(r.text)
scribeList = {}
scribeList['normal'] = []
scribeList['tor'] = []
scribeList['i2p'] = []
scribeList['loki'] = []
for item in rJson:
scribeList['normal'].append(item)
mightyList['scribe'] = scribeList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Scribe')
fetchJsonList('scribe', 'Scribe', 'https://git.sr.ht/~edwardloveall/scribe/blob/main/docs/instances.json', None, False)
def quetre():
r = requests.get(
'https://raw.githubusercontent.com/zyachel/quetre/main/README.md')
_list = {}
_list['normal'] = []
_list['tor'] = []
_list['i2p'] = []
_list['loki'] = []
tmp = re.findall(
r"\| \[.*\]\(([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z0-9]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)*\|*[A-Z]{0,}.*\|.*\|", r.text)
for item in tmp:
if re.search(torRegex, item):
_list['tor'].append(item)
else:
_list['normal'].append(item)
mightyList['quetre'] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Quetre')
fetchRegexList('quetre', 'Quetre', 'https://raw.githubusercontent.com/zyachel/quetre/main/README.md', r"\| \[.*\]\(([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z0-9]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)*\|*[A-Z]{0,}.*\|.*\|")
def libremdb():
r = requests.get(
'https://raw.githubusercontent.com/zyachel/libremdb/main/README.md')
_list = {}
_list['normal'] = []
_list['tor'] = []
_list['i2p'] = []
_list['loki'] = []
fetchRegexList('libremdb', 'libremdb', 'https://raw.githubusercontent.com/zyachel/libremdb/main/README.md', r"\| \[.*\]\(([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z0-9]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)*\|*[A-Z]{0,}.*\|.*\|")
tmp = re.findall(
r"\| \[.*\]\(([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z0-9]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)*\|*[A-Z]{0,}.*\|.*\|", r.text)
for item in tmp:
if item.strip() == "":
continue
if re.search(torRegex, item):
_list['tor'].append(item)
else:
_list['normal'].append(item)
mightyList['libremdb'] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Libremdb')
def simpleertube():
r = requests.get('https://simple-web.org/instances/simpleertube')
_list = {}
_list['normal'] = []
_list['tor'] = []
_list['i2p'] = []
_list['loki'] = []
for item in r.text.strip().split('\n'):
_list['normal'].append('https://' + item)
mightyList['simpleertube'] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'SimpleerTube')
fetchTextList('simpleertube', 'SimpleerTube', 'https://simple-web.org/instances/simpleertube', 'https://')
def simplytranslate():
r = requests.get('https://simple-web.org/instances/simplytranslate')
simplyTranslateList = {}
simplyTranslateList['normal'] = []
simplyTranslateList['clearnet'] = []
for item in r.text.strip().split('\n'):
simplyTranslateList['normal'].append('https://' + item)
simplyTranslateList['clearnet'].append('https://' + item)
r = requests.get('https://simple-web.org/instances/simplytranslate_onion')
simplyTranslateList['tor'] = []
@ -412,31 +365,19 @@ def simplytranslate():
def linvgatranslate():
r = requests.get(
'https://raw.githubusercontent.com/TheDavidDelta/lingva-translate/main/instances.json')
rJson = json.loads(r.text)
lingvaList = {}
lingvaList['normal'] = []
lingvaList['tor'] = []
lingvaList['i2p'] = []
lingvaList['loki'] = []
for item in rJson:
lingvaList['normal'].append(item)
mightyList['lingva'] = lingvaList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'LinvgaTranslate')
fetchJsonList('lingva', 'LingvaTranslate', 'https://raw.githubusercontent.com/TheDavidDelta/lingva-translate/main/instances.json', None, False)
def searx_searxng():
r = requests.get('https://searx.space/data/instances.json')
rJson = json.loads(r.text)
searxList = {}
searxList['normal'] = []
searxList['clearnet'] = []
searxList['tor'] = []
searxList['i2p'] = []
searxList['loki'] = []
searxngList = {}
searxngList['normal'] = []
searxngList['clearnet'] = []
searxngList['tor'] = []
searxngList['i2p'] = []
searxngList['loki'] = []
@ -453,9 +394,9 @@ def searx_searxng():
searxList['i2p'].append(item[:-1])
else:
if (rJson['instances'][item].get('generator') == 'searxng'):
searxngList['normal'].append(item[:-1])
searxngList['clearnet'].append(item[:-1])
else:
searxList['normal'].append(item[:-1])
searxList['clearnet'].append(item[:-1])
mightyList['searx'] = searxList
mightyList['searxng'] = searxngList
@ -463,160 +404,66 @@ def searx_searxng():
def whoogle():
r = requests.get(
'https://raw.githubusercontent.com/benbusby/whoogle-search/main/misc/instances.txt')
tmpList = r.text.strip().split('\n')
whoogleList = {}
whoogleList['normal'] = []
whoogleList['tor'] = []
whoogleList['i2p'] = []
whoogleList['loki'] = []
for item in tmpList:
if re.search(torRegex, item):
whoogleList['tor'].append(item)
elif re.search(torRegex, item):
whoogleList['i2p'].append(item)
else:
whoogleList['normal'].append(item)
mightyList['whoogle'] = whoogleList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Whoogle')
fetchTextList('whoogle', 'Whoogle', 'https://raw.githubusercontent.com/benbusby/whoogle-search/main/misc/instances.txt', '')
def librex():
r = requests.get(
'https://raw.githubusercontent.com/hnhx/librex/main/README.md')
_list = {}
_list['normal'] = []
_list['tor'] = []
_list['i2p'] = []
_list['loki'] = []
tmp = re.findall(
r"\| {1,2}\[(?:(?:[a-zA-Z0-9]+\.)+[a-zA-Z]{2,}|✅)\]\((https?:\/{2}(?:[a-zA-Z0-9]+\.)+[a-zA-Z0-9]{2,})", r.text)
for item in tmp:
if item.strip() == "":
continue
elif re.search(torRegex, item):
_list['tor'].append(item)
elif re.search(i2pRegex, item):
_list['i2p'].append(item)
else:
_list['normal'].append(item)
mightyList['librex'] = _list
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Librex')
fetchJsonList('librex', 'LibreX', 'https://raw.githubusercontent.com/hnhx/librex/main/instances.json', {'clearnet': 'clearnet', 'tor': 'tor', 'i2p': 'i2p', 'loki': None}, True)
def rimgo():
r = requests.get(
'https://codeberg.org/video-prize-ranch/rimgo/raw/branch/main/instances.json')
rJson = json.loads(r.text)
rimgoList = {}
rimgoList['normal'] = []
rimgoList['tor'] = []
rimgoList['i2p'] = []
rimgoList['loki'] = []
for item in rJson:
if 'url' in item:
rimgoList['normal'].append(item['url'])
if 'onion' in item:
rimgoList['tor'].append(item['onion'])
if 'i2p' in item:
rimgoList['i2p'].append(item['i2p'])
mightyList['rimgo'] = rimgoList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Rimgo')
fetchJsonList('rimgo', 'rimgo', 'https://codeberg.org/video-prize-ranch/rimgo/raw/branch/main/instances.json', {'clearnet': 'url', 'tor': 'onion', 'i2p': 'i2p', 'loki': None}, False)
def librarian():
r = requests.get(
'https://codeberg.org/librarian/librarian/raw/branch/main/instances.json')
rJson = json.loads(r.text)
librarianList = {}
librarianList['normal'] = []
librarianList['tor'] = []
librarianList['i2p'] = []
librarianList['loki'] = []
instances = rJson['instances']
for item in instances:
url = item['url']
if url.strip() == "":
continue
elif re.search(torRegex, url):
librarianList['tor'].append(url)
elif re.search(i2pRegex, url):
librarianList['i2p'].append(url)
elif re.search(lokiRegex, url):
librarianList['loki'].append(url)
else:
librarianList['normal'].append(url)
mightyList['librarian'] = librarianList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Librarian')
fetchJsonList('librarian', 'Librarian', 'https://codeberg.org/librarian/librarian/raw/branch/main/instances.json', 'url', True)
def neuters():
json_object = json.dumps(mightyList, ensure_ascii=False, indent=2)
with open('./src/instances/neuters.json') as file:
mightyList['neuters'] = json.load(file)
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Neuters')
fetchFromFile('neuters', 'Neuters')
def beatbump():
json_object = json.dumps(mightyList, ensure_ascii=False, indent=2)
with open('./src/instances/beatbump.json') as file:
mightyList['beatbump'] = json.load(file)
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Beatbump')
fetchFromFile('beatbump', 'Beatbump')
def hyperpipe():
r = requests.get(
'https://codeberg.org/Hyperpipe/pages/raw/branch/main/api/frontend.json')
rJson = json.loads(r.text)
hyperpipeList = {}
hyperpipeList['normal'] = []
hyperpipeList['tor'] = []
hyperpipeList['i2p'] = []
hyperpipeList['loki'] = []
for item in rJson:
url = item['url']
if url.strip() == "":
continue
elif re.search(torRegex, url):
hyperpipeList['tor'].append(url)
elif re.search(i2pRegex, url):
hyperpipeList['i2p'].append(url)
elif re.search(lokiRegex, url):
hyperpipeList['loki'].append(url)
else:
hyperpipeList['normal'].append(url)
mightyList['hyperpipe'] = hyperpipeList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Hyperpipe')
fetchJsonList('hyperpipe', 'Hyperpipe', 'https://codeberg.org/Hyperpipe/pages/raw/branch/main/api/frontend.json', 'url', False)
def facil():
json_object = json.dumps(mightyList, ensure_ascii=False, indent=2)
with open('./src/instances/facil.json') as file:
mightyList['facil'] = json.load(file)
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'FacilMap')
fetchFromFile('facil', 'FacilMap')
def libreTranslate():
fetchRegexList('libreTranslate', 'LibreTranslate', 'https://raw.githubusercontent.com/LibreTranslate/LibreTranslate/main/README.md', r"\[(?:[^\s\/]+\.)+[a-zA-Z0-9]+\]\((https?:\/{2}(?:[^\s\/]+\.)+[a-zA-Z0-9]+)\/?\)\|")
def breezeWiki():
fetchRegexList('breezeWiki', 'BreezeWiki', 'https://gitdab.com/cadence/breezewiki-docs/raw/branch/main/docs.scrbl', r"\(\"[^\n\s\r\t\f\v\"]+\" \"https?:\/{2}(?:[^\s\/]+\.)+[a-zA-Z0-9]+(?:\/[^\s\/]+)*\" \"(https?:\/{2}(?:[^\s\/]+\.)+[a-zA-Z0-9]+(?:\/[^\s\/]+)*)\"\)")
def peertube():
r = requests.get(
'https://instances.joinpeertube.org/api/v1/instances?start=0&count=1045&sort=-createdAt')
rJson = json.loads(r.text)
try:
r = requests.get(
'https://instances.joinpeertube.org/api/v1/instances?start=0&count=1045&sort=-createdAt')
rJson = json.loads(r.text)
myList = []
for k in rJson['data']:
myList.append('https://'+k['host'])
myList = ['https://search.joinpeertube.org']
for k in rJson['data']:
myList.append('https://'+k['host'])
mightyList['peertube'] = myList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'PeerTube')
mightyList['peertube'] = myList
print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'PeerTube')
except Exception:
fetchCache('peertube', 'PeerTube')
def isValid(url): # This code is contributed by avanitrachhadiya2155
try:
result = urlparse(url)
return all([result.scheme, result.netloc])
except:
except Exception:
return False
@ -636,6 +483,7 @@ quetre()
libremdb()
simplytranslate()
linvgatranslate()
libreTranslate()
searx_searxng()
whoogle()
librex()
@ -646,7 +494,9 @@ beatbump()
hyperpipe()
facil()
simpleertube()
breezeWiki()
mightyList = filterLastSlash(mightyList)
mightyList = idnaEncode(mightyList)
cloudflare = []
authenticate = []

View File

@ -1,5 +1,5 @@
{
"normal": ["https://neuters.de"],
"clearnet": ["https://neuters.de"],
"tor": [],
"i2p": [],
"loki": []

View File

@ -1,7 +1,7 @@
{
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
"version": "2.2.1",
"version": "2.3.0",
"manifest_version": 2,
"browser_specific_settings": {
"gecko": {

View File

@ -2,80 +2,52 @@
import generalHelper from "../../assets/javascripts/general.js"
import utils from "../../assets/javascripts/utils.js"
import youtubeHelper from "../../assets/javascripts/youtube/youtube.js"
import youtubeMusicHelper from "../../assets/javascripts/youtubeMusic.js"
import twitterHelper from "../../assets/javascripts/twitter.js"
import instagramHelper from "../../assets/javascripts/instagram.js"
import redditHelper from "../../assets/javascripts/reddit.js"
import searchHelper from "../../assets/javascripts/search.js"
import translateHelper from "../../assets/javascripts/translate/translate.js"
import mapsHelper from "../../assets/javascripts/maps.js"
import wikipediaHelper from "../../assets/javascripts/wikipedia.js"
import mediumHelper from "../../assets/javascripts/medium.js"
import quoraHelper from "../../assets/javascripts/quora.js"
import libremdbHelper from "../../assets/javascripts/imdb.js"
import reutersHelper from "../../assets/javascripts/reuters.js"
import imgurHelper from "../../assets/javascripts/imgur.js"
import tiktokHelper from "../../assets/javascripts/tiktok.js"
import sendTargetsHelper from "../../assets/javascripts/sendTargets.js"
import peertubeHelper from "../../assets/javascripts/peertube.js"
import lbryHelper from "../../assets/javascripts/lbry.js"
import frontend from "../../assets/javascripts/frontend.js"
import servicesHelper from "../../assets/javascripts/services.js"
window.browser = window.browser || window.chrome
browser.runtime.onInstalled.addListener(details => {
function initDefaults() {
function initDefaults() {
browser.storage.local.clear(() => {
fetch("/instances/blacklist.json")
.then(response => response.text())
.then(async data => {
browser.storage.local.clear(() => {
browser.storage.local.set({ cloudflareBlackList: JSON.parse(data).cloudflare }, () => {
browser.storage.local.set({ authenticateBlackList: JSON.parse(data).authenticate }, () => {
browser.storage.local.set({ offlineBlackList: JSON.parse(data).offline }, () => {
generalHelper.initDefaults()
youtubeHelper.initDefaults()
youtubeMusicHelper.initDefaults()
twitterHelper.initDefaults()
instagramHelper.initDefaults()
mapsHelper.initDefaults()
searchHelper.initDefaults()
translateHelper.initDefaults()
mediumHelper.initDefaults()
quoraHelper.initDefaults()
libremdbHelper.initDefaults()
reutersHelper.initDefaults()
redditHelper.initDefaults()
wikipediaHelper.initDefaults()
imgurHelper.initDefaults()
tiktokHelper.initDefaults()
sendTargetsHelper.initDefaults()
peertubeHelper.initDefaults()
lbryHelper.initDefaults()
})
})
})
browser.storage.local.set({ blacklists: JSON.parse(data) }, async () => {
await generalHelper.initDefaults()
await servicesHelper.initDefaults()
})
})
}
if (details.reason == "install") initDefaults()
})
}
// if (details.reason == 'install' || (details.reason == "update" && details.previousVersion != browser.runtime.getManifest().version)) {
// if (details.reason == "update")
// browser.storage.local.get(null, r => {
// if (r.theme) {
// const old = encodeURIComponent(JSON.stringify(r))
// browser.tabs.create({ url: browser.runtime.getURL(`/pages/background/reset_warning.html?data=${old}`) });
// }
// initDefaults();
// })
// else initDefaults();
// }
browser.runtime.onInstalled.addListener(details => {
if (details.previousVersion != browser.runtime.getManifest().version) {
switch (details.reason) {
case "install":
initDefaults()
break
case "update":
fetch("/instances/blacklist.json")
.then(response => response.text())
.then(async data => {
browser.storage.local.set({ blacklists: JSON.parse(data) }, async () => {
switch (details.previousVersion) {
case "2.2.0":
case "2.2.1":
await generalHelper.initDefaults()
await servicesHelper.initDefaults()
await servicesHelper.upgradeOptions()
break
default:
await servicesHelper.processUpdate()
}
})
})
}
}
})
let BYPASSTABs = []
let tabIdRedirects = {}
// true == Always redirect, false == Never redirect, null/undefined == follow options for services
browser.webRequest.onBeforeRequest.addListener(
details => {
const url = new URL(details.url)
@ -88,29 +60,12 @@ browser.webRequest.onBeforeRequest.addListener(
return null
}
let newUrl = youtubeMusicHelper.redirect(url, details.type)
if (!newUrl) newUrl = youtubeHelper.redirect(url, details.type, details.tabId, initiator)
if (!newUrl) newUrl = twitterHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = instagramHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = mapsHelper.redirect(url, initiator)
if (!newUrl) newUrl = redditHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = mediumHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = quoraHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = libremdbHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = reutersHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = imgurHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = tiktokHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = sendTargetsHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = peertubeHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = lbryHelper.redirect(url, details.type, initiator)
if (!newUrl) newUrl = translateHelper.redirect(url)
if (!newUrl) newUrl = searchHelper.redirect(url)
if (!newUrl) newUrl = wikipediaHelper.redirect(url)
if (tabIdRedirects[details.tabId] == false) return null
let newUrl = servicesHelper.redirect(url, details.type, initiator, tabIdRedirects[details.tabId])
if (details.frameAncestors && details.frameAncestors.length > 0 && generalHelper.isException(new URL(details.frameAncestors[0].url))) newUrl = null
if (generalHelper.isException(url)) newUrl = "BYPASSTAB"
if (BYPASSTABs.includes(details.tabId)) newUrl = null
if (newUrl) {
if (newUrl === "CANCEL") {
@ -119,7 +74,7 @@ browser.webRequest.onBeforeRequest.addListener(
}
if (newUrl === "BYPASSTAB") {
console.log(`Bypassed ${details.tabId} ${url}`)
if (!BYPASSTABs.includes(details.tabId)) BYPASSTABs.push(details.tabId)
if (tabIdRedirects[details.tabId] != false) tabIdRedirects[details.tabId] = false
return null
}
console.info("Redirecting", url.href, "=>", newUrl)
@ -132,39 +87,14 @@ browser.webRequest.onBeforeRequest.addListener(
)
browser.tabs.onRemoved.addListener(tabId => {
const i = BYPASSTABs.indexOf(tabId)
if (i > -1) {
BYPASSTABs.splice(i, 1)
console.log("Removed BYPASSTABs", tabId)
if (tabIdRedirects[tabId] != undefined) {
delete tabIdRedirects[tabId]
console.log("Removed tab " + tabId + " from tabIdRedirects")
}
})
browser.webRequest.onHeadersReceived.addListener(
e => {
let response = youtubeHelper.removeXFrameOptions(e)
if (!response) response = twitterHelper.removeXFrameOptions(e)
return response
},
{ urls: ["<all_urls>"] },
["blocking", "responseHeaders"]
)
async function redirectOfflineInstance(url, tabId) {
let newUrl = await youtubeHelper.switchInstance(url, true)
if (!newUrl) newUrl = await twitterHelper.switchInstance(url, true)
if (!newUrl) newUrl = await instagramHelper.switchInstance(url, true)
if (!newUrl) newUrl = await redditHelper.switchInstance(url, true)
if (!newUrl) newUrl = await searchHelper.switchInstance(url, true)
if (!newUrl) newUrl = await translateHelper.switchInstance(url, true)
if (!newUrl) newUrl = await mediumHelper.switchInstance(url, true)
if (!newUrl) newUrl = await quoraHelper.switchInstance(url, true)
if (!newUrl) newUrl = await libremdbHelper.switchInstance(url, true)
if (!newUrl) newUrl = await tiktokHelper.switchInstance(url, true)
if (!newUrl) newUrl = await imgurHelper.switchInstance(url, true)
if (!newUrl) newUrl = await wikipediaHelper.switchInstance(url, true)
if (!newUrl) newUrl = await peertubeHelper.switchInstance(url, true)
if (!newUrl) newUrl = await lbryHelper.switchInstance(url, true)
if (!newUrl) newUrl = await youtubeMusicHelper.switchInstance(url, true)
let newUrl = await servicesHelper.switchInstance(url, true)
if (newUrl) {
if (counter >= 5) {
@ -181,7 +111,7 @@ async function redirectOfflineInstance(url, tabId) {
let counter = 0
function isAutoRedirect() {
return new Promise(resolve => browser.storage.local.get("autoRedirect", r => resolve(r.autoRedirect == true)))
return new Promise(resolve => browser.storage.local.get("options", r => resolve(r.options.autoRedirect == true)))
}
browser.webRequest.onResponseStarted.addListener(
@ -230,16 +160,88 @@ browser.contextMenus.create({
contexts: ["browser_action"],
})
browser.contextMenus.onClicked.addListener(info => {
if (info.menuItemId == "switchInstance") utils.switchInstance()
else if (info.menuItemId == "settings") browser.runtime.openOptionsPage()
else if (info.menuItemId == "copyRaw") utils.copyRaw()
else if (info.menuItemId == "unify") utils.unify()
browser.contextMenus.create({
id: "toggleTab",
title: browser.i18n.getMessage("toggleTab"),
contexts: ["page", "tab"],
})
browser.contextMenus.create({
id: "redirectLink",
title: browser.i18n.getMessage("redirectLink"),
contexts: ["link"],
})
function handleToggleTab(tab) {
return new Promise(async resolve => {
switch (tabIdRedirects[tab.id]) {
case false:
const newUrl = await servicesHelper.reverse(tab.url, true)
if (newUrl) browser.tabs.update(tab.id, { url: newUrl })
resolve()
return
case true:
browser.tabs.reload(tab.id)
resolve()
return
}
})
}
browser.contextMenus.onClicked.addListener((info, tab) => {
return new Promise(async resolve => {
switch (info.menuItemId) {
case "switchInstance":
utils.switchInstance()
resolve()
return
case "settings":
browser.runtime.openOptionsPage()
resolve()
return
case "copyRaw":
utils.copyRaw()
resolve()
return
case "unify":
utils.unify()
resolve()
return
case "toggleTab":
if (tabIdRedirects[tab.id] != undefined) {
tabIdRedirects[tab.id] = !tabIdRedirects[tab.id]
await handleToggleTab(tab)
resolve()
return
} else {
const url = new URL(tab.url)
const service = await servicesHelper.computeService(url)
if (service) {
browser.storage.local.get("options", async r => {
if (r.options[service].enabled) tabIdRedirects[tab.id] = false
else tabIdRedirects[tab.id] = true
await handleToggleTab(tab)
resolve()
return
})
} else {
tabIdRedirects[tab.id] = false
await handleToggleTab(tab)
resolve()
return
}
}
case "redirectLink":
const tmpUrl = new URL(info.linkUrl)
const newUrl = servicesHelper.redirect(tmpUrl, "main_frame", null, true)
if (newUrl) browser.tabs.create({ url: newUrl })
resolve()
return
}
})
})
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.function === "unify") utils.unify(false).then(r => sendResponse({ response: r }))
return true
})
browser.storage.local.set({ version: browser.runtime.getManifest().version })

View File

@ -1,59 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title data-localise="__MSG_instanceIsOff__">Reset Warning</title>
<link href="../stylesheets/styles.css" rel="stylesheet" />
<style>
body {
margin: 0;
padding: 0;
height: 100vh;
width: 100vw;
flex-wrap: wrap;
justify-content: center;
align-items: center;
font-size: 30px;
display: flex;
}
div {
width: 80%;
}
div.logo {
display: flex;
}
img {
width: 90px;
height: auto;
}
</style>
</head>
<body>
<div>
<div class="logo">
<img src="/assets/images/libredirect.svg" alt="LibRedirect icon" />
<h1>LibRedirect</h1>
</div>
<p data-localise="__MSG_instanceOffline__">All settings have been reset as they're incompatible with the previous version.</p>
<p>Sorry for the inconvenience, but we're going in a fast development process and can't support nor convert older settings. It will reach a stable plateau though.</p>
<a id="export-settings" class="button button-inline">
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path
d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
></path>
</svg>
&nbsp;
<x data-localise="__MSG_exportSettings__">Export Settings</x>
</a>
</div>
</body>
<script src="reset_warning.js"></script>
</html>

View File

@ -1,7 +0,0 @@
let params = new URLSearchParams(location.search)
const resultString = JSON.stringify(JSON.parse(params.get("data")), null, " ")
let exportSettingsElement = document.getElementById("export-settings")
exportSettingsElement.href = "data:application/json;base64," + btoa(resultString)
exportSettingsElement.download = "libredirect-settings.json"

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html id="elementToShowWithJavaScript" lang="en">
<%- include('src/pages/widgets/head') -%>
<body class="option" dir="auto">
<%- include('src/pages/widgets/links', {services: services}) -%>
<div id="pages">
<%- include('src/pages/options/widgets/general', {config: {networks, services}}) -%>
<%- include('src/pages/options/widgets/services', {config: {networks, services}}) -%>
<%- include('src/pages/options/widgets/about') -%>
</div>
</body>
<script type="module" src="./index.js"></script>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +0,0 @@
doctype html
html#elementToShowWithJavaScript(lang="en")
head
meta(charset='utf-8')
meta(name="viewport" content="width=device-width, initial-scale=1")
link(rel="icon" type="image/x-icon" href="../../../assets/images/libredirect.svg")
link(href="../stylesheets/styles.css" rel="stylesheet")
title General
script(type="module" src="./init.js")
body.option(dir="auto")
include ../widgets/links.pug
+links('general')
div#pages
include ./widgets/general.pug
include ./widgets/youtube.pug
include ./widgets/youtubeMusic.pug
include ./widgets/twitter.pug
include ./widgets/instagram.pug
include ./widgets/tiktok.pug
include ./widgets/reddit.pug
include ./widgets/imgur.pug
include ./widgets/wikipedia.pug
include ./widgets/medium.pug
include ./widgets/quora.pug
include ./widgets/imdb.pug
include ./widgets/reuters.pug
include ./widgets/peertube.pug
include ./widgets/lbry.pug
include ./widgets/search.pug
include ./widgets/translate.pug
include ./widgets/maps.pug
include ./widgets/sendTargets.pug
include ./widgets/about.pug
script(type="module" src="./index.js")

View File

@ -4,8 +4,8 @@ import localise from "../../assets/javascripts/localise.js"
function changeTheme() {
return new Promise(resolve => {
browser.storage.local.get("theme", r => {
switch (r.theme) {
browser.storage.local.get("options", r => {
switch (r.options.theme) {
case "dark":
document.body.classList.add("dark-theme")
document.body.classList.remove("light-theme")

View File

@ -0,0 +1,24 @@
<section class="option-block" id="about_page">
<div class="some-block option-block">
<h1 data-localise="__MSG_about__">About</h1>
</div>
<hr>
<div class="about">
<div class="some-block option-block">
<h4>Donate: ♥️</h4>
<h4><a href='https://libredirect.codeberg.page/donate'>https://libredirect.codeberg.page/donate</a> </h4>
</div>
<div class="some-block option-block">
<h4>FAQ:</h4>
<h4><a href='https://libredirect.codeberg.page/faq'>https://libredirect.codeberg.page/faq</a></h4>
</div>
<div class="some-block option-block">
<h4>Docs:</h4>
<h4><a href='https://libredirect.codeberg.page/docs'>https://libredirect.codeberg.page/docs</a></h4>
</div>
<div class="some-block option-block">
<h4>Source Code:</h4>
<h4><a href='https://libredirect.codeberg.page/source_code'>https://libredirect.codeberg.page/source_code</a></h4>
</div>
</div>
</section>

View File

@ -1,17 +0,0 @@
section#about_page.option-block
.some-block.option-block
h1(data-localise="__MSG_about__") About
hr
.about
.some-block.option-block
h4 Donate: ♥️
h4 <a href='https://libredirect.github.io/donate'>https://libredirect.github.io/donate</a>
.some-block.option-block
h4 FAQ:
h4 <a href='https://libredirect.github.io/faq'>https://libredirect.github.io/faq</a>
.some-block.option-block
h4 Docs:
h4 <a href='https://libredirect.github.io/docs'>https://libredirect.github.io/docs</a>
.some-block.option-block
h4 Source Code:
h4 <a href='https://libredirect.github.io/source_code'>https://libredirect.github.io/source_code</a>

View File

@ -0,0 +1,102 @@
<section class="option-block" id="general_page">
<div class="some-block option-block">
<h1 data-localise="__MSG_general__">General</h1>
</div>
<hr>
<div class="some-block option-block">
<h4 data-localise="__MSG_theme__">Theme</h4>
<select id="theme">
<option value="detect" data-localise="__MSG_detect__">Detect</option>
<option value="light" data-localise="__MSG_light__">Light</option>
<option value="dark" data-localise="__MSG_dark__">Dark</option>
</select>
</div>
<div class="some-block option-block">
<h4 data-localise="__MSG_network__">Network</h4>
<select id="network">
<% for (const network in config.networks) { -%>
<option value="<%= network %>"><%= config.networks[network].name %></option>
<% }; %>
</select>
</div>
<div id="network-fallback">
<div class="some-block option-block">
<h4 data-localise="__MSG_networkFallback__">Fallback to clearnet if no instances are available for the current network</h4>
<input id="network-fallback-checkbox" type="checkbox">
</div>
</div>
<div class="some-block option-block">
<h4 data-localise="__MSG_autoRedirect__"></h4>
<input id="auto-redirect" type="checkbox">
</div>
<form>
<div class="some-block option-block">
<h4 data-localise="__MSG_latencyThreshold">Latency Threshold</h4>
<output id="latency-output" for="latencyInput" name="latencyOutput"></output>
<input id="latency-input" type="range" min="50" max="5000" value="1000" name="latencyInput" step="50">
</div>
</form>
<div class="some-block option-block">
<h4 data-localise="__MSG_exceptions__"></h4>
</div>
<form id="custom-exceptions-instance-form">
<div class="some-block option-block">
<div class="some-block" style="padding:0;">
<input id="exceptions-custom-instance" placeholder="https://www.google.com" type="url">&nbsp;
<select id="exceptions-custom-instance-type">
<option value="url">URL</option>
<option value="regex">Regex</option>
</select>&nbsp;
</div>
<button class="add" id="exceptions-add-instance" type="submit">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path>
</svg>
</button>
</div>
</form>
<div class="checklist" id="exceptions-custom-checklist"></div>
<div class="buttons buttons-inline"><a class="button button-inline" id="update-instances">
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path>
</svg>
<x data-localise="__MSG_updateInstances__">Update Instances</x></a>&nbsp; &nbsp;</div>
<div class="buttons buttons-inline">
<label class="button button-inline" id="import_settings_text" for="import-settings">
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"></path>
</svg>&nbsp;
<x data-localise="__MSG_importSettings__">Import Settings</x>
</label>
<input class="button button-inline" id="import-settings" type="file" style="display:none;">&nbsp; &nbsp;<a class="button button-inline" id="export-settings">
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"></path>
</svg>&nbsp;
<x data-localise="__MSG_exportSettings__">Export Settings</x></a>&nbsp; &nbsp;<a class="button button-inline" id="reset-settings">
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path d="M12,5V2L8,6l4,4V7c3.31,0,6,2.69,6,6c0,2.97-2.17,5.43-5,5.91v2.02c3.95-0.49,7-3.85,7-7.93C20,8.58,16.42,5,12,5z"></path>
<path d="M6,13c0-1.65,0.67-3.15,1.76-4.24L6.34,7.34C4.9,8.79,4,10.79,4,13c0,4.08,3.05,7.44,7,7.93v-2.02 C8.17,18.43,6,15.97,6,13z"></path>
</svg>
<x data-localise="__MSG_resetSettings__">Reset Settings</x></a>
</div>
<hr>
<div class="some-block option-block">
<h4 data-localise="__MSG_customPopup__">Customize Popup</h4>
</div>
<div class="checklist-popup" id="popup-frontends-checklist">
<% for (const service in config.services) { -%>
<div>
<div>
<% if (config.services[service].imageType != "svgMono") { _%>
<img src="../../../assets/images/<%= service %>-icon.<%= config.services[service].imageType %>">
<% } else { _%>
<%- include ('src/assets/images/' + service + '-icon.svg') %>
<% } _%>
<label data-localise="__MSG_<%= service %>__" for="<%= service %>"><%= config.services[service].name %></label>
</div>
<input id="<%= service %>" type="checkbox">
</div>
<% }; %>
</div>
<script type="module" src="./widgets/general.js"></script>
</section>

View File

@ -3,25 +3,7 @@ window.browser = window.browser || window.chrome
import utils from "../../../assets/javascripts/utils.js"
import generalHelper from "../../../assets/javascripts/general.js"
import youtubeHelper from "../../../assets/javascripts/youtube/youtube.js"
import youtubeMusicHelper from "../../../assets/javascripts/youtubeMusic.js"
import twitterHelper from "../../../assets/javascripts/twitter.js"
import instagramHelper from "../../../assets/javascripts/instagram.js"
import redditHelper from "../../../assets/javascripts/reddit.js"
import searchHelper from "../../../assets/javascripts/search.js"
import translateHelper from "../../../assets/javascripts/translate/translate.js"
import mapsHelper from "../../../assets/javascripts/maps.js"
import wikipediaHelper from "../../../assets/javascripts/wikipedia.js"
import mediumHelper from "../../../assets/javascripts/medium.js"
import quoraHelper from "../../../assets/javascripts/quora.js"
import libremdbHelper from "../../../assets/javascripts/imdb.js"
import reutersHelper from "../../../assets/javascripts/reuters.js"
import imgurHelper from "../../../assets/javascripts/imgur.js"
import tiktokHelper from "../../../assets/javascripts/tiktok.js"
import sendTargetsHelper from "../../../assets/javascripts/sendTargets.js"
import peertubeHelper from "../../../assets/javascripts/peertube.js"
import lbryHelper from "../../../assets/javascripts/lbry.js"
import servicesHelper from "../../../assets/javascripts/services.js"
let updateInstancesElement = document.getElementById("update-instances")
updateInstancesElement.addEventListener("click", async () => {
@ -33,12 +15,46 @@ updateInstancesElement.addEventListener("click", async () => {
} else updateInstancesElement.innerHTML = "Failed Miserabely"
})
let config
async function getConfig() {
return new Promise(resolve => {
fetch("/config/config.json")
.then(response => response.text())
.then(data => {
config = JSON.parse(data)
resolve()
})
})
}
function setOption(option, type, event) {
browser.storage.local.get("options", r => {
let options = r.options
browser.storage.local.set({ options })
})
browser.storage.local.get("options", r => {
let options = r.options
if (type == "select") {
options[option] = event.target.options[event.target.options.selectedIndex].value
} else if (type == "checkbox") {
options[option] = event.target.checked
} else if (type == "range") {
options[option] = event.target.value
}
browser.storage.local.set({ options })
})
}
let exportSettingsElement = document.getElementById("export-settings")
function exportSettings() {
return browser.storage.local.get(null, result => {
let resultString = JSON.stringify(result, null, " ")
exportSettingsElement.href = "data:application/json;base64," + btoa(encodeURI(resultString))
browser.storage.local.get("options", result => {
result.options.version = browser.runtime.getManifest().version
let resultString = JSON.stringify(result.options, null, " ")
exportSettingsElement.href = "data:application/json;base64," + btoa(resultString)
exportSettingsElement.download = "libredirect-settings.json"
return
})
@ -57,7 +73,22 @@ importSettingsElement.addEventListener("change", () => {
reader.onload = async () => {
const data = JSON.parse(reader.result)
if ("theme" in data && "disableImgur" in data && "imgurRedirects" in data) {
browser.storage.local.clear(() => browser.storage.local.set({ ...data }, () => location.reload()))
browser.storage.local.clear(() =>
browser.storage.local.set({ ...data }, () => {
fetch("/instances/blacklist.json")
.then(response => response.text())
.then(async data => {
browser.storage.local.set({ blacklists: JSON.parse(data) }, async () => {
await generalHelper.initDefaults()
await servicesHelper.initDefaults()
await servicesHelper.upgradeOptions()
location.reload()
})
})
})
)
} else if ("version" in data) {
browser.storage.local.clear(() => browser.storage.local.set({ options: data }, () => location.reload()))
} else {
console.log("incompatible settings")
importError()
@ -81,31 +112,10 @@ resetSettings.addEventListener("click", async () => {
fetch("/instances/blacklist.json")
.then(response => response.text())
.then(async data => {
browser.storage.local.set({ cloudflareBlackList: JSON.parse(data).cloudflare }, () => {
browser.storage.local.set({ offlineBlackList: JSON.parse(data).offline }, () => {
browser.storage.local.set({ authenticateBlackList: JSON.parse(data).authenticate }, async () => {
await generalHelper.initDefaults()
await youtubeHelper.initDefaults()
await youtubeMusicHelper.initDefaults()
await twitterHelper.initDefaults()
await instagramHelper.initDefaults()
await mapsHelper.initDefaults()
await searchHelper.initDefaults()
await translateHelper.initDefaults()
await mediumHelper.initDefaults()
await quoraHelper.initDefaults()
await libremdbHelper.initDefaults()
await reutersHelper.initDefaults()
await redditHelper.initDefaults()
await wikipediaHelper.initDefaults()
await imgurHelper.initDefaults()
await tiktokHelper.initDefaults()
await sendTargetsHelper.initDefaults()
await peertubeHelper.initDefaults()
await lbryHelper.initDefaults()
location.reload()
})
})
browser.storage.local.set({ blacklists: JSON.parse(data) }, async () => {
await generalHelper.initDefaults()
await servicesHelper.initDefaults()
location.reload()
})
})
})
@ -113,32 +123,30 @@ resetSettings.addEventListener("click", async () => {
let autoRedirectElement = document.getElementById("auto-redirect")
autoRedirectElement.addEventListener("change", event => {
browser.storage.local.set({ autoRedirect: event.target.checked })
setOption("autoRedirect", "checkbox", event)
})
let themeElement = document.getElementById("theme")
themeElement.addEventListener("change", event => {
const value = event.target.options[theme.selectedIndex].value
browser.storage.local.set({ theme: value })
setOption("theme", "select", event)
location.reload()
})
let protocolElement = document.getElementById("protocol")
protocolElement.addEventListener("change", event => {
const value = event.target.options[protocol.selectedIndex].value
browser.storage.local.set({ protocol: value })
let networkElement = document.getElementById("network")
networkElement.addEventListener("change", event => {
setOption("network", "select", event)
location.reload()
})
let protocolFallbackCheckbox = document.getElementById("protocol-fallback-checkbox")
protocolFallbackCheckbox.addEventListener("change", event => {
browser.storage.local.set({ protocolFallback: event.target.checked })
let networkFallbackCheckbox = document.getElementById("network-fallback-checkbox")
networkFallbackCheckbox.addEventListener("change", event => {
setOption("networkFallback", "checkbox", event)
})
let latencyOutput = document.getElementById("latency-output")
let latencyInput = document.getElementById("latency-input")
latencyInput.addEventListener("change", event => {
browser.storage.local.set({ latencyThreshold: event.target.value })
setOption("latencyThreshold", "range", event)
})
latencyInput.addEventListener("input", event => {
latencyOutput.value = event.target.value
@ -148,60 +156,55 @@ let nameCustomInstanceInput = document.getElementById("exceptions-custom-instanc
let instanceTypeElement = document.getElementById("exceptions-custom-instance-type")
let instanceType = "url"
let popupFrontends
for (const frontend of generalHelper.allPopupFrontends)
document.getElementById(frontend).addEventListener("change", event => {
if (event.target.checked && !popupFrontends.includes(frontend)) popupFrontends.push(frontend)
else if (popupFrontends.includes(frontend)) {
var index = popupFrontends.indexOf(frontend)
if (index !== -1) popupFrontends.splice(index, 1)
}
browser.storage.local.set({ popupFrontends })
})
await getConfig()
for (const service in config.services) {
document.getElementById(service).addEventListener("change", event => {
browser.storage.local.get("options", r => {
let options = r.options
if (event.target.checked && !options.popupServices.includes(service)) options.popupServices.push(service)
else if (options.popupServices.includes(service)) {
var index = options.popupServices.indexOf(service)
if (index !== -1) options.popupServices.splice(index, 1)
}
browser.storage.local.set({ options })
})
})
}
// const firstPartyIsolate = document.getElementById('firstPartyIsolate');
// firstPartyIsolate.addEventListener("change", () => browser.storage.local.set({ firstPartyIsolate: firstPartyIsolate.checked }))
browser.storage.local.get(
[
"theme",
"autoRedirect",
"exceptions",
"protocol",
"protocolFallback",
"latencyThreshold",
// 'firstPartyIsolate'
],
r => {
autoRedirectElement.checked = r.autoRedirect
themeElement.value = r.theme
protocolElement.value = r.protocol
protocolFallbackCheckbox.checked = r.protocolFallback
latencyOutput.value = r.latencyThreshold
// firstPartyIsolate.checked = r.firstPartyIsolate;
browser.storage.local.get("options", r => {
autoRedirectElement.checked = r.options.autoRedirect
themeElement.value = r.options.theme
networkElement.value = r.options.network
networkFallbackCheckbox.checked = r.options.networkFallback
latencyOutput.value = r.options.latencyThreshold
let options = r.options
// firstPartyIsolate.checked = r.firstPartyIsolate;
let protocolFallbackElement = document.getElementById("protocol-fallback")
if (protocolElement.value == "normal") {
protocolFallbackElement.style.display = "none"
} else {
protocolFallbackElement.style.display = "block"
//let networkFallbackElement = document.getElementById("network-fallback")
if (networkElement.value == "clearnet") {
networkFallbackCheckbox.disabled = true
} else {
networkFallbackCheckbox.disabled = false
}
instanceTypeElement.addEventListener("change", event => {
instanceType = event.target.options[instanceTypeElement.selectedIndex].value
if (instanceType == "url") {
nameCustomInstanceInput.setAttribute("type", "url")
nameCustomInstanceInput.setAttribute("placeholder", "https://www.google.com")
} else if (instanceType == "regex") {
nameCustomInstanceInput.setAttribute("type", "text")
nameCustomInstanceInput.setAttribute("placeholder", "https?://(www.|)youtube.com/")
}
instanceTypeElement.addEventListener("change", event => {
instanceType = event.target.options[instanceTypeElement.selectedIndex].value
if (instanceType == "url") {
nameCustomInstanceInput.setAttribute("type", "url")
nameCustomInstanceInput.setAttribute("placeholder", "https://www.google.com")
} else if (instanceType == "regex") {
nameCustomInstanceInput.setAttribute("type", "text")
nameCustomInstanceInput.setAttribute("placeholder", "https?://(www.|)youtube.com/")
}
})
let exceptionsCustomInstances = r.exceptions
function calcExceptionsCustomInstances() {
document.getElementById("exceptions-custom-checklist").innerHTML = [...exceptionsCustomInstances.url, ...exceptionsCustomInstances.regex]
.map(
x => `<div>
})
let exceptionsCustomInstances = r.options.exceptions
function calcExceptionsCustomInstances() {
document.getElementById("exceptions-custom-checklist").innerHTML = [...exceptionsCustomInstances.url, ...exceptionsCustomInstances.regex]
.map(
x => `<div>
${x}
<button class="add" id="clear-${x}">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px"
@ -211,49 +214,47 @@ browser.storage.local.get(
</button>
</div>
<hr>`
)
.join("\n")
)
.join("\n")
for (const x of [...exceptionsCustomInstances.url, ...exceptionsCustomInstances.regex]) {
document.getElementById(`clear-${x}`).addEventListener("click", () => {
console.log(x)
let index
index = exceptionsCustomInstances.url.indexOf(x)
if (index > -1) exceptionsCustomInstances.url.splice(index, 1)
else {
index = exceptionsCustomInstances.regex.indexOf(x)
if (index > -1) exceptionsCustomInstances.regex.splice(index, 1)
}
browser.storage.local.set({ exceptions: exceptionsCustomInstances })
calcExceptionsCustomInstances()
})
for (const x of [...exceptionsCustomInstances.url, ...exceptionsCustomInstances.regex]) {
document.getElementById(`clear-${x}`).addEventListener("click", () => {
console.log(x)
let index
index = exceptionsCustomInstances.url.indexOf(x)
if (index > -1) exceptionsCustomInstances.url.splice(index, 1)
else {
index = exceptionsCustomInstances.regex.indexOf(x)
if (index > -1) exceptionsCustomInstances.regex.splice(index, 1)
}
options.exceptions = exceptionsCustomInstances
browser.storage.local.set({ options })
calcExceptionsCustomInstances()
})
}
}
calcExceptionsCustomInstances()
document.getElementById("custom-exceptions-instance-form").addEventListener("submit", event => {
event.preventDefault()
let val
if (instanceType == "url") {
if (nameCustomInstanceInput.validity.valid) {
let url = new URL(nameCustomInstanceInput.value)
val = `${url.network}//${url.host}`
if (!exceptionsCustomInstances.url.includes(val)) exceptionsCustomInstances.url.push(val)
}
} else if (instanceType == "regex") {
val = nameCustomInstanceInput.value
if (val.trim() != "" && !exceptionsCustomInstances.regex.includes(val)) exceptionsCustomInstances.regex.push(val)
}
if (val) {
options.exceptions = exceptionsCustomInstances
browser.storage.local.set({ options })
nameCustomInstanceInput.value = ""
}
calcExceptionsCustomInstances()
document.getElementById("custom-exceptions-instance-form").addEventListener("submit", event => {
event.preventDefault()
})
let val
if (instanceType == "url") {
if (nameCustomInstanceInput.validity.valid) {
let url = new URL(nameCustomInstanceInput.value)
val = `${url.protocol}//${url.host}`
if (!exceptionsCustomInstances.url.includes(val)) exceptionsCustomInstances.url.push(val)
}
} else if (instanceType == "regex") {
val = nameCustomInstanceInput.value
if (val.trim() != "" && !exceptionsCustomInstances.regex.includes(val)) exceptionsCustomInstances.regex.push(val)
}
if (val) {
browser.storage.local.set({ exceptions: exceptionsCustomInstances })
nameCustomInstanceInput.value = ""
}
calcExceptionsCustomInstances()
})
browser.storage.local.get("popupFrontends", r => {
popupFrontends = r.popupFrontends
for (const frontend of generalHelper.allPopupFrontends) document.getElementById(frontend).checked = popupFrontends.includes(frontend)
})
}
)
for (const service in config.services) document.getElementById(service).checked = options.popupServices.includes(service)
})

View File

@ -1,210 +0,0 @@
section#general_page.option-block
.some-block.option-block
h1(data-localise="__MSG_general__") General
hr
.some-block.option-block
h4(data-localise="__MSG_theme__") Theme
select#theme
option(value="DEFAULT" data-localise="__MSG_system__") System
option(value="light" data-localise="__MSG_light__") Light
option(value="dark" data-localise="__MSG_dark__") Dark
//- .some-block.option-block
h4 Tor Browser
input#firstPartyIsolate(type="checkbox")
.some-block.option-block
h4(data-localise="__MSG_protocol__")
select#protocol
option(value="normal" data-localise="__MSG_normal__") Normal
option(value="tor") Tor
option(value="i2p") I2P
option(value="loki") Lokinet
#protocol-fallback
.some-block.option-block
h4(data-localise="__MSG_protocolFallback__") Fallback to normal if no instances are available for the current protocol
input#protocol-fallback-checkbox(type="checkbox")
.some-block.option-block
h4(data-localise="__MSG_autoRedirect__")
input#auto-redirect(type="checkbox")
form
.some-block.option-block
h4(data-localise="__MSG_latencyThreshold") Latency Threshold
output#latency-output(for="latencyInput" name="latencyOutput")
input#latency-input(type="range" min="50" max="5000" value="1000" name="latencyInput" step="50")
.some-block.option-block
h4(data-localise="__MSG_exceptions__")
form#custom-exceptions-instance-form
.some-block.option-block
.some-block(style="padding:0;")
input#exceptions-custom-instance(placeholder="https://www.google.com" type="url")
|&nbsp;
select#exceptions-custom-instance-type
option(value="url") URL
option(value="regex") Regex
|&nbsp;
button#exceptions-add-instance.add(type="submit")
svg(xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor")
path(d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z")
#exceptions-custom-checklist.checklist
.buttons.buttons-inline
a#update-instances.button.button-inline
svg(xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
path(d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z")
x(data-localise="__MSG_updateInstances__") Update Instances
|&nbsp; &nbsp;
.buttons.buttons-inline
label#import_settings_text.button.button-inline(for="import-settings")
svg(xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
path(d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z")
|&nbsp;
x(data-localise="__MSG_importSettings__") Import Settings
input#import-settings.button.button-inline(type="file" style="display:none;")
|&nbsp; &nbsp;
a#export-settings.button.button-inline
svg(xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
path(d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z")
|&nbsp;
x(data-localise="__MSG_exportSettings__") Export Settings
|&nbsp; &nbsp;
a#reset-settings.button.button-inline
svg(xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
path(d="M12,5V2L8,6l4,4V7c3.31,0,6,2.69,6,6c0,2.97-2.17,5.43-5,5.91v2.02c3.95-0.49,7-3.85,7-7.93C20,8.58,16.42,5,12,5z")
path(d="M6,13c0-1.65,0.67-3.15,1.76-4.24L6.34,7.34C4.9,8.79,4,10.79,4,13c0,4.08,3.05,7.44,7,7.93v-2.02 C8.17,18.43,6,15.97,6,13z")
x(data-localise="__MSG_resetSettings__") Reset Settings
hr
.some-block.option-block
h4(data-localise="__MSG_customPopup__") Customize Popup
#popup-frontends-checklist.checklist-popup
div
div
img(src="../../../assets/images/youtube-icon.png")
x(data-localise="__MSG_youtube__") YouTube
input#youtube(type="checkbox")
div
div
img(src="../../../assets/images/youtube-music-icon.png")
x(data-localise="__MSG_ytmusic__") YoutubeMusic
input#youtubeMusic(type="checkbox")
div
div
img(src="../../../assets/images/twitter-icon.png")
x(data-localise="__MSG_twitter__") Twitter
input#twitter(type="checkbox")
div
div
img(src="../../../assets/images/instagram-icon.png")
x(data-localise="__MSG_instagram__") Instagram
input#instagram(type="checkbox")
div
div
img(src="../../../assets/images/tiktok-icon.png")
x(data-localise="__MSG_tiktok__") TikTok
input#tiktok(type="checkbox")
div
div
img(src="../../../assets/images/imgur.png")
x(data-localise="__MSG_imgur__") Imgur
input#imgur(type="checkbox")
div
div
img(src="../../../assets/images/reddit-icon.png")
x(data-localise="__MSG_reddit__") Reddit
input#reddit(type="checkbox")
div
div
svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor")
path(d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z")
x(data-localise="__MSG_search__") Search
input#search(type="checkbox")
div
div
svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor")
path(d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z")
x(data-localise="__MSG_translate__") Translate
input#translate(type="checkbox")
div
div
svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor")
path(d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM10 5.47l4 1.4v11.66l-4-1.4V5.47zm-5 .99l3-1.01v11.7l-3 1.16V6.46zm14 11.08l-3 1.01V6.86l3-1.16v11.84z")
x(data-localise="__MSG_maps__") Maps
input#maps(type="checkbox")
div
div
img(src="../../../assets/images/wikipedia-icon.svg")
x(data-localise="__MSG_wikipedia__") Wikipedia
input#wikipedia(type="checkbox")
div
div
svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1770 1000" fill="currentColor")
circle(cx="500" cy="500" r="500")
ellipse(ry="475" rx="250" cy="501" cx="1296")
ellipse(cx="1682" cy="502" rx="88" ry="424")
x(data-localise="__MSG_medium__") Medium
input#medium(type="checkbox")
div
div
img(src="../../../assets/images/quora.png")
x() Quora
input#quora(type="checkbox")
div
div
img(src="../../../assets/images/imdb.svg")
x IMDb
input#imdb(type="checkbox")
div
div
img(src="../../../assets/images/reuters.svg")
x Reuters
input#reuters(type="checkbox")
div
div
img(src="../../../assets/images/peertube-icon.svg")
x(data-localise="__MSG_peertube__") PeerTube
input#peertube(type="checkbox")
div
div
img(src="../../../assets/images/lbry-icon.png")
x(data-localise="__MSG_lbry__") LBRY
input#lbry(type="checkbox")
div
div
svg(xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
path(d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z")
x(data-localise="__MSG_sendFiles__") Send Files
input#sendTargets(type="checkbox")
script(type="module" src="./widgets/general.js")

View File

@ -1,55 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// UNCOMMENT ALL COMMENTS ONCE OTHER FRONTENDS EXIST
const frontends = new Array("libremdb")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("imdb-enable")
const imdb = document.getElementById("imdb_page")
//const frontend = document.getElementById("imdb-frontend");
let protocol
/*
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = 'block'
} else {
frontendDiv.style.display = 'none'
}
}
}
*/
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableImdb", "protocol"], r => {
enable.checked = !r.disableImdb
protocol = r.protocol
changeProtocolSettings()
})
imdb.addEventListener("change", () => {
browser.storage.local.set({ disableImdb: !enable.checked })
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("imdb", frontends[i], protocols[x], document)
}
utils.latency("imdb", frontends[i], document, location)
}

View File

@ -1,26 +0,0 @@
section#imdb_page.option-block
.some-block.option-block
h1() IMDb
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#imdb-enable(type="checkbox")
#libremdb
hr
.normal
include ../../widgets/instances.pug
+instances('https://libremdb.com')
include ../../widgets/latency.pug
+latency('libremdb')
.tor
include ../../widgets/instances.pug
+instances('http://libremdb.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://libremdb.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://libremdb.loki')
script(type="module" src="./widgets/imdb.js")

View File

@ -1,55 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// UNCOMMENT ALL COMMENTS ONCE OTHER FRONTENDS EXIST
const frontends = new Array("rimgo")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("imgur-enable")
const imgur = document.getElementById("imgur_page")
//const frontend = document.getElementById("imgur-frontend");
let protocol
/*
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = 'block'
} else {
frontendDiv.style.display = 'none'
}
}
}
*/
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableImgur", "protocol"], r => {
enable.checked = !r.disableImgur
protocol = r.protocol
changeProtocolSettings()
})
imgur.addEventListener("change", () => {
browser.storage.local.set({ disableImgur: !enable.checked })
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("imgur", frontends[i], protocols[x], document)
}
utils.latency("imgur", frontends[i], document, location)
}

View File

@ -1,27 +0,0 @@
section#imgur_page.option-block
.some-block.option-block
h1(data-localise="__MSG_imgur__") Imgur
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#imgur-enable(type="checkbox")
#rimgo
hr
.normal
include ../../widgets/instances.pug
+instances('https://rimgo.com')
include ../../widgets/latency.pug
+latency('rimgo')
.tor
include ../../widgets/instances.pug
+instances('http://rimgo.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://rimgo.onion')
.loki
include ../../widgets/instances.pug
+instances('http://rimgo.loki')
script(type="module" src="./widgets/imgur.js")

View File

@ -1,55 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// UNCOMMENT ALL COMMENTS ONCE OTHER FRONTENDS EXIST
const frontends = new Array("bibliogram")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("instagram-enable")
const instagram = document.getElementById("instagram_page")
//const frontend = document.getElementById("instagram-frontend");
let protocol
/*
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = 'block'
} else {
frontendDiv.style.display = 'none'
}
}
}
*/
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableInstagram", "protocol"], r => {
enable.checked = !r.disableInstagram
protocol = r.protocol
changeProtocolSettings()
})
instagram.addEventListener("change", () => {
browser.storage.local.set({ disableInstagram: !enable.checked })
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("instagram", frontends[i], protocols[x], document)
}
utils.latency("instagram", frontends[i], document, location)
}

View File

@ -1,27 +0,0 @@
section#instagram_page.option-block
.some-block.option-block
h1(data-localise="__MSG_instagram__") Instagram
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#instagram-enable(type="checkbox")
#bibliogram
hr
.normal
include ../../widgets/instances.pug
+instances('https://bibliogram.com')
include ../../widgets/latency.pug
+latency('bibliogram')
.tor
include ../../widgets/instances.pug
+instances('https://bibliogram.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://bibliogram.onion')
.loki
include ../../widgets/instances.pug
+instances('http://bibliogram.loki')
script(type="module" src="./widgets/instagram.js")

View File

@ -1,60 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
const frontends = new Array("librarian")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("lbry-enable")
const lbry = document.getElementById("lbry_page")
const redirectType = document.getElementById("lbry-redirect_type")
const frontend = document.getElementById("lbry-frontend")
let protocol
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = "block"
} else {
frontendDiv.style.display = "none"
}
}
}
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableLbryTargets", "protocol", "lbryFrontend", "lbryRedirectType"], r => {
enable.checked = !r.disableLbryTargets
protocol = r.protocol
redirectType.value = r.lbryRedirectType
frontend.value = r.lbryFrontend
changeFrontendsSettings()
changeProtocolSettings()
})
lbry.addEventListener("change", () => {
browser.storage.local.set({
disableLbryTargets: !enable.checked,
lbryRedirectType: redirectType.value,
lbryFrontend: frontend.value,
})
changeFrontendsSettings()
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("lbryTargets", frontends[i], protocols[x], document)
}
utils.latency("lbryTargets", frontends[i], document, location)
}

View File

@ -1,38 +0,0 @@
section#lbry_page.option-block
.some-block.option-block
h1(data-localise="__MSG_lbry__") LBRY
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#lbry-enable(type="checkbox")
.some-block.option-block
h4(data-localise="__MSG_frontend__") Frontend
select#lbry-frontend
option(value="librarian") Librarian
option(value="lbryDesktop" data-localise="__MSG_lbryDesktop__") LBRY Desktop
.some-block.option-block
h4(data-localise="__MSG_redirectType__") Redirect Type
select#lbry-redirect_type
option(value="both" data-localise="__MSG_both__") both
option(value="main_frame" data-localise="__MSG_onlyNotEmbedded__") Only Not Embedded
#librarian
hr
.normal
include ../../widgets/instances.pug
+instances('https://librarian.com')
include ../../widgets/latency.pug
+latency('librarian')
.tor
include ../../widgets/instances.pug
+instances('https://librarian.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://librarian.onion')
.loki
include ../../widgets/instances.pug
+instances('http://librarian.loki')
script(type="module" src="./widgets/lbry.js")

View File

@ -1,57 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
const frontends = new Array("facil")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("maps-enable")
const maps = document.getElementById("maps_page")
const frontend = document.getElementById("maps-frontend")
let protocol
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = "block"
} else {
frontendDiv.style.display = "none"
}
}
}
browser.storage.local.get(["disableMaps", "protocol", "mapsFrontend"], r => {
enable.checked = !r.disableMaps
protocol = r.protocol
frontend.value = r.mapsFrontend
changeFrontendsSettings()
changeProtocolSettings()
})
maps.addEventListener("change", () => {
browser.storage.local.set({
disableMaps: !enable.checked,
mapsFrontend: frontend.value,
})
changeFrontendsSettings()
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("maps", frontends[i], protocols[x], document)
}
utils.latency("maps", frontends[i], document, location)
}

View File

@ -1,32 +0,0 @@
section#maps_page.option-block
.some-block.option-block
h1(data-localise="__MSG_maps__") Maps
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#maps-enable(type="checkbox")
.some-block.option-block
h4(data-localise="__MSG_frontend__") Frontend
select#maps-frontend
option(value="osm") OpenStreetMap
option(value="facil") Facil Map
#facil
hr
.normal
include ../../widgets/instances.pug
+instances('https://facilmap.com')
include ../../widgets/latency.pug
+latency('facil')
.tor
+instances('http://facilmap.onion')
include ../../widgets/instances.pug
.i2p
include ../../widgets/instances.pug
+instances('http://facilmap.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://facilmap.loki')
script(type="module" src="./widgets/maps.js")

View File

@ -1,55 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// UNCOMMENT ALL COMMENTS ONCE OTHER FRONTENDS EXIST
const frontends = new Array("scribe")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("medium-enable")
const medium = document.getElementById("medium_page")
//const frontend = document.getElementById("medium-frontend");
let protocol
/*
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = 'block'
} else {
frontendDiv.style.display = 'none'
}
}
}
*/
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableMedium", "protocol"], r => {
enable.checked = !r.disableMedium
protocol = r.protocol
changeProtocolSettings()
})
medium.addEventListener("change", () => {
browser.storage.local.set({ disableMedium: !enable.checked })
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("medium", frontends[i], protocols[x], document)
}
utils.latency("medium", frontends[i], document, location)
}

View File

@ -1,26 +0,0 @@
section#medium_page.option-block
.some-block.option-block
h1(data-localise="__MSG_medium__") Medium
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#medium-enable(type="checkbox")
#scribe
hr
.normal
include ../../widgets/instances.pug
+instances('https://scribe.com')
include ../../widgets/latency.pug
+latency('scribe')
.tor
include ../../widgets/instances.pug
+instances('http://scribe.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://scribe.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://scribe.loki')
script(type="module" src="./widgets/medium.js")

View File

@ -1,55 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// UNCOMMENT ALL COMMENTS ONCE OTHER FRONTENDS EXIST
const frontends = new Array("simpleertube")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("peertube-enable")
const peertube = document.getElementById("peertube_page")
//const frontend = document.getElementById("peertube-frontend");
let protocol
/*
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = 'block'
} else {
frontendDiv.style.display = 'none'
}
}
}
*/
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disablePeertubeTargets", "protocol"], r => {
enable.checked = !r.disablePeertubeTargets
protocol = r.protocol
changeProtocolSettings()
})
peertube.addEventListener("change", () => {
browser.storage.local.set({ disablePeertubeTargets: !enable.checked })
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("peertube", frontends[i], protocols[x], document)
}
utils.latency("peertube", frontends[i], document, location)
}

View File

@ -1,26 +0,0 @@
section#peertube_page.option-block
.some-block.option-block
h1(data-localise="__MSG_peertube__") PeerTube
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#peertube-enable(type="checkbox")
#simpleertube
hr
.normal
include ../../widgets/instances.pug
+instances('https://simpleertube.com')
include ../../widgets/latency.pug
+latency('simpleertube')
.tor
include ../../widgets/instances.pug
+instances('http://simpleertube.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://simpleertube.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://simpleertube.loki')
script(type="module" src="./widgets/peertube.js")

View File

@ -1,55 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// UNCOMMENT ALL COMMENTS ONCE OTHER FRONTENDS EXIST
const frontends = new Array("quetre")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("quora-enable")
const quora = document.getElementById("quora_page")
//const frontend = document.getElementById("quora-frontend");
let protocol
/*
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = 'block'
} else {
frontendDiv.style.display = 'none'
}
}
}
*/
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableQuora", "protocol"], r => {
enable.checked = !r.disableQuora
protocol = r.protocol
changeProtocolSettings()
})
quora.addEventListener("change", () => {
browser.storage.local.set({ disableQuora: !enable.checked })
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("quora", frontends[i], protocols[x], document)
}
utils.latency("quora", frontends[i], document, location)
}

View File

@ -1,26 +0,0 @@
section#quora_page.option-block
.some-block.option-block
h1() Quora
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#quora-enable(type="checkbox")
#quetre
hr
.normal
include ../../widgets/instances.pug
+instances('https://quetre.com')
include ../../widgets/latency.pug
+latency('quetre')
.tor
include ../../widgets/instances.pug
+instances('http://quetre.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://quetre.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://quetre.loki')
script(type="module" src="./widgets/quora.js")

View File

@ -1,57 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
const frontends = new Array("libreddit", "teddit")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("reddit-enable")
const reddit = document.getElementById("reddit_page")
const frontend = document.getElementById("reddit-frontend")
let protocol
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = "block"
} else {
frontendDiv.style.display = "none"
}
}
}
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableReddit", "protocol", "redditFrontend"], r => {
enable.checked = !r.disableReddit
protocol = r.protocol
frontend.value = r.redditFrontend
changeFrontendsSettings()
changeProtocolSettings()
})
reddit.addEventListener("change", () => {
browser.storage.local.set({
disableReddit: !enable.checked,
redditFrontend: frontend.value,
})
changeFrontendsSettings()
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("reddit", frontends[i], protocols[x], document)
}
utils.latency("reddit", frontends[i], document, location)
}

View File

@ -1,48 +0,0 @@
section#reddit_page.option-block
.some-block.option-block
h1(data-localise="__MSG_reddit__") Reddit
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#reddit-enable(type="checkbox")
.some-block.option-block
h4#frontend(data-localise="__MSG_frontend__") Frontend
select#reddit-frontend
option(value="libreddit") Libreddit
option(value="teddit") Teddit
#libreddit
hr
.normal
include ../../widgets/instances.pug
+instances('https://libreddit.com')
include ../../widgets/latency.pug
+latency('libreddit')
.tor
include ../../widgets/instances.pug
+instances('http://libreddit.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://libreddit.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://libreddit.loki')
#teddit
hr
.normal
include ../../widgets/instances.pug
+instances('https://teddit.com')
+latency('teddit')
.tor
include ../../widgets/instances.pug
+instances('http://teddit.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://teddit.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://teddit.loki')
script(type="module" src="./widgets/reddit.js")

View File

@ -1,55 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// UNCOMMENT ALL COMMENTS ONCE OTHER FRONTENDS EXIST
const frontends = new Array("neuters")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("reuters-enable")
const reuters = document.getElementById("reuters_page")
//const frontend = document.getElementById("reuters-frontend");
let protocol
/*
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = 'block'
} else {
frontendDiv.style.display = 'none'
}
}
}
*/
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableReuters", "protocol"], r => {
enable.checked = !r.disableReuters
protocol = r.protocol
changeProtocolSettings()
})
reuters.addEventListener("change", () => {
browser.storage.local.set({ disableReuters: !enable.checked })
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("reuters", frontends[i], protocols[x], document)
}
utils.latency("reuters", frontends[i], document, location)
}

View File

@ -1,26 +0,0 @@
section#reuters_page.option-block
.some-block.option-block
h1() Reuters
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#reuters-enable(type="checkbox")
#neuters
hr
.normal
include ../../widgets/instances.pug
+instances('https://neuters.com')
include ../../widgets/latency.pug
+latency('neuters')
.tor
include ../../widgets/instances.pug
+instances('http://neuters.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://neuters.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://neuters.loki')
script(type="module" src="./widgets/reuters.js")

View File

@ -1,204 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// GOAL: to never mention frontends/protocls outside these two arrays, so that adding a new frontend/protocol is as easy as adding it here.
// This may be expanded across the whole project, where almost everything becomes a template, and the frontend/protocol parts just become a JSON file.
// ONCE FINISHED: add librex and see if it works
const frontends = new Array("searx", "searxng", "whoogle", "librex") // Add librex once /javascripts/search.js is made agnostic
const protocols = new Array("normal", "tor", "i2p", "loki")
//let frontendProtocols = (frontends.length)
// I will leave comments of my privious attemps so that people can learn from my mistakes. :)
/*
for (let i = 0; i < frontends.length; i++) {
this.frontends[i] = frontends[i].getElementsByClassName(protocol)
}
*/
// There was a class here, but I deleted a bit of it
/*
this.searxDiv = searxDiv.getElementsByClassName(protocol)[0];
this.searxngDiv = searxngDiv.getElementsByClassName(protocol)[0];
this.librexDiv = librexDiv.getElementsByClassName(protocol)[0];
*/
/*
* Here I was trying to solve the issue by making a 2D array, but I later realised I was overcomplicating things
for (var i = 0; i < frontends.length; i++) {
frontendProtocols[i] = new Array(protocols.length)
}
*/
/*
const searxDiv = document.getElementById("searx");
const searxngDiv = document.getElementById("searxng");
const whoogleDiv = document.getElementById("whoogle");
*/
const enable = document.getElementById("search-enable")
const search = document.getElementById("search_page")
const frontend = document.getElementById("search-frontend")
let protocol
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = "block"
} else {
frontendDiv.style.display = "none"
}
}
/*
if (frontend.value == 'searx') {
searxDiv.style.display = 'block';
searxngDiv.style.display = 'none';
whoogleDiv.style.display = 'none';
librexDiv.style.display = 'none';
}
else if (frontend.value == 'searxng') {
searxDiv.style.display = 'none';
searxngDiv.style.display = 'block';
whoogleDiv.style.display = 'none';
librexDiv.style.display = 'none';
}
else if (frontend.value == 'whoogle') {
searxDiv.style.display = 'none';
searxngDiv.style.display = 'none';
whoogleDiv.style.display = 'block';
librexDiv.style.display = 'none';
}
else if (frontend.value == 'librex') {
searxDiv.style.display = 'none';
searxDiv.style.display = 'none';
searxngDiv.style.display = 'none';
librexDiv.style.display = 'block';
}
*/
}
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
//if (frontends[i] == frontend.value) { // Here we are checking if the frontend matches the current one. This skips the protocol checking for that frontend, speeding things up. I no longer do this as protocol setting is only set once in the ui so every frontend needs to get their protocols setup immidiately.
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
//if the frontend value equals the selected one, it will show. Otherwise, it will be hidden
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
/*
} else {
continue
}
*/
}
/*
* "Legacy" code
const normalsearxDiv = searxDiv.getElementsByClassName("normal")[0];
const torsearxDiv = searxDiv.getElementsByClassName("tor")[0];
const i2psearxDiv = searxDiv.getElementsByClassName("i2p")[0];
const normalsearxngDiv = searxngDiv.getElementsByClassName("normal")[0];
const torsearxngDiv = searxngDiv.getElementsByClassName("tor")[0];
const i2psearxngDiv = searxngDiv.getElementsByClassName("i2p")[0];
const torwhoogleDiv = whoogleDiv.getElementsByClassName("tor")[0];
const i2pwhoogleDiv = whoogleDiv.getElementsByClassName("i2p")[0];
const normalwhoogleDiv = whoogleDiv.getElementsByClassName("normal")[0];
function protocolDisplay(proto) {
proto.searxngDiv = 'block'
}
protocolDisplay(protocol.value)
if (protocol.value == 'normal') {
normalsearxDiv.style.display = 'block';
normalsearxngDiv.style.display = 'block';
normalwhoogleDiv.style.display = 'block';
torsearxDiv.style.display = 'none';
torsearxngDiv.style.display = 'none';
torwhoogleDiv.style.display = 'none';
i2psearxDiv.style.display = 'none';
i2psearxngDiv.style.display = 'none';
i2pwhoogleDiv.style.display = 'none';
}
else if (protocol.value == 'tor') {
normalsearxDiv.style.display = 'none';
normalsearxngDiv.style.display = 'none';
normalwhoogleDiv.style.display = 'none';
torsearxDiv.style.display = 'block';
torsearxngDiv.style.display = 'block';
torwhoogleDiv.style.display = 'block';
i2psearxDiv.style.display = 'none';
i2psearxngDiv.style.display = 'none';
i2pwhoogleDiv.style.display = 'none';
}
else if (protocol.value == 'i2p') {
normalsearxDiv.style.display = 'none';
normalsearxngDiv.style.display = 'none';
normalwhoogleDiv.style.display = 'none';
torsearxDiv.style.display = 'none';
torsearxngDiv.style.display = 'none';
torwhoogleDiv.style.display = 'none';
i2psearxDiv.style.display = 'block';
i2psearxngDiv.style.display = 'block';
i2pwhoogleDiv.style.display = 'block';
}
*/
}
browser.storage.local.get(["disableSearch", "searchFrontend", "protocol"], r => {
enable.checked = !r.disableSearch
frontend.value = r.searchFrontend
protocol = r.protocol
changeFrontendsSettings()
changeProtocolSettings()
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("search", frontends[i], protocols[x], document)
}
utils.latency("search", frontends[i], document, location)
}
search.addEventListener("change", () => {
browser.storage.local.set({
disableSearch: !enable.checked,
searchFrontend: frontend.value,
})
changeFrontendsSettings()
})
/*
* more "legacy" code
utils.processDefaultCustomInstances('search', 'searx', 'normal', document);
utils.processDefaultCustomInstances('search', 'searx', 'tor', document);
utils.processDefaultCustomInstances('search', 'searx', 'i2p', document);
utils.processDefaultCustomInstances('search', 'searxng', 'normal', document);
utils.processDefaultCustomInstances('search', 'searxng', 'tor', document);
utils.processDefaultCustomInstances('search', 'searxng', 'i2p', document);
utils.processDefaultCustomInstances('search', 'whoogle', 'normal', document);
utils.processDefaultCustomInstances('search', 'whoogle', 'tor', document);
utils.processDefaultCustomInstances('search', 'whoogle', 'i2p', document);
utils.latency('search', 'searx', document, location, true)
utils.latency('search', 'searxng', document, location, true)
utils.latency('search', 'whoogle', document, location, true)
*/

View File

@ -1,85 +0,0 @@
section#search_page.option-block
.some-block.option-block
h1(data-localise="__MSG_search__") Search
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#search-enable(type="checkbox")
.some-block.option-block
h4(data-localise="__MSG_frontend__") Frontend
select#search-frontend
option(value="searxng") SearXNG
option(value="searx") SearX
option(value="whoogle") Whoogle
option(value="librex") LibreX
.some-block
h4(data-localise="__MSG_searchNote__") Note: To use Search, make LibRedirect the Default Search Engine
#searx
hr
.normal
include ../../widgets/instances.pug
+instances('https://searx.com')
include ../../widgets/latency.pug
+latency('searx')
.tor
include ../../widgets/instances.pug
+instances('http://searx.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://searx.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://searx.loki')
#searxng
hr
.normal
include ../../widgets/instances.pug
+instances('https://searxng.com')
+latency('searxng')
.tor
include ../../widgets/instances.pug
+instances('http://searxng.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://searxng.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://searxng.loki')
#whoogle
hr
.normal
include ../../widgets/instances.pug
+instances('https://whoogle.com')
+latency('whoogle')
.tor
include ../../widgets/instances.pug
+instances('http://whoogle.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://whoogle.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://whoogle.loki')
#librex
hr
.normal
include ../../widgets/instances.pug
+instances('https://librex.com')
+latency('librex')
.tor
include ../../widgets/instances.pug
+instances('http://librex.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://librex.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://librex.loki')
script(type="module" src="./widgets/search.js")

View File

@ -1,55 +0,0 @@
import utils from "../../../assets/javascripts/utils.js"
// UNCOMMENT ALL COMMENTS ONCE OTHER FRONTENDS EXIST
const frontends = new Array("send")
const protocols = new Array("normal", "tor", "i2p", "loki")
const enable = document.getElementById("sendTargets-enable")
const sendTargets = document.getElementById("sendTargets_page")
//const frontend = document.getElementById("sendTargets-frontend");
let protocol
/*
function changeFrontendsSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
if (frontends[i] == frontend.value) {
frontendDiv.style.display = 'block'
} else {
frontendDiv.style.display = 'none'
}
}
}
*/
function changeProtocolSettings() {
for (let i = 0; i < frontends.length; i++) {
const frontendDiv = document.getElementById(frontends[i])
for (let x = 0; x < protocols.length; x++) {
const protocolDiv = frontendDiv.getElementsByClassName(protocols[x])[0]
if (protocols[x] == protocol) {
protocolDiv.style.display = "block"
} else {
protocolDiv.style.display = "none"
}
}
}
}
browser.storage.local.get(["disableSendTarget", "protocol"], r => {
enable.checked = !r.disableSendTarget
protocol = r.protocol
changeProtocolSettings()
})
sendTargets.addEventListener("change", () => {
browser.storage.local.set({ disableSendTarget: !enable.checked })
})
for (let i = 0; i < frontends.length; i++) {
for (let x = 0; x < protocols.length; x++) {
utils.processDefaultCustomInstances("sendTargets", frontends[i], protocols[x], document)
}
utils.latency("sendTargets", frontends[i], document, location)
}

View File

@ -1,26 +0,0 @@
section#sendTargets_page.option-block
.some-block.option-block
h1(data-localise="__MSG_sendFiles__") Send Files
hr
.some-block.option-block
h4(data-localise="__MSG_enable__") Enable
input#sendTargets-enable(type="checkbox")
#send
hr
.normal
include ../../widgets/instances.pug
+instances('https://send.com')
include ../../widgets/latency.pug
+latency('send')
.tor
include ../../widgets/instances.pug
+instances('http://send.onion')
.i2p
include ../../widgets/instances.pug
+instances('http://send.i2p')
.loki
include ../../widgets/instances.pug
+instances('http://send.loki')
script(type="module" src="./widgets/sendTargets.js")

View File

@ -0,0 +1,86 @@
<% for (const service in config.services) { -%>
<section class="option-block" id="<%= service %>_page">
<div class="some-block option-block">
<h1 data-localise="__MSG_<%= service %>__"><%= config.services[service].name %></h1>
</div>
<hr>
<div class="some-block option-block">
<h4 data-localise="__MSG_enable__">Enable</h4>
<input id="<%= service %>-enabled" type="checkbox">
</div>
<% if (Object.keys(config.services[service].frontends).length > 1) { %>
<div class="some-block option-block">
<h4 data-localise="__MSG_frontend__">Frontend</h4>
<select id="<%= service %>-frontend">
<% for (const frontend in config.services[service].frontends) { -%>
<option value="<%= frontend %>"><%= config.services[service].frontends[frontend].name %></option>
<% } %>
</select>
</div>
<% if (config.services[service].embeddable) { _%>
<div class="some-block option-block">
<h4 data-localise="__MSG_embed_frontend__">Embed Frontend</h4>
<select id="<%= service %>-embedFrontend">
<% for (const frontend in config.services[service].frontends) { -%>
<% if (config.services[service].frontends[frontend].embeddable) { _%>
<option value="<%= frontend %>"><%= config.services[service].frontends[frontend].name %></option>
<% } _%>
<% } %>
</select>
</div>
<% } _%>
<% } _%>
<% if (config.services[service].embeddable) { _%>
<div class="some-block option-block">
<h4 data-localise="__MSG_redirectType__">Redirect Type</h4>
<select id="<%= service %>-redirectType">
<option value="both" data-localise="__MSG_both__">both</option>
<option value="sub_frame" data-localise="__MSG_onlyEmbedded__">Only Embedded</option>
<option value="main_frame" data-localise="__MSG_onlyNotEmbedded__">Only Not Embedded</option>
</select>
</div>
<% } _%>
<hr>
<% for (const frontend in config.services[service].frontends) { -%>
<% if (config.services[service].frontends[frontend].instanceList) { _%>
<div id="<%= frontend %>">
<% for (const network in config.networks) { -%>
<div class="<%= network %>">
<div class="some-block option-block">
<h4 data-localise="__MSG_defaultInstances__">Default Instances</h4>
</div>
<div class="checklist"></div>
<hr>
<div class="some-block option-block">
<h4 data-localise="__MSG_customInstances__">Custom Instances</h4>
</div>
<form class="custom-instance-form">
<div class="some-block option-block">
<input class="custom-instance" placeholder="http://<%= frontend %>.<%= config.networks[network].tld %>" type="url">
<button class="add add-instance" type="submit">
<svg xmlns="https://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path>
</svg>
</button>
</div>
</form>
<div class="checklist custom-checklist"></div>
<% if (network == "clearnet") { _%>
<div class="buttons buttons-inline">
<label class="button button-inline" id="latency-<%= frontend %>-label" for="latency-<%= frontend %>">
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
<path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"></path>
</svg>&nbsp;
<x data-localise="__MSG_testInstancesLatency__">Test Instances Latency</x>
</label>
<input class="button button-inline" id="latency-<%= frontend %>" style="display:none;">
</div>
<% } _%>
</div>
<% } %>
</div>
<% } _%>
<% } %>
</section>
<% } %>
<script type="module" src="./widgets/services.js"></script>

Some files were not shown because too many files have changed in this diff Show More