2022-10-25 13:43:59 +02:00
|
|
|
import utils from "./utils.js"
|
|
|
|
|
2023-01-21 12:29:10 +01:00
|
|
|
window.browser = window.browser || window.chrome
|
|
|
|
|
2023-01-18 16:14:00 +01:00
|
|
|
let config, options
|
2022-10-25 13:43:59 +02:00
|
|
|
|
|
|
|
function init() {
|
|
|
|
return new Promise(async resolve => {
|
2023-01-21 12:29:10 +01:00
|
|
|
options = await utils.getOptions()
|
|
|
|
config = await utils.getConfig()
|
|
|
|
resolve()
|
2022-10-25 13:43:59 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
init()
|
|
|
|
browser.storage.onChanged.addListener(init)
|
|
|
|
|
2023-01-07 09:14:35 +01:00
|
|
|
function all(service, frontend, options, config) {
|
2022-10-25 13:43:59 +02:00
|
|
|
let instances = []
|
|
|
|
if (!frontend) {
|
|
|
|
for (const frontend in config.services[service].frontends) {
|
2023-01-07 09:14:35 +01:00
|
|
|
if (options[frontend]) {
|
|
|
|
instances.push(...options[frontend])
|
|
|
|
}
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
2023-01-21 12:29:10 +01:00
|
|
|
} else if (options[frontend]) {
|
|
|
|
instances = options[frontend]
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
|
|
|
return instances
|
|
|
|
}
|
|
|
|
|
2022-11-12 10:51:58 +01:00
|
|
|
function regexArray(service, url, config, frontend) {
|
2023-01-18 16:14:00 +01:00
|
|
|
let targetList = config.services[service].targets
|
2023-01-22 18:44:36 +01:00
|
|
|
if (frontend && config.services[service].frontends[frontend].excludeTargets) {
|
|
|
|
targetList = targetList.filter(val =>
|
|
|
|
!config.services[service].frontends[frontend].excludeTargets.includes(targetList.indexOf(val))
|
|
|
|
)
|
|
|
|
}
|
2023-01-18 16:14:00 +01:00
|
|
|
for (const targetString in targetList) {
|
|
|
|
const target = new RegExp(targetList[targetString])
|
|
|
|
if (target.test(url.href)) return true
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2023-01-22 18:44:36 +01:00
|
|
|
function redirect(url, type, initiator, forceRedirection) {
|
2022-11-12 09:54:34 +01:00
|
|
|
if (type != "main_frame" && type != "sub_frame" && type != "image") return
|
2022-10-25 13:43:59 +02:00
|
|
|
let randomInstance
|
|
|
|
let frontend
|
|
|
|
for (const service in config.services) {
|
|
|
|
if (!forceRedirection && !options[service].enabled) continue
|
|
|
|
|
2022-12-31 09:01:50 +01:00
|
|
|
frontend = options[service].frontend ?? Object.keys(config.services[service].frontends)[0]
|
2022-10-25 13:43:59 +02:00
|
|
|
|
2023-02-04 21:16:36 +01:00
|
|
|
if (!regexArray(service, url, config, frontend)) {
|
|
|
|
frontend = null
|
|
|
|
continue
|
|
|
|
}
|
2022-11-12 10:51:58 +01:00
|
|
|
|
2023-02-09 00:18:03 +01:00
|
|
|
if (
|
|
|
|
(config.services[service].embeddable && type != options[service].redirectType && options[service].redirectType != "both")
|
|
|
|
||
|
|
|
|
(!config.services[service].embeddable && type != "main_frame")
|
|
|
|
) {
|
|
|
|
if (options[service].unsupportedUrls == 'block') return 'CANCEL'
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-02-06 16:05:15 +01:00
|
|
|
let instanceList = options[frontend]
|
|
|
|
if (instanceList === undefined) break
|
|
|
|
if (instanceList.length === 0) return
|
|
|
|
|
2023-01-23 10:54:45 +01:00
|
|
|
if (
|
|
|
|
initiator
|
|
|
|
&&
|
2023-02-06 16:05:15 +01:00
|
|
|
instanceList.includes(initiator.origin)
|
2023-01-23 10:54:45 +01:00
|
|
|
) return "BYPASSTAB"
|
2023-01-22 18:44:36 +01:00
|
|
|
|
2023-01-18 16:14:00 +01:00
|
|
|
randomInstance = utils.getRandomInstance(instanceList)
|
2023-01-07 10:33:38 +01:00
|
|
|
|
2022-10-25 13:43:59 +02:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
// Here is a (temperory) space for defining constants required in 2 or more switch cases.
|
|
|
|
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]
|
|
|
|
}
|
2023-02-05 10:03:24 +01:00
|
|
|
|
2023-02-04 21:16:36 +01:00
|
|
|
if (!frontend) return
|
|
|
|
|
2022-10-25 13:43:59 +02:00
|
|
|
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.
|
2023-02-05 10:03:24 +01:00
|
|
|
case "beatbump": {
|
2022-10-25 13:43:59 +02:00
|
|
|
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")
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "hyperpipe": {
|
2022-10-25 13:43:59 +02:00
|
|
|
return `${randomInstance}${url.pathname}${url.search}`.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/"))
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "lbryDesktop": {
|
2022-10-25 13:43:59 +02:00
|
|
|
return url.href.replace(/^https?:\/{2}odysee\.com\//, "lbry://").replace(/:(?=[a-zA-Z0-9])/g, "#")
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
2022-10-25 13:43:59 +02:00
|
|
|
case "searx":
|
|
|
|
case "searxng":
|
2022-12-08 09:59:06 +01:00
|
|
|
return `${randomInstance}/${url.search}`
|
2023-02-05 10:03:24 +01:00
|
|
|
case "whoogle": {
|
2022-12-08 09:59:06 +01:00
|
|
|
return `${randomInstance}/search${url.search}`
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "librex": {
|
2022-12-08 09:59:06 +01:00
|
|
|
return `${randomInstance}/search.php${url.search}`
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "send": {
|
2022-10-25 13:43:59 +02:00
|
|
|
return randomInstance
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "nitter": {
|
2022-10-25 13:43:59 +02:00
|
|
|
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}`
|
2022-12-27 16:01:24 +01:00
|
|
|
return `${randomInstance}${url.pathname}${search}#m`
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "yattee": {
|
2022-10-25 13:43:59 +02:00
|
|
|
return url.href.replace(/^https?:\/{2}/, "yattee://")
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "freetube": {
|
2022-10-25 13:43:59 +02:00
|
|
|
return `freetube://https://youtu.be${url.pathname}${url.search}`.replace(/watch\?v=/, "")
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
2023-02-25 09:45:55 +01:00
|
|
|
case "invidious":
|
|
|
|
case "piped":
|
|
|
|
case "pipedMaterial":
|
|
|
|
case "cloudtube": {
|
|
|
|
if (url.pathname == "/live_chat") {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`;
|
|
|
|
}
|
2023-02-07 18:46:39 +01:00
|
|
|
case "poketube": {
|
2023-02-25 09:45:55 +01:00
|
|
|
if (url.pathname == "/live_chat") {
|
|
|
|
return null;
|
|
|
|
}
|
2023-02-07 18:46:39 +01:00
|
|
|
if (url.pathname.startsWith('/channel')) {
|
|
|
|
const reg = /\/channel\/(.*)\/?$/.exec(url.pathname)
|
|
|
|
if (reg) {
|
|
|
|
const id = reg[1]
|
|
|
|
return `${randomInstance}/channel?id=${id}${url.search}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (/\/@[a-z]+\//.exec(url.pathname)) {
|
|
|
|
return randomInstance
|
|
|
|
}
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
}
|
2023-02-05 10:03:24 +01:00
|
|
|
case "simplyTranslate": {
|
2022-10-25 13:43:59 +02:00
|
|
|
return `${randomInstance}/${url.search}`
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "libreTranslate": {
|
2022-10-25 13:43:59 +02:00
|
|
|
return `${randomInstance}/${url.search}`
|
|
|
|
.replace(/(?<=\/?)sl/, "source")
|
|
|
|
.replace(/(?<=&)tl/, "target")
|
|
|
|
.replace(/(?<=&)text/, "q")
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
2022-10-25 13:43:59 +02:00
|
|
|
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()
|
2022-10-29 13:46:53 +02:00
|
|
|
xmlhttp.timeout = 5000
|
|
|
|
http.ontimeout = () => {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
http.onerror = () => {
|
|
|
|
return
|
|
|
|
}
|
2022-10-25 13:43:59 +02:00
|
|
|
xmlhttp.send()
|
2022-10-29 13:46:53 +02:00
|
|
|
http.onreadystatechange = () => {
|
|
|
|
if (xmlhttp.status === 200) {
|
|
|
|
const json = JSON.parse(xmlhttp.responseText)[0]
|
|
|
|
if (json) {
|
|
|
|
return [`${json.lat},${json.lon}`, `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}`]
|
|
|
|
}
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
2022-10-29 13:46:53 +02:00
|
|
|
console.info("Error: Status is " + xmlhttp.status)
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
2022-10-29 13:46:53 +02:00
|
|
|
xmlhttp.open("GET", `https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`, false)
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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()
|
2023-01-06 22:24:25 +01:00
|
|
|
// console.log("mapCentre", mapCentre)
|
|
|
|
// console.log("prefs", prefs)
|
|
|
|
// console.log("prefsEncoded", prefsEncoded)
|
2022-10-25 13:43:59 +02:00
|
|
|
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}`
|
|
|
|
}
|
|
|
|
}
|
2023-02-05 10:03:24 +01:00
|
|
|
case "lingva": {
|
2022-10-25 13:43:59 +02:00
|
|
|
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
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "breezeWiki": {
|
2023-02-03 08:30:19 +01:00
|
|
|
let wiki, urlpath = ""
|
|
|
|
if (url.hostname.match(/^[a-zA-Z0-9-]+\.(?:fandom|wikia)\.com/)) {
|
|
|
|
wiki = url.hostname.match(/^[a-zA-Z0-9-]+(?=\.(?:fandom|wikia)\.com)/)
|
2022-10-26 14:54:36 +02:00
|
|
|
if (wiki == "www" || !wiki) wiki = ""
|
2023-02-06 07:59:40 +01:00
|
|
|
else wiki = `/${wiki}`
|
2022-10-26 14:54:36 +02:00
|
|
|
urlpath = url.pathname
|
|
|
|
} else {
|
|
|
|
wiki = url.pathname.match(/(?<=wiki\/w:c:)[a-zA-Z0-9-]+(?=:)/)
|
|
|
|
if (!wiki) wiki = ""
|
|
|
|
else {
|
|
|
|
wiki = "/" + wiki + "/wiki/"
|
|
|
|
urlpath = url.pathname.match(/(?<=wiki\/w:c:[a-zA-Z0-9-]+:).+/)
|
|
|
|
}
|
|
|
|
}
|
2023-02-09 00:18:03 +01:00
|
|
|
if (url.href.search(/Special:Search\?query/) > -1) {
|
|
|
|
return `${randomInstance}${wiki}${urlpath}${url.search}`.replace(/Special:Search\?query/, "search?q").replace(/\/wiki/, "")
|
|
|
|
}
|
|
|
|
return `${randomInstance}${wiki}${urlpath}${url.search}`
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "rimgo": {
|
2023-02-09 00:18:03 +01:00
|
|
|
if (url.href.search(/^https?:\/{2}(?:[im]\.)?stack\./) > -1) {
|
|
|
|
return `${randomInstance}/stack${url.pathname}${url.search}`
|
|
|
|
}
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "libreddit": {
|
2022-10-25 13:43:59 +02:00
|
|
|
const subdomain = url.hostname.match(/^(?:(?:external-)?preview|i)(?=\.redd\.it)/)
|
|
|
|
if (!subdomain) return `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
switch (subdomain[0]) {
|
|
|
|
case "preview":
|
|
|
|
return `${randomInstance}/preview/pre${url.pathname}${url.search}`
|
|
|
|
case "external-preview":
|
|
|
|
return `${randomInstance}/preview/external-pre${url.pathname}${url.search}`
|
|
|
|
case "i":
|
|
|
|
return `${randomInstance}/img${url.pathname}`
|
|
|
|
}
|
2023-02-09 00:18:03 +01:00
|
|
|
return randomInstance
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
|
|
|
case "teddit": {
|
2022-10-25 13:43:59 +02:00
|
|
|
if (/^(?:(?:external-)?preview|i)\.redd\.it/.test(url.hostname)) {
|
|
|
|
if (url.search == "") return `${randomInstance}${url.pathname}?teddit_proxy=${url.hostname}`
|
|
|
|
else return `${randomInstance}${url.pathname}${url.search}&teddit_proxy=${url.hostname}`
|
|
|
|
}
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
2023-02-05 10:03:24 +01:00
|
|
|
}
|
2023-02-01 10:22:15 +01:00
|
|
|
case "neuters": {
|
|
|
|
const p = url.pathname
|
|
|
|
if (p.startsWith('/article/') || p.startsWith('/pf/') || p.startsWith('/arc/') || p.startsWith('/resizer/')) {
|
2023-02-06 07:59:40 +01:00
|
|
|
return null
|
2023-02-01 10:22:15 +01:00
|
|
|
}
|
2023-02-06 07:59:40 +01:00
|
|
|
return `${randomInstance}${p}`
|
2023-02-01 10:22:15 +01:00
|
|
|
}
|
2023-02-01 16:26:11 +01:00
|
|
|
case "dumb": {
|
2023-02-09 00:18:03 +01:00
|
|
|
if (url.pathname.endsWith('-lyrics')) {
|
|
|
|
return `${randomInstance}${url.pathname}`
|
|
|
|
}
|
2023-02-01 11:20:01 +01:00
|
|
|
}
|
2023-02-02 21:29:40 +01:00
|
|
|
case "ruralDictionary": {
|
2023-02-06 16:05:15 +01:00
|
|
|
if (!url.pathname.includes('/define.php') && !url.pathname.includes('/random.php') && url.pathname != '/') return
|
2023-02-02 21:29:40 +01:00
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
}
|
2023-02-04 21:16:36 +01:00
|
|
|
case "anonymousOverflow": {
|
|
|
|
if (!url.pathname.startsWith('/questions') && url.pathname != '/') return
|
2023-02-06 16:05:15 +01:00
|
|
|
const threadID = /\/(\d+)\/?$/.exec(url.pathname)
|
|
|
|
if (threadID) return `${randomInstance}/questions/${threadID[1]}${url.search}`
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
|
2023-02-04 21:16:36 +01:00
|
|
|
}
|
2023-02-05 10:03:24 +01:00
|
|
|
case "biblioReads": {
|
|
|
|
if (!url.pathname.startsWith('/book/show/') && url.pathname != '/') return
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
}
|
2023-02-05 10:34:06 +01:00
|
|
|
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]
|
2023-02-20 13:46:48 +01:00
|
|
|
return link + url.hash
|
2023-02-05 10:34:06 +01:00
|
|
|
}
|
2023-02-09 09:44:09 +01:00
|
|
|
case "proxiTok": {
|
|
|
|
if (url.pathname.startsWith('/email')) return
|
2023-02-04 21:16:36 +01:00
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
2023-02-06 17:31:28 +01:00
|
|
|
}
|
2023-02-10 02:17:16 +01:00
|
|
|
case "waybackClassic": {
|
|
|
|
const regex = /^\/\web\/[0-9]+\*\/(.*)/.exec(url.pathname)
|
|
|
|
if (regex) {
|
|
|
|
const link = regex[1]
|
|
|
|
return `${randomInstance}/cgi-bin/history.cgi?utf8=✓&q=${encodeURIComponent(link)}`
|
|
|
|
}
|
|
|
|
return `${randomInstance}`
|
|
|
|
}
|
2023-02-13 12:45:24 +01:00
|
|
|
case "gothub": {
|
|
|
|
const regex = /^\/(.*)\/(.*)\/(?:blob|tree)\/(.*)\/(.*)/.exec(url.pathname)
|
|
|
|
if (regex) {
|
|
|
|
const user = regex[1]
|
|
|
|
const repo = regex[2]
|
|
|
|
const branch = regex[3]
|
|
|
|
const path = regex[4]
|
|
|
|
return `${randomInstance}/file/${user}/${repo}/${branch}/${path}`
|
|
|
|
}
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
}
|
2023-02-14 12:34:47 +01:00
|
|
|
case "mikuIndividious": {
|
|
|
|
if (url.hostname == "bilibili.com" || url.hostname == "www.bilibili.com" || url.hostname == 'b23.tv') {
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
}
|
|
|
|
if (url.hostname == "space.bilibili.com") {
|
|
|
|
return `${randomInstance}/space${url.pathname}${url.search}`
|
|
|
|
}
|
|
|
|
}
|
2023-02-14 16:24:10 +01:00
|
|
|
case "tent": {
|
|
|
|
if (url.hostname == 'bandcamp.com' && url.pathname == '/search') {
|
|
|
|
const query = url.searchParams.get('q')
|
|
|
|
return `${randomInstance}/search.php?query=${encodeURIComponent(query)}`
|
|
|
|
}
|
|
|
|
if (url.hostname.endsWith('bandcamp.com')) {
|
|
|
|
const regex = /^(.*)\.bandcamp\.com/.exec(url.hostname)
|
|
|
|
const artist = regex[1]
|
|
|
|
if (url.pathname == '/') {
|
|
|
|
return `${randomInstance}/artist.php?name=${artist}`
|
|
|
|
} else {
|
|
|
|
const regex = /^\/(.*)\/(.*)/.exec(url.pathname)
|
|
|
|
if (regex) {
|
|
|
|
const type = regex[1]
|
|
|
|
const name = regex[2]
|
|
|
|
return `${randomInstance}/release.php?artist=${artist}&type=${type}&name=${name}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (url.hostname == 'f4.bcbits.com') {
|
|
|
|
const regex = /\/img\/(.*)/.exec(url.pathname)
|
|
|
|
const image = regex[1]
|
|
|
|
return `${randomInstance}/image.php?file=${image}`
|
|
|
|
}
|
|
|
|
if (url.hostname == 't4.bcbits.com') {
|
|
|
|
const regex = /\/stream\/(.*)\/(.*)\/(.*)/.exec(url.pathname)
|
|
|
|
if (regex) {
|
|
|
|
const directory = regex[1]
|
|
|
|
const format = regex[2]
|
|
|
|
const file = regex[3]
|
|
|
|
const token = url.searchParams.get('token')
|
|
|
|
return `${randomInstance}/audio.php/?directory=${directory}&format=${format}&file=${file}&token=${encodeURIComponent(token)}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-02-14 12:34:47 +01:00
|
|
|
default: {
|
|
|
|
return `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
}
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function computeService(url, returnFrontend) {
|
2023-01-21 12:29:10 +01:00
|
|
|
return new Promise(async resolve => {
|
|
|
|
const config = await utils.getConfig()
|
|
|
|
const options = await utils.getOptions()
|
|
|
|
for (const service in config.services) {
|
|
|
|
if (regexArray(service, url, config)) {
|
|
|
|
resolve(service)
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
for (const frontend in config.services[service].frontends) {
|
2023-01-23 10:54:45 +01:00
|
|
|
if (all(service, frontend, options, config).includes(utils.protocolHost(url))) {
|
2023-01-22 18:44:36 +01:00
|
|
|
if (returnFrontend)
|
|
|
|
resolve([service, frontend, utils.protocolHost(url)])
|
|
|
|
else
|
|
|
|
resolve(service)
|
2023-01-21 12:29:10 +01:00
|
|
|
return
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
2023-01-21 12:29:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
resolve()
|
2022-10-25 13:43:59 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-02-08 09:28:57 +01:00
|
|
|
function switchInstance(url) {
|
2022-10-25 13:43:59 +02:00
|
|
|
return new Promise(async resolve => {
|
2023-02-08 09:28:57 +01:00
|
|
|
let options = await utils.getOptions()
|
|
|
|
let config = await utils.getConfig()
|
|
|
|
|
2022-10-25 13:43:59 +02:00
|
|
|
const protocolHost = utils.protocolHost(url)
|
|
|
|
for (const service in config.services) {
|
2023-01-23 10:54:45 +01:00
|
|
|
let frontend = options[service].frontend ?? Object.keys(config.services[service].frontends)[0]
|
|
|
|
let instancesList = [...options[frontend]]
|
|
|
|
if (!instancesList.includes(protocolHost)) continue
|
2023-01-24 09:24:02 +01:00
|
|
|
|
2023-01-23 10:54:45 +01:00
|
|
|
instancesList.splice(instancesList.indexOf(protocolHost), 1)
|
2022-10-25 13:43:59 +02:00
|
|
|
if (instancesList.length === 0) {
|
|
|
|
resolve()
|
|
|
|
return
|
|
|
|
}
|
2023-01-23 10:54:45 +01:00
|
|
|
|
2022-10-25 13:43:59 +02:00
|
|
|
const randomInstance = utils.getRandomInstance(instancesList)
|
2023-01-22 18:44:36 +01:00
|
|
|
const newUrl = `${randomInstance}${url.pathname}${url.search}`
|
|
|
|
resolve(newUrl)
|
2022-10-25 13:43:59 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
resolve()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-01-24 09:24:02 +01:00
|
|
|
function reverse(url) {
|
2022-10-25 13:43:59 +02:00
|
|
|
return new Promise(async resolve => {
|
2023-02-08 09:28:57 +01:00
|
|
|
let options = await utils.getOptions()
|
|
|
|
let config = await utils.getConfig()
|
|
|
|
|
2023-01-23 10:54:45 +01:00
|
|
|
let protocolHost = utils.protocolHost(url)
|
2022-10-25 13:43:59 +02:00
|
|
|
for (const service in config.services) {
|
2023-01-23 10:54:45 +01:00
|
|
|
let frontend = options[service].frontend ?? Object.keys(config.services[service].frontends)[0]
|
2023-01-24 09:24:02 +01:00
|
|
|
if (!options[frontend].includes(protocolHost)) continue
|
2022-10-25 13:43:59 +02:00
|
|
|
|
|
|
|
switch (service) {
|
|
|
|
case "youtube":
|
|
|
|
case "imdb":
|
|
|
|
case "imgur":
|
|
|
|
case "tiktok":
|
|
|
|
case "twitter":
|
|
|
|
case "reddit":
|
|
|
|
case "imdb":
|
|
|
|
case "quora":
|
|
|
|
case "medium":
|
2023-01-22 18:44:36 +01:00
|
|
|
resolve(config.services[service].url + url.pathname + url.search)
|
|
|
|
return
|
2022-12-10 09:59:28 +01:00
|
|
|
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
|
2022-10-25 13:43:59 +02:00
|
|
|
default:
|
|
|
|
resolve()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
resolve()
|
2023-01-22 18:44:36 +01:00
|
|
|
return
|
2022-10-25 13:43:59 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-02-05 19:42:19 +01:00
|
|
|
const defaultInstances = {
|
|
|
|
'invidious': ['https://inv.vern.cc'],
|
|
|
|
'piped': ['https://pipedapi-libre.kavin.rocks'],
|
|
|
|
'pipedMaterial': ['https://piped-material.xn--17b.net'],
|
|
|
|
'cloudtube': ['https://tube.cadence.moe'],
|
2023-02-07 18:46:39 +01:00
|
|
|
'poketube': ['https://poketube.fun'],
|
2023-02-05 19:42:19 +01:00
|
|
|
'proxiTok': ['https://proxitok.pabloferreiro.es'],
|
|
|
|
'send': ['https://send.vis.ee'],
|
|
|
|
'nitter': ['https://nitter.net'],
|
|
|
|
'libreddit': ['https://libreddit.spike.codes'],
|
|
|
|
'teddit': ['https://teddit.net'],
|
|
|
|
'scribe': ['https://scribe.rip'],
|
|
|
|
'libMedium': ['https://md.vern.cc'],
|
|
|
|
'quetre': ['https://quetre.iket.me'],
|
|
|
|
'libremdb': ['https://libremdb.iket.me'],
|
|
|
|
'simplyTranslate': ['https://simplytranslate.org'],
|
|
|
|
'lingva': ['https://lingva.ml'],
|
|
|
|
'searxng': ['https://sx.vern.cc'],
|
|
|
|
'rimgo': ['https://rimgo.vern.cc'],
|
|
|
|
'librarian': ['https://lbry.vern.cc'],
|
|
|
|
'beatbump': ['https://beatbump.ml'],
|
|
|
|
'hyperpipe': ['https://hyperpipe.surge.sh'],
|
|
|
|
'facil': [' https://facilmap.org '],
|
|
|
|
'osm': ['https://www.openstreetmap.org'],
|
|
|
|
'breezeWiki': ['https://breezewiki.com'],
|
|
|
|
'neuters': ['https://neuters.de'],
|
|
|
|
'dumb': ['https://dm.vern.cc'],
|
|
|
|
'ruralDictionary': ['https://rd.vern.cc'],
|
|
|
|
'anonymousOverflow': ['https://code.whatever.social'],
|
|
|
|
'biblioReads': ['https://biblioreads.ml'],
|
|
|
|
'wikiless': ['https://wikiless.org'],
|
2023-02-10 02:17:16 +01:00
|
|
|
'suds': ['https://sd.vern.cc'],
|
2023-02-13 12:45:24 +01:00
|
|
|
'waybackClassic': ['https://wayback-classic.net'],
|
2023-02-14 12:34:47 +01:00
|
|
|
'gothub': ['https://gh.odyssey346.dev'],
|
|
|
|
'mikuIndividious': ['https://mikuinv.resrv.org'],
|
2023-02-19 14:06:00 +01:00
|
|
|
"tent": ['https://tent.sny.sh'],
|
|
|
|
"wolfreeAlpha": ['https://gqq.gitlab.io', 'https://uqq.gitlab.io']
|
2023-02-05 19:42:19 +01:00
|
|
|
}
|
|
|
|
|
2023-01-06 22:24:25 +01:00
|
|
|
function initDefaults() {
|
2022-10-25 13:43:59 +02:00
|
|
|
return new Promise(resolve => {
|
2023-01-21 12:29:10 +01:00
|
|
|
browser.storage.local.clear(async () => {
|
|
|
|
let config = await utils.getConfig()
|
|
|
|
let options = {}
|
|
|
|
for (const service in config.services) {
|
|
|
|
options[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] = []
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
2023-01-21 12:29:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
options['exceptions'] = {
|
|
|
|
url: [],
|
|
|
|
regex: [],
|
|
|
|
}
|
|
|
|
options['theme'] = "detect"
|
|
|
|
options['popupServices'] = ["youtube", "twitter", "tiktok", "imgur", "reddit", "quora", "translate", "maps"]
|
2023-02-08 13:51:07 +01:00
|
|
|
options['fetchInstances'] = 'github'
|
2023-01-18 16:14:00 +01:00
|
|
|
|
2023-02-05 19:42:19 +01:00
|
|
|
options = { ...options, ...defaultInstances }
|
2023-01-22 18:44:36 +01:00
|
|
|
|
2023-01-21 12:29:10 +01:00
|
|
|
browser.storage.local.set({ options },
|
|
|
|
() => resolve()
|
|
|
|
)
|
|
|
|
})
|
2023-01-18 16:14:00 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-10-25 13:43:59 +02:00
|
|
|
function upgradeOptions() {
|
2023-01-21 12:29:10 +01:00
|
|
|
return new Promise(async resolve => {
|
|
|
|
const oldOptions = await utils.getOptions()
|
2023-02-09 00:18:03 +01:00
|
|
|
const config = await utils.getConfig()
|
2023-01-21 12:29:10 +01:00
|
|
|
|
|
|
|
let options = {}
|
2023-02-08 13:51:07 +01:00
|
|
|
options = [...oldOptions]
|
|
|
|
options.fetchInstances = 'github'
|
2023-01-21 12:29:10 +01:00
|
|
|
|
2023-02-09 00:18:03 +01:00
|
|
|
for (service in config.services) {
|
|
|
|
options[service].unsupportedUrls = 'bypass'
|
|
|
|
}
|
|
|
|
|
2023-01-21 12:29:10 +01:00
|
|
|
browser.storage.local.clear(() => {
|
|
|
|
browser.storage.local.set({ options }, () => {
|
|
|
|
resolve()
|
2022-10-25 13:43:59 +02:00
|
|
|
})
|
2023-01-21 12:29:10 +01:00
|
|
|
})
|
2022-10-25 13:43:59 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function processUpdate() {
|
2023-01-21 12:29:10 +01:00
|
|
|
return new Promise(async resolve => {
|
|
|
|
let config = await utils.getConfig()
|
|
|
|
let options = await utils.getOptions()
|
|
|
|
for (const service in config.services) {
|
|
|
|
if (!options[service]) options[service] = {}
|
|
|
|
for (const defaultOption in config.services[service].options) {
|
|
|
|
if (options[service][defaultOption] === undefined) {
|
|
|
|
options[service][defaultOption] = config.services[service].options[defaultOption]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const frontend in config.services[service].frontends) {
|
|
|
|
if (options[frontend] === undefined && config.services[service].frontends[frontend].instanceList) {
|
2023-02-05 19:42:19 +01:00
|
|
|
options[frontend] = defaultInstances[frontend]
|
2023-01-21 12:29:10 +01:00
|
|
|
}
|
2023-02-05 19:42:19 +01:00
|
|
|
else if (frontend in options && !(frontend in config.services[service].frontends)) {
|
2023-01-21 12:29:10 +01:00
|
|
|
delete options[frontend]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
browser.storage.local.set({ options }, () => {
|
|
|
|
resolve()
|
|
|
|
})
|
2022-10-25 13:43:59 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// For websites that have a strict policy that would not normally allow these frontends to be embedded within the website.
|
|
|
|
function modifyContentSecurityPolicy(details) {
|
|
|
|
let isChanged = false
|
|
|
|
if (details.type == "main_frame") {
|
|
|
|
for (const header in details.responseHeaders) {
|
|
|
|
if (details.responseHeaders[header].name == "content-security-policy") {
|
|
|
|
let instancesList = []
|
|
|
|
for (const service in config.services) {
|
|
|
|
if (config.services[service].embeddable) {
|
|
|
|
for (const frontend in config.services[service].frontends) {
|
|
|
|
if (config.services[service].frontends[frontend].embeddable) {
|
|
|
|
for (const network in config.networks) {
|
2023-01-06 22:24:25 +01:00
|
|
|
instancesList.push(...options[frontend])
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let securityPolicyList = details.responseHeaders[header].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 + "; "
|
|
|
|
}
|
|
|
|
|
|
|
|
details.responseHeaders[header].value = newSecurity
|
|
|
|
isChanged = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isChanged) return { responseHeaders: details.responseHeaders }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-08 09:28:57 +01:00
|
|
|
async function copyRaw(url, test) {
|
|
|
|
const newUrl = await reverse(url)
|
|
|
|
if (newUrl) {
|
|
|
|
if (!test) {
|
|
|
|
navigator.clipboard.writeText(newUrl)
|
|
|
|
}
|
|
|
|
return newUrl
|
|
|
|
}
|
2023-01-21 12:29:10 +01:00
|
|
|
}
|
|
|
|
|
2022-10-25 13:43:59 +02:00
|
|
|
export default {
|
|
|
|
redirect,
|
|
|
|
computeService,
|
|
|
|
reverse,
|
|
|
|
initDefaults,
|
|
|
|
upgradeOptions,
|
|
|
|
processUpdate,
|
|
|
|
modifyContentSecurityPolicy,
|
2023-01-21 12:29:10 +01:00
|
|
|
copyRaw,
|
|
|
|
switchInstance
|
2022-10-25 13:43:59 +02:00
|
|
|
}
|