This commit is contained in:
commit
02d1110084
|
@ -6,7 +6,6 @@
|
|||
OpenStreetMap (OSM) reverse geocoding, done via the [OSM Nomantim API](https://nominatim.org/release-docs/develop/api/Overview/),
|
||||
used as part of OSM redirects, which can be disabled by toggling the OSM redirects.
|
||||
- It also connects to [this url](https://raw.githubusercontent.com/libredirect/libredirect/master/src/instances/data.json) to update the Instances List. Though this only gets triggered when the user presses the `Update Instances` button.
|
||||
- For bibliogram instances. To set a cookie you should send an HTTP request to the server as the server stores settings values itself and gives you a token to access them.
|
||||
|
||||
## Future Changes
|
||||
|
||||
|
|
13
README.md
13
README.md
|
@ -6,6 +6,8 @@ A web extension that redirects YouTube, Twitter, Instagram... requests to altern
|
|||
[![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)
|
||||
|
||||
[![OpenCollective Badge](https://opencollective.com/libredirect/tiers/badge.svg)](https://opencollective.com/libredirect#category-CONTRIBUTE)
|
||||
|
||||
[![Firefox Add-on](./img/badge-amo.png)](https://addons.mozilla.org/firefox/addon/libredirect/)
|
||||
<a href="./chromium.md">
|
||||
<img src ="./img/badge-chromium.png" height=60 >
|
||||
|
@ -31,7 +33,7 @@ A web extension that redirects YouTube, Twitter, Instagram... requests to altern
|
|||
- 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/)
|
||||
- Translate => [SimplyTranslate](https://git.sr.ht/~metalune/simplytranslate_web), [LingvaTranslate](https://github.com/TheDavidDelta/lingva-translate), [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate)
|
||||
- Maps => [OpenStreetMap](https://www.openstreetmap.org/), [FacilMap](https://github.com/FacilMap/facilmap)
|
||||
- Google Maps => [OpenStreetMap](https://www.openstreetmap.org/), [FacilMap](https://github.com/FacilMap/facilmap)
|
||||
- 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.
|
||||
|
@ -43,13 +45,11 @@ A web extension that redirects YouTube, Twitter, Instagram... requests to altern
|
|||
[![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)
|
||||
<a href="https://opencollective.com/libredirect"><img src = ./img/Open-Collective.png width=17% height=17%></a>
|
||||
<a href="https://opencollective.com/libredirect"><img src = ./img/Open-Collective.png width=19% height=19%></a>
|
||||
|
||||
- BTC: `bc1qrhue0frps6p2vkg978u9ayethnwprtmfug827q`
|
||||
- BCH: `qqz5vfnrngk0tjy73q2688qzw4wnllnuzqfndflhl8`
|
||||
- ETH: `0x896E5796Da76E49A400A9186E1c459CD2C64b4E8`
|
||||
- XMR: `4AM5CVfaGsnEXQQjZSzJvaWufe7pT86ubcZPr83fCjb2Hn3iwcForTWFy2Z3ugXcufUwHaGcucfPMFgPXBFSYGFvNrmV5XR`
|
||||
|
||||
Note : We have removed our addresses for BTC and ETH. If you want to donate via Crypto use OpenCollective. We still have XMR as OpenCollective doesn't support it.
|
||||
## Mirror Repos
|
||||
|
||||
[![Codeberg](https://raw.githubusercontent.com/ManeraKai/manerakai/main/icons/codeberg.svg)](https://codeberg.org/LibRedirect/libredirect)
|
||||
|
@ -117,5 +117,8 @@ npm run start
|
|||
3. select `load unpacked extension`
|
||||
4. select `src` folder
|
||||
|
||||
---
|
||||
|
||||
[Privacy Policy](Privacy-Policy.md)\
|
||||
Forked from [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect)
|
||||
|
||||
|
|
|
@ -32,10 +32,8 @@ async function initDefaults() {
|
|||
},
|
||||
theme: "detect",
|
||||
popupServices: ["youtube", "twitter", "instagram", "tiktok", "imgur", "reddit", "quora", "translate", "maps"],
|
||||
autoRedirect: false,
|
||||
network: "clearnet",
|
||||
networkFallback: true,
|
||||
latencyThreshold: 1000,
|
||||
},
|
||||
},
|
||||
() => resolve()
|
||||
|
|
|
@ -47,7 +47,9 @@ function all(service, frontend, options, config, redirects) {
|
|||
|
||||
function regexArray(service, url, config, frontend) {
|
||||
if (config.services[service].targets == "datajson") {
|
||||
if (targets[service].startsWith(utils.protocolHost(url))) return true
|
||||
for (const instance of targets[service]) {
|
||||
if (instance.startsWith(utils.protocolHost(url))) return true
|
||||
}
|
||||
} else {
|
||||
const targetList = config.services[service].targets
|
||||
if (frontend && config.services[service].frontends[frontend].excludeTargets)
|
||||
|
@ -128,7 +130,8 @@ function redirect(url, type, initiator, forceRedirection) {
|
|||
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}`
|
||||
if (url.pathname.startsWith("/reel")) return `${randomInstance}${url.pathname}`
|
||||
if (url.pathname.startsWith("/tv")) return `${randomInstance}/p${url.pathname.replace(/\/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, "#")
|
||||
|
@ -138,11 +141,11 @@ function redirect(url, type, initiator, forceRedirection) {
|
|||
else return `${randomInstance}${url.pathname}/`
|
||||
case "searx":
|
||||
case "searxng":
|
||||
return `${randomInstance}/?q=${encodeURIComponent(url.searchParams.get("q"))}`
|
||||
return `${randomInstance}/${url.search}`
|
||||
case "whoogle":
|
||||
return `${randomInstance}/search?q=${encodeURIComponent(url.searchParams.get("q"))}`
|
||||
return `${randomInstance}/search${url.search}`
|
||||
case "librex":
|
||||
return `${randomInstance}/search.php?q=${encodeURIComponent(url.searchParams.get("q"))}`
|
||||
return `${randomInstance}/search.php${url.search}`
|
||||
case "send":
|
||||
return randomInstance
|
||||
case "nitter":
|
||||
|
@ -411,7 +414,7 @@ function redirect(url, type, initiator, forceRedirection) {
|
|||
if (url.hostname.match(/^[a-zA-Z0-9-]+\.fandom\.com/)) {
|
||||
wiki = url.hostname.match(/^[a-zA-Z0-9-]+(?=\.fandom\.com)/)
|
||||
if (wiki == "www" || !wiki) wiki = ""
|
||||
else wiki = "/" + wiki
|
||||
else wiki = `/${wiki}`;
|
||||
urlpath = url.pathname
|
||||
} else {
|
||||
wiki = url.pathname.match(/(?<=wiki\/w:c:)[a-zA-Z0-9-]+(?=:)/)
|
||||
|
@ -443,6 +446,8 @@ function redirect(url, type, initiator, forceRedirection) {
|
|||
else return `${randomInstance}${url.pathname}${url.search}&teddit_proxy=${url.hostname}`
|
||||
}
|
||||
return `${randomInstance}${url.pathname}${url.search}`
|
||||
case "simpleertube":
|
||||
return `${randomInstance}/${url.hostname}${url.pathname}${url.search}`
|
||||
default:
|
||||
return `${randomInstance}${url.pathname}${url.search} `
|
||||
}
|
||||
|
@ -541,6 +546,14 @@ function reverse(url, urlString) {
|
|||
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
|
||||
case "fandom":
|
||||
let regex = url.pathname.match(/^\/([a-zA-Z0-9-]+)\/wiki\/([a-zA-Z0-9-]+)/)
|
||||
if (regex) {
|
||||
resolve(`https://${regex[1]}.fandom.com/wiki/${regex[2]}`)
|
||||
return
|
||||
}
|
||||
resolve()
|
||||
return
|
||||
default:
|
||||
resolve()
|
||||
return
|
||||
|
@ -550,50 +563,6 @@ function reverse(url, urlString) {
|
|||
})
|
||||
}
|
||||
|
||||
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(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
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function setRedirects(passedRedirects) {
|
||||
return new Promise(resolve => {
|
||||
fetch("/config/config.json")
|
||||
|
@ -662,7 +631,6 @@ function initDefaults() {
|
|||
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") {
|
||||
|
@ -687,7 +655,7 @@ function initDefaults() {
|
|||
}
|
||||
}
|
||||
}
|
||||
browser.storage.local.set({ redirects, options, targets, latency, localstorage })
|
||||
browser.storage.local.set({ redirects, options, targets, localstorage })
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
@ -702,7 +670,6 @@ function upgradeOptions() {
|
|||
.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
|
||||
|
@ -717,7 +684,6 @@ function upgradeOptions() {
|
|||
options.popupServices.splice(tmp, 1)
|
||||
options.popupServices.push("sendFiles")
|
||||
}
|
||||
options.autoRedirect = r.autoRedirect
|
||||
switch (r.onlyEmbeddedVideo) {
|
||||
case "onlyNotEmbedded":
|
||||
options.youtube.redirectType = "main_frame"
|
||||
|
@ -747,7 +713,6 @@ function upgradeOptions() {
|
|||
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"
|
||||
|
@ -763,7 +728,7 @@ function upgradeOptions() {
|
|||
}
|
||||
}
|
||||
}
|
||||
browser.storage.local.set({ options, latency }, () => resolve())
|
||||
browser.storage.local.set({ options }, () => resolve())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -870,7 +835,6 @@ export default {
|
|||
computeService,
|
||||
switchInstance,
|
||||
reverse,
|
||||
unifyPreferences,
|
||||
setRedirects,
|
||||
initDefaults,
|
||||
upgradeOptions,
|
||||
|
|
|
@ -13,7 +13,6 @@ function camelCase(str) {
|
|||
|
||||
let cloudflareBlackList = []
|
||||
let authenticateBlackList = []
|
||||
let offlineBlackList = []
|
||||
async function initBlackList() {
|
||||
return new Promise(resolve => {
|
||||
fetch("/instances/blacklist.json")
|
||||
|
@ -21,7 +20,6 @@ async function initBlackList() {
|
|||
.then(data => {
|
||||
cloudflareBlackList = JSON.parse(data).cloudflare
|
||||
authenticateBlackList = JSON.parse(data).authenticate
|
||||
offlineBlackList = JSON.parse(data).offline
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
@ -60,7 +58,6 @@ function protocolHost(url) {
|
|||
}
|
||||
|
||||
async function processDefaultCustomInstances(service, frontend, network, document) {
|
||||
let instancesLatency
|
||||
let frontendNetworkElement = document.getElementById(frontend).getElementsByClassName(network)[0]
|
||||
|
||||
let frontendCustomInstances = []
|
||||
|
@ -74,11 +71,10 @@ async function processDefaultCustomInstances(service, frontend, network, documen
|
|||
|
||||
async function getFromStorage() {
|
||||
return new Promise(async resolve =>
|
||||
browser.storage.local.get(["options", "redirects", "latency"], r => {
|
||||
browser.storage.local.get(["options", "redirects",], r => {
|
||||
frontendDefaultRedirects = r.options[frontend][network].enabled
|
||||
frontendCustomInstances = r.options[frontend][network].custom
|
||||
options = r.options
|
||||
instancesLatency = r.latency[frontend] ?? []
|
||||
redirects = r.redirects
|
||||
resolve()
|
||||
})
|
||||
|
@ -106,22 +102,17 @@ async function processDefaultCustomInstances(service, frontend, network, documen
|
|||
<x data-localise="__MSG_toggleAll__">Toggle All</x>
|
||||
<input type="checkbox" class="toggle-all"/>
|
||||
</div>`,
|
||||
...redirects[frontend][network].map(x => {
|
||||
...redirects[frontend][network]
|
||||
.sort((a, b) =>
|
||||
(cloudflareBlackList.includes(a) && !cloudflareBlackList.includes(b))
|
||||
||
|
||||
(authenticateBlackList.includes(a) && !authenticateBlackList.includes(b))
|
||||
)
|
||||
.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 == -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>" : ""
|
||||
|
||||
let warnings = [cloudflare, authenticate, offline, latency].join(" ")
|
||||
let warnings = [cloudflare, authenticate].join(" ")
|
||||
return `<div>
|
||||
<x><a href="${x}" target="_blank">${x}</a>${warnings}</x>
|
||||
<input type="checkbox" class="${x}"/>
|
||||
|
@ -168,7 +159,7 @@ async function processDefaultCustomInstances(service, frontend, network, documen
|
|||
x => `<div>
|
||||
${x}
|
||||
<button class="add clear-${x}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
|
||||
<svg xmlns="https://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
|
||||
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
@ -211,133 +202,6 @@ async function processDefaultCustomInstances(service, frontend, network, documen
|
|||
})
|
||||
}
|
||||
|
||||
function ping(href) {
|
||||
return new Promise(async resolve => {
|
||||
let average = 0
|
||||
let time
|
||||
for (let i = 0; i < 3; i++) {
|
||||
time = await pingOnce(href)
|
||||
if (i == 0) continue
|
||||
if (time >= 5000) {
|
||||
resolve(time)
|
||||
return
|
||||
}
|
||||
average += time
|
||||
}
|
||||
average = parseInt(average / 3)
|
||||
resolve(average)
|
||||
})
|
||||
}
|
||||
|
||||
function pingOnce(href) {
|
||||
return new Promise(async resolve => {
|
||||
let started
|
||||
let http = new XMLHttpRequest()
|
||||
http.timeout = 5000
|
||||
http.ontimeout = () => resolve(5000)
|
||||
http.onerror = () => resolve()
|
||||
http.onreadystatechange = () => {
|
||||
if (http.readyState == 2) {
|
||||
if (http.status == 200) {
|
||||
let ended = new Date().getTime()
|
||||
http.abort()
|
||||
resolve(ended - started)
|
||||
} else {
|
||||
resolve(5000 + http.status)
|
||||
}
|
||||
}
|
||||
}
|
||||
http.open("GET", `${href}?_=${new Date().getTime()}`, true)
|
||||
started = new Date().getTime()
|
||||
http.send(null)
|
||||
})
|
||||
}
|
||||
|
||||
async function testLatency(element, instances, frontend) {
|
||||
return new Promise(async resolve => {
|
||||
let myList = {}
|
||||
let latencyThreshold, options
|
||||
browser.storage.local.get(["options"], r => {
|
||||
latencyThreshold = r.options.latencyThreshold
|
||||
options = r.options
|
||||
})
|
||||
for (const href of instances) {
|
||||
await ping(href).then(time => {
|
||||
let color
|
||||
if (time) {
|
||||
myList[href] = time
|
||||
if (time <= 1000) color = "green"
|
||||
else if (time <= 2000) color = "orange"
|
||||
else color = "red"
|
||||
|
||||
if (time > latencyThreshold && options[frontend].clearnet.enabled.includes(href)) {
|
||||
options[frontend].clearnet.enabled.splice(options[frontend].clearnet.enabled.indexOf(href), 1)
|
||||
}
|
||||
|
||||
let text
|
||||
if (time == 5000) text = "5000ms+"
|
||||
else if (time > 5000) text = `ERROR: ${time - 5000}`
|
||||
else text = `${time}ms`
|
||||
element.innerHTML = `${href}: <span style="color:${color};">${text}</span>`
|
||||
} else {
|
||||
myList[href] = -1
|
||||
color = "red"
|
||||
element.innerHTML = `${href}: <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(targetUrl, urls, name) {
|
||||
return new Promise(resolve => {
|
||||
const query = {
|
||||
url: protocolHost(targetUrl),
|
||||
name: name,
|
||||
}
|
||||
browser.cookies.getAll(query, async cookies => {
|
||||
for (const cookie of cookies)
|
||||
if (cookie.name == name) {
|
||||
for (const url of urls) {
|
||||
const setQuery = {
|
||||
url: url,
|
||||
name: name,
|
||||
value: cookie.value,
|
||||
secure: true,
|
||||
expirationDate: cookie.expirationDate,
|
||||
}
|
||||
browser.cookies.set(setQuery)
|
||||
}
|
||||
break
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getPreferencesFromToken(frontend, targetUrl, urls, name, endpoint) {
|
||||
return new Promise(resolve => {
|
||||
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()
|
||||
http.open("POST", `${url}/settings/stay`, false)
|
||||
http.send(null)
|
||||
}
|
||||
resolve()
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
function copyRaw(test, copyRawElement) {
|
||||
return new Promise(resolve => {
|
||||
browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
|
||||
|
@ -370,25 +234,6 @@ function copyRaw(test, copyRawElement) {
|
|||
})
|
||||
}
|
||||
|
||||
function unify() {
|
||||
return new Promise(resolve => {
|
||||
browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
|
||||
let currTab = tabs[0]
|
||||
if (currTab) {
|
||||
let url
|
||||
try {
|
||||
url = new URL(currTab.url)
|
||||
} catch {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
|
||||
resolve(await servicesHelper.unifyPreferences(url, currTab.id))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function switchInstance(test) {
|
||||
return new Promise(resolve => {
|
||||
browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
|
||||
|
@ -412,41 +257,12 @@ function switchInstance(test) {
|
|||
})
|
||||
}
|
||||
|
||||
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)
|
||||
browser.storage.local.get("redirects", r => {
|
||||
let redirects = r.redirects
|
||||
const oldHtml = latencyLabel.innerHTML
|
||||
latencyLabel.innerHTML = "..."
|
||||
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)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
getRandomInstance,
|
||||
updateInstances,
|
||||
protocolHost,
|
||||
processDefaultCustomInstances,
|
||||
latency,
|
||||
copyCookie,
|
||||
getPreferencesFromToken,
|
||||
switchInstance,
|
||||
copyRaw,
|
||||
unify,
|
||||
camelCase,
|
||||
}
|
||||
|
|
|
@ -21,14 +21,6 @@
|
|||
"youtube": {
|
||||
"frontends": {
|
||||
"invidious": {
|
||||
"preferences": {
|
||||
"cookies": [
|
||||
"PREFS"
|
||||
],
|
||||
"localstorage": [
|
||||
"dark_mode"
|
||||
]
|
||||
},
|
||||
"name": "Invidious",
|
||||
"embeddable": true,
|
||||
"instanceList": true
|
||||
|
@ -38,29 +30,6 @@
|
|||
1,
|
||||
2
|
||||
],
|
||||
"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
|
||||
|
@ -70,21 +39,11 @@
|
|||
1,
|
||||
2
|
||||
],
|
||||
"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
|
||||
|
@ -130,30 +89,10 @@
|
|||
"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
|
||||
}
|
||||
|
@ -173,27 +112,6 @@
|
|||
"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
|
||||
|
@ -217,17 +135,12 @@
|
|||
"instagram": {
|
||||
"frontends": {
|
||||
"bibliogram": {
|
||||
"preferences": {
|
||||
"token": "token",
|
||||
"fetchEndpoint": "/settings.json",
|
||||
"setEndpoint": "/applysettings"
|
||||
},
|
||||
"name": "Bibliogram",
|
||||
"instanceList": true
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
"^https?:\\/{2}(www\\.)?instagram\\.com\\/?(p\\/|$)"
|
||||
"^https?:\\/{2}(www\\.)?instagram\\.com\\/?(p\\/|reel\\/|$)"
|
||||
],
|
||||
"name": "Instagram",
|
||||
"options": {
|
||||
|
@ -240,12 +153,6 @@
|
|||
"tiktok": {
|
||||
"frontends": {
|
||||
"proxiTok": {
|
||||
"preferences": {
|
||||
"cookies": [
|
||||
"api-test_endpoints",
|
||||
"theme"
|
||||
]
|
||||
},
|
||||
"name": "ProxiTok",
|
||||
"instanceList": true
|
||||
}
|
||||
|
@ -264,52 +171,16 @@
|
|||
"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(?=\\/u(ser)?\\/|\\/r\\/|\\/?$)",
|
||||
"^https?:\\/{2}(www\\.|old\\.|np\\.|new\\.|amp\\.|)reddit\\.com(?=\\/u(ser)?\\/|\\/r\\/|\\/search|\\/?$)",
|
||||
"^https?:\\/{2}(i|(external-)?preview)\\.redd\\.it"
|
||||
],
|
||||
"name": "Reddit",
|
||||
|
@ -343,12 +214,6 @@
|
|||
"wikipedia": {
|
||||
"frontends": {
|
||||
"wikiless": {
|
||||
"preferences": {
|
||||
"cookies": [
|
||||
"theme",
|
||||
"default_lang"
|
||||
]
|
||||
},
|
||||
"name": "Wikiless",
|
||||
"instanceList": true
|
||||
}
|
||||
|
@ -402,11 +267,6 @@
|
|||
"quora": {
|
||||
"frontends": {
|
||||
"quetre": {
|
||||
"preferences": {
|
||||
"localstorage": [
|
||||
"theme"
|
||||
]
|
||||
},
|
||||
"name": "Quetre",
|
||||
"instanceList": true
|
||||
}
|
||||
|
@ -425,11 +285,6 @@
|
|||
"imdb": {
|
||||
"frontends": {
|
||||
"libremdb": {
|
||||
"preferences": {
|
||||
"localstorage": [
|
||||
"theme"
|
||||
]
|
||||
},
|
||||
"name": "libremdb",
|
||||
"instanceList": true
|
||||
}
|
||||
|
@ -500,20 +355,6 @@
|
|||
"lbry": {
|
||||
"frontends": {
|
||||
"librarian": {
|
||||
"preferences": {
|
||||
"cookies": [
|
||||
"nsfw",
|
||||
"theme"
|
||||
],
|
||||
"localstorage": [
|
||||
"autoplay",
|
||||
"autoplayNextVid",
|
||||
"collapseComments",
|
||||
"plyr",
|
||||
"sb_categories",
|
||||
"showRelated"
|
||||
]
|
||||
},
|
||||
"name": "Librarian",
|
||||
"embeddable": true,
|
||||
"instanceList": true
|
||||
|
@ -542,55 +383,10 @@
|
|||
"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
|
||||
},
|
||||
|
@ -599,20 +395,6 @@
|
|||
"instanceList": true
|
||||
},
|
||||
"librex": {
|
||||
"preferences": {
|
||||
"cookies": [
|
||||
"bibliogram",
|
||||
"disable_frontends",
|
||||
" disable_special",
|
||||
"invidious",
|
||||
"libreddit",
|
||||
"nitter",
|
||||
"proxitok",
|
||||
"save",
|
||||
"theme",
|
||||
"wikiless"
|
||||
]
|
||||
},
|
||||
"name": "LibreX",
|
||||
"instanceList": true
|
||||
}
|
||||
|
@ -632,26 +414,10 @@
|
|||
"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
|
||||
},
|
||||
|
@ -743,9 +509,6 @@
|
|||
},
|
||||
"authenticate": {
|
||||
"color": "orange"
|
||||
},
|
||||
"offline": {
|
||||
"color": "grey"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -117,21 +117,6 @@ def is_authenticate(url):
|
|||
return False
|
||||
return False
|
||||
|
||||
|
||||
def is_offline(url):
|
||||
try:
|
||||
r = requests.get(url, timeout=5, headers=headers)
|
||||
if r.status_code >= 400:
|
||||
print(url + ' is ' + Fore.RED + 'offline' + Style.RESET_ALL)
|
||||
print("Status code")
|
||||
print(r.status_code)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def fetchCache(frontend, name):
|
||||
try:
|
||||
with open('./src/instances/data.json') as file:
|
||||
|
@ -457,9 +442,7 @@ def libreTranslate():
|
|||
|
||||
|
||||
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\/]+)*)\"\)")
|
||||
|
||||
fetchJsonList('breezeWiki', 'BreezeWiki', 'https://docs.breezewiki.com/files/instances.json', 'instance', False)
|
||||
|
||||
def privateBin():
|
||||
fetchJsonList('privateBin', 'PrivateBin',
|
||||
|
@ -524,7 +507,6 @@ mightyList = idnaEncode(mightyList)
|
|||
|
||||
cloudflare = []
|
||||
authenticate = []
|
||||
offline = []
|
||||
for k1, v1 in mightyList.items():
|
||||
if type(mightyList[k1]) is dict:
|
||||
for k2, v2 in mightyList[k1].items():
|
||||
|
@ -537,15 +519,12 @@ for k1, v1 in mightyList.items():
|
|||
cloudflare.append(instance)
|
||||
if not instance.endswith('.onion') and not instance.endswith('.i2p') and not instance.endswith('.loki') and is_authenticate(instance):
|
||||
authenticate.append(instance)
|
||||
elif not instance.endswith('.onion') and not instance.endswith('.i2p') and not instance.endswith('.loki') and is_offline(instance):
|
||||
offline.append(instance)
|
||||
|
||||
peertube()
|
||||
|
||||
blacklist = {
|
||||
'cloudflare': cloudflare,
|
||||
'authenticate': authenticate,
|
||||
'offline': offline
|
||||
}
|
||||
|
||||
# Writing to file
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"48": "assets/images/libredirect-48.png",
|
||||
"128": "assets/images/libredirect-128.png"
|
||||
},
|
||||
"permissions": ["webRequest", "webRequestBlocking", "storage", "unlimitedStorage", "cookies", "clipboardWrite", "contextMenus", "<all_urls>"],
|
||||
"permissions": ["webRequest", "webRequestBlocking", "storage", "unlimitedStorage", "clipboardWrite", "contextMenus", "<all_urls>"],
|
||||
"browser_action": {
|
||||
"default_title": "__MSG_extensionName__",
|
||||
"browser_style": false,
|
||||
|
@ -39,7 +39,7 @@
|
|||
"chrome_settings_overrides": {
|
||||
"search_provider": {
|
||||
"name": "__MSG_extensionName__",
|
||||
"keyword": "libredirect",
|
||||
"keyword": "@libredirect",
|
||||
"favicon_url": "https://raw.githubusercontent.com/libredirect/libredirect/master/src/assets/images/libredirect-16.png",
|
||||
"search_url": "https://search.libredirect.invalid/?q={searchTerms}",
|
||||
"encoding": "UTF-8",
|
||||
|
@ -58,12 +58,6 @@
|
|||
"default": "Alt+Shift+C"
|
||||
},
|
||||
"description": "Copies the original link. Ex: Copies the original twitter link while in the nitter website"
|
||||
},
|
||||
"unify": {
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+U"
|
||||
},
|
||||
"description": "Copies the preferences (cookies, localStorage) from the current opened instance and copy them to all the other selected instances"
|
||||
}
|
||||
},
|
||||
"default_locale": "en",
|
||||
|
|
|
@ -89,47 +89,9 @@ browser.tabs.onRemoved.addListener(tabId => {
|
|||
}
|
||||
})
|
||||
|
||||
async function redirectOfflineInstance(url, tabId) {
|
||||
let newUrl = await servicesHelper.switchInstance(url, true)
|
||||
|
||||
if (newUrl) {
|
||||
if (counter >= 5) {
|
||||
browser.tabs.update(tabId, {
|
||||
url: `/pages/errors/instance_offline.html?url=${encodeURIComponent(newUrl)}`,
|
||||
})
|
||||
counter = 0
|
||||
} else {
|
||||
browser.tabs.update(tabId, { url: newUrl })
|
||||
counter++
|
||||
}
|
||||
}
|
||||
}
|
||||
let counter = 0
|
||||
|
||||
function isAutoRedirect() {
|
||||
return new Promise(resolve => browser.storage.local.get("options", r => resolve(r.options.autoRedirect == true)))
|
||||
}
|
||||
|
||||
browser.webRequest.onResponseStarted.addListener(
|
||||
async details => {
|
||||
if (!(await isAutoRedirect())) return null
|
||||
if (details.type == "main_frame" && details.statusCode >= 500) redirectOfflineInstance(new URL(details.url), details.tabId)
|
||||
},
|
||||
{ urls: ["<all_urls>"] }
|
||||
)
|
||||
|
||||
browser.webRequest.onErrorOccurred.addListener(
|
||||
async details => {
|
||||
if (!(await isAutoRedirect())) return
|
||||
if (details.type == "main_frame") redirectOfflineInstance(new URL(details.url), details.tabId)
|
||||
},
|
||||
{ urls: ["<all_urls>"] }
|
||||
)
|
||||
|
||||
browser.commands.onCommand.addListener(command => {
|
||||
if (command === "switchInstance") utils.switchInstance()
|
||||
else if (command == "copyRaw") utils.copyRaw()
|
||||
else if (command == "unify") utils.unify()
|
||||
})
|
||||
|
||||
browser.contextMenus.create({
|
||||
|
@ -150,26 +112,6 @@ browser.contextMenus.create({
|
|||
contexts: ["browser_action"],
|
||||
})
|
||||
|
||||
browser.contextMenus.create({
|
||||
id: "unify",
|
||||
title: browser.i18n.getMessage("unifySettings"),
|
||||
contexts: ["browser_action"],
|
||||
})
|
||||
|
||||
try {
|
||||
browser.contextMenus.create({
|
||||
id: "toggleTab",
|
||||
title: browser.i18n.getMessage("toggleTab"),
|
||||
contexts: ["page", "tab"],
|
||||
})
|
||||
} catch {
|
||||
browser.contextMenus.create({
|
||||
id: "toggleTab",
|
||||
title: browser.i18n.getMessage("toggleTab"),
|
||||
contexts: ["page"],
|
||||
})
|
||||
}
|
||||
|
||||
browser.contextMenus.create({
|
||||
id: "redirectLink",
|
||||
title: browser.i18n.getMessage("redirectLink"),
|
||||
|
@ -207,10 +149,6 @@ browser.contextMenus.onClicked.addListener((info, tab) => {
|
|||
utils.copyRaw()
|
||||
resolve()
|
||||
return
|
||||
case "unify":
|
||||
utils.unify()
|
||||
resolve()
|
||||
return
|
||||
case "toggleTab":
|
||||
if (tabIdRedirects[tab.id] != undefined) {
|
||||
tabIdRedirects[tab.id] = !tabIdRedirects[tab.id]
|
||||
|
@ -254,8 +192,3 @@ browser.webRequest.onHeadersReceived.addListener(
|
|||
{ urls: ["<all_urls>"] },
|
||||
["blocking", "responseHeaders"]
|
||||
)
|
||||
|
||||
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.function === "unify") utils.unify(false).then(r => sendResponse({ response: r }))
|
||||
return true
|
||||
})
|
||||
|
|
|
@ -1,39 +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__">Instance is offline</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 {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<p id="message">
|
||||
<span data-localise="__MSG_instanceOffline__">This instance is offline, you'll be redirected after</span>
|
||||
<span id="number">2</span> <x data-localise="__MSG_sec__">seconds</x>
|
||||
</p>
|
||||
<button id="cancel" data-localise="__MSG_cancel__">Cancel</button>
|
||||
</div>
|
||||
|
||||
<script src="instance_offline.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,20 +0,0 @@
|
|||
import localise from "../../assets/javascripts/localise.js"
|
||||
|
||||
const params = new Proxy(new URLSearchParams(window.location.search), {
|
||||
get: (searchParams, prop) => searchParams.get(prop),
|
||||
})
|
||||
|
||||
let number = document.getElementById("number")
|
||||
setTimeout(() => (number.innerHTML = "1"), 1000)
|
||||
setTimeout(() => {
|
||||
number.innerHTML = "0"
|
||||
if (!isCanceled) window.location = params.url
|
||||
}, 2000)
|
||||
|
||||
let isCanceled = false
|
||||
document.getElementById("cancel").addEventListener("click", () => {
|
||||
isCanceled = true
|
||||
document.getElementById("message").innerHTML = browser.i18n.getMessage("redirectionCanceled")
|
||||
})
|
||||
|
||||
localise.localisePage()
|
|
@ -10,22 +10,22 @@
|
|||
|
||||
<div class="some-block option-block">
|
||||
<h4>Donate: ♥️</h4>
|
||||
<h4><a href='https://libredirect.codeberg.page/donate'>https://libredirect.codeberg.page/donate</a> </h4>
|
||||
<h4><a href='https://libredirect.codeberg.page/donate'>https://libredirect.github.io/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>
|
||||
<h4><a href='https://libredirect.codeberg.page/faq'>https://libredirect.github.io/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>
|
||||
<h4><a href='https://libredirect.codeberg.page/docs'>https://libredirect.github.io/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>
|
||||
<h4><a href='https://libredirect.codeberg.page/source_code'>https://libredirect.github.io/source_code</a></h4>
|
||||
</div>
|
||||
|
||||
<div class="some-block option-block">
|
||||
|
|
|
@ -13,37 +13,6 @@
|
|||
</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>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="some-block option-block">
|
||||
<h4 data-localise="__MSG_exclude_from_redirecting_">Excluded from redirecting</h4>
|
||||
</div>
|
||||
|
|
|
@ -121,37 +121,12 @@ resetSettings.addEventListener("click", async () => {
|
|||
})
|
||||
})
|
||||
|
||||
let autoRedirectElement = document.getElementById("auto-redirect")
|
||||
autoRedirectElement.addEventListener("change", event => {
|
||||
setOption("autoRedirect", "checkbox", event)
|
||||
})
|
||||
|
||||
let themeElement = document.getElementById("theme")
|
||||
themeElement.addEventListener("change", event => {
|
||||
setOption("theme", "select", event)
|
||||
location.reload()
|
||||
})
|
||||
|
||||
let networkElement = document.getElementById("network")
|
||||
networkElement.addEventListener("change", event => {
|
||||
setOption("network", "select", event)
|
||||
location.reload()
|
||||
})
|
||||
|
||||
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 => {
|
||||
setOption("latencyThreshold", "range", event)
|
||||
})
|
||||
latencyInput.addEventListener("input", event => {
|
||||
latencyOutput.value = event.target.value
|
||||
})
|
||||
|
||||
let nameCustomInstanceInput = document.getElementById("exceptions-custom-instance")
|
||||
let instanceTypeElement = document.getElementById("exceptions-custom-instance-type")
|
||||
let instanceType = "url"
|
||||
|
@ -173,20 +148,9 @@ for (const service in config.services) {
|
|||
}
|
||||
|
||||
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
|
||||
|
||||
//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") {
|
||||
|
@ -204,7 +168,7 @@ browser.storage.local.get("options", r => {
|
|||
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"
|
||||
<svg xmlns="https://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px"
|
||||
fill="currentColor">
|
||||
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||
</svg>
|
||||
|
|
|
@ -44,16 +44,6 @@
|
|||
<% 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="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>
|
||||
|
||||
<x data-localise="__MSG_testInstancesLatency__">Test Instances Latency</x>
|
||||
</label>
|
||||
<input class="button button-inline" id="latency-<%= frontend %>" style="display: none" />
|
||||
</div>
|
||||
<div class="<%= network %>">
|
||||
<div class="some-block option-block">
|
||||
<h4 data-localise="__MSG_defaultInstances__">Default Instances</h4>
|
||||
|
|
|
@ -108,7 +108,6 @@ for (const service in config.services) {
|
|||
for (const network in config.networks) {
|
||||
utils.processDefaultCustomInstances(service, frontend, network, document)
|
||||
}
|
||||
utils.latency(service, frontend, document, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="../stylesheets/styles.css" rel="stylesheet">
|
||||
<link href="./style.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body dir="auto">
|
||||
<div class="current_site">
|
||||
<div class="some-block" id="instance-div"><a class="title prevent">
|
||||
<%- include('src/assets/images/instance-icon.svg', {services: services}) -%>
|
||||
<h4 id="instance"></h4>
|
||||
</a>
|
||||
<span id="end"><input type="checkbox" id="instance-enabled"/></span>
|
||||
</div>
|
||||
<%- include('src/pages/widgets/switches', {services: services}) -%>
|
||||
<div id="current_site_divider">
|
||||
<hr>
|
||||
|
@ -23,33 +19,29 @@
|
|||
<%- include('src/pages/widgets/switches', {services: services}) -%>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="some-block" id="change_instance_div"><a class="title button prevent" id="change_instance">
|
||||
<div class="some-block" id="change_instance_div">
|
||||
<a class="title button prevent" id="change_instance">
|
||||
<h4 data-localise="__MSG_switchInstance__">Change Instance</h4>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="26px" viewBox="0 0 24 24" width="26px" fill="currentColor">
|
||||
<path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"></path>
|
||||
</svg></a></div>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<div class="some-block" id="copy_raw_div" title="Copy the original redirected link"> <a class="title button prevent" id="copy_raw">
|
||||
<h4 data-localise="__MSG_copyRaw__">Copy Raw</h4>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
|
||||
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"></path>
|
||||
</svg></a></div>
|
||||
<div class="some-block" id="unify_div" title="Unify preferences across all selected instances"><a class="title button prevent" id="unify">
|
||||
<h4 data-localise="__MSG_unifySettings__">Unify Settings</h4>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
|
||||
<path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path>
|
||||
</svg></a></div>
|
||||
</svg>
|
||||
</a></div>
|
||||
<div class="some-block"><a class="title button prevent" id="more-options">
|
||||
<h4 data-localise="__MSG_settings__">Settings</h4>
|
||||
<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></a></div>
|
||||
<div class="some-block"><a class="title button" id="about" href="/pages/options/index.html#about">
|
||||
<h4 data-localise="__MSG_about__">About</h4>
|
||||
<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></a></div>
|
||||
</svg>
|
||||
</a></div>
|
||||
<div class="space"></div>
|
||||
<script type="module" src="../options/init.js"></script>
|
||||
<script type="module" src="./popup.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -39,7 +39,6 @@ const currSite = document.getElementsByClassName("current_site")[0]
|
|||
|
||||
function setDivs() {
|
||||
return new Promise(resolve => {
|
||||
divs.instance = document.getElementById("instance")
|
||||
for (const service in config.services) {
|
||||
divs[service] = {}
|
||||
divs[service].toggle = {}
|
||||
|
@ -58,7 +57,6 @@ const currentSiteIsFrontend = document.getElementById("current_site_divider")
|
|||
|
||||
browser.storage.local.get(["options", "redirects"], r => {
|
||||
browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
|
||||
document.getElementById("instance-div").classList.add("hide")
|
||||
for (const service in config.services) {
|
||||
if (!r.options.popupServices.includes(service)) allSites.getElementsByClassName(service)[0].classList.add("hide")
|
||||
else allSites.getElementsByClassName(service)[0].classList.remove("hide")
|
||||
|
@ -75,7 +73,6 @@ browser.storage.local.get(["options", "redirects"], r => {
|
|||
url = new URL(tabs[0].url)
|
||||
} catch {
|
||||
currentSiteIsFrontend.classList.add("hide")
|
||||
document.getElementById("unify_div").style.display = "none"
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -89,51 +86,11 @@ browser.storage.local.get(["options", "redirects"], r => {
|
|||
service = service[0]
|
||||
let isCustom = false
|
||||
for (const network in config.networks) if (r.options[frontend][network].custom.indexOf(instance) > -1) isCustom = true
|
||||
if (!isCustom) {
|
||||
divs.instance.innerHTML = instance.replace(/https?:\/{2}/, "")
|
||||
let tmp
|
||||
let instanceNetwork
|
||||
for (const network in config.networks) {
|
||||
tmp = r.redirects[frontend][network].indexOf(instance)
|
||||
if (tmp > -1) {
|
||||
const instanceDiv = document.getElementById("instance-enabled")
|
||||
tmp = r.options[frontend][network].enabled.indexOf(instance)
|
||||
if (tmp > -1) instanceDiv.checked = true
|
||||
else instanceDiv.checked = false
|
||||
instanceNetwork = network
|
||||
instanceDiv.addEventListener("change", () => {
|
||||
browser.storage.local.get("options", r => {
|
||||
// Although options would be available in this context, it is fetched again to make sure it is up to date
|
||||
let options = r.options
|
||||
if (instanceDiv.checked) options[frontend][instanceNetwork].enabled.push(instance)
|
||||
else options[frontend][instanceNetwork].enabled.splice(options[frontend][instanceNetwork].enabled.indexOf(instance), 1)
|
||||
browser.storage.local.set({ options })
|
||||
})
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
document.getElementById("instance-div").classList.remove("hide")
|
||||
}
|
||||
}
|
||||
divs[service].current.classList.remove("hide")
|
||||
divs[service].all.classList.add("hide")
|
||||
if (frontend && config.services[service].frontends[frontend].preferences && !config.services[service].frontends[frontend].preferences.token) {
|
||||
const unify = document.getElementById("unify")
|
||||
const textElement = document.getElementById("unify").getElementsByTagName("h4")[0]
|
||||
unify.addEventListener("click", () => {
|
||||
const oldHtml = textElement.innerHTML
|
||||
textElement.innerHTML = "..."
|
||||
browser.runtime.sendMessage({ function: "unify" }, response => {
|
||||
if (response && response.response) textElement.innerHTML = oldHtml
|
||||
})
|
||||
})
|
||||
} else {
|
||||
document.getElementById("unify_div").style.display = "none"
|
||||
}
|
||||
} else {
|
||||
currentSiteIsFrontend.classList.add("hide")
|
||||
document.getElementById("unify_div").style.display = "none"
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue