about summary refs log tree commit diff stats
path: root/src/assets
diff options
context:
space:
mode:
authorHygna <hygna@proton.me>2022-09-09 15:55:33 +0100
committerHygna <hygna@proton.me>2022-09-09 15:55:33 +0100
commit4cab752e05dd479c4c3da7c06c276de51ca9f637 (patch)
tree8f42c2edea9aca343d5d8cf4f2e813a79d6f0d9f /src/assets
parentMake redirect not return on a single instance frontend (diff)
downloadlibredirect-4cab752e05dd479c4c3da7c06c276de51ca9f637.zip
All irregular url structures completed
Diffstat (limited to 'src/assets')
-rw-r--r--src/assets/javascripts/services.js259
1 files changed, 253 insertions, 6 deletions
diff --git a/src/assets/javascripts/services.js b/src/assets/javascripts/services.js
index 973e44b4..9c880432 100644
--- a/src/assets/javascripts/services.js
+++ b/src/assets/javascripts/services.js
@@ -6,11 +6,13 @@ let config
 

 function getConfig() {

 	return new Promise(async resolve => {

+		let data

 		fetch("/config/config.json")

 			.then(response => response.text())

 			.then(data => {

-				config = JSON.parse(data)

+				data = JSON.parse(data)

 			})

+		config = data

 		resolve()

 	})

 }

@@ -25,7 +27,6 @@ function init() {
 			networkFallback = r.networkFallback

 		})

 		//cur = current

-		getConfig()

 		for (service in config.services) {

 			redirects = {}

 			browser.storage.local.get([`disable${camelCase(service)}`, `${service}Redirects`, `${service}RedirectType,`, `${service}Frontend`], r => {

@@ -46,6 +47,8 @@ function init() {
 	})

 }

 

+getConfig()

+console.log(config)

 init()

 browser.storage.onChanged.addListener(init)

 

@@ -54,9 +57,13 @@ function redirect(url, type, initiator) {
 	if (url.pathname == "/") return

 	for (service in config.services) {

 		if (disabled && !disableOverride) continue

+		let targets = service.targets

+		if (targets == "datajson") {

+			browser.storage.local.get(`${service}Targets`, (targets = r[service + "Targets"]))

+		}

+

 		if (initiator && (all().includes(initiator.origin) || targets.includes(initiator.host))) continue

-		//if (!targets.some(rx => rx.test(url.href))) continue

-		if (!target.test(url)) continue

+		if (!targets.some(rx => rx.test(url.href))) continue

 		if (type != redirectType && type != "both") continue

 		browser.storage.local.get(`${service}Frontend`, (frontend = r[service + "Frontend"]))

 		let instanceList = redirects[frontend][curNetwork]

@@ -64,6 +71,26 @@ function redirect(url, type, initiator) {
 		if (instanceList.length === 0 && redirects.indexOf(frontend) != -1) return

 		randomInstance = utils.getRandomInstance(instanceList)

 	}

+

+	// Here is a (temperory) space for defining constants required in 2 or more switch cases.

+	// When possible, try have the two switch cases share all their code as done with searx and searxng.

+	// Do not do that when they do not share 100% of their code.

+

+	const mapCentreRegex = /@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/

+	const dataLatLngRegex = /!3d(-?[0-9]{1,}.[0-9]{1,})!4d(-?[0-9]{1,}.[0-9]{1,})/

+	const placeRegex = /\/place\/(.*)\//

+	function convertMapCentre() {

+		let [, lat, lon, zoom] = 0

+		if (url.pathname.match(mapCentreRegex)) {

+			// Set map centre if present

+			;[, lat, lon, zoom] = url.pathname.match(mapCentreRegex)

+		} else if (url.searchParams.has("center")) {

+			;[lat, lon] = url.searchParams.get("center").split(",")

+			zoom = url.searchParams.get("zoom") ?? "17"

+		}

+		return [zoom, lon, lat]

+	}

+

 	switch (frontend) {

 		// This is where all instance-specific code must be ran to convert the service url to one that can be understood by the frontend.

 		case "beatbump":

@@ -108,9 +135,229 @@ function redirect(url, type, initiator) {
 			return `freetube://https://youtube.com${url.pathname}${url.search}`

 		case "simplyTranslate":

 			return `${randomInstance}/${url.search}`

+		case "osm": {

+			if (initiator && initiator.host === "earth.google.com") return

+			travelModes = {

+				driving: "fossgis_osrm_car",

+				walking: "fossgis_osrm_foot",

+				bicycling: "fossgis_osrm_bike",

+				transit: "fossgis_osrm_car", // not implemented on OSM, default to car.

+			}

+

+			function addressToLatLng(address) {

+				const xmlhttp = new XMLHttpRequest()

+				xmlhttp.open("GET", `https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`, false)

+				xmlhttp.send()

+				if (xmlhttp.status === 200) {

+					const json = JSON.parse(xmlhttp.responseText)[0]

+					if (json) {

+						console.log("json", json)

+						return [`${json.lat},${json.lon}`, `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}`]

+					}

+				}

+				console.info("Error: Status is " + xmlhttp.status)

+			}

+

+			let mapCentre = "#"

+			let prefs = {}

+

+			const mapCentreData = convertMapCentre()

+			if (mapCentreData[0] && mapCentreData[1] && mapCentreData[2]) mapCentre = `#map=${mapCentreData[0]}/${mapCentreData[1]}/${mapCentreData[2]}`

+			if (url.searchParams.get("layer")) prefs.layers = osmLayers[url.searchParams.get("layer")]

+

+			if (url.pathname.includes("/embed")) {

+				// Handle Google Maps Embed API

+				// https://www.google.com/maps/embed/v1/place?key=AIzaSyD4iE2xVSpkLLOXoyqT-RuPwURN3ddScAI&q=Eiffel+Tower,Paris+France

+				//console.log("embed life")

+

+				let query = ""

+				if (url.searchParams.has("q")) query = url.searchParams.get("q")

+				else if (url.searchParams.has("query")) query = url.searchParams.has("query")

+				else if (url.searchParams.has("pb"))

+					try {

+						query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1]

+					} catch (error) {

+						console.error(error)

+					} // Unable to find map marker in URL.

+

+				let [coords, boundingbox] = addressToLatLng(query)

+				prefs.bbox = boundingbox

+				prefs.marker = coords

+				prefs.layer = "mapnik"

+				let prefsEncoded = new URLSearchParams(prefs).toString()

+				return `${randomInstance}/export/embed.html?${prefsEncoded}`

+			} else if (url.pathname.includes("/dir")) {

+				// Handle Google Maps Directions

+				// https://www.google.com/maps/dir/?api=1&origin=Space+Needle+Seattle+WA&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling

+

+				let travMod = url.searchParams.get("travelmode")

+				if (url.searchParams.has("travelmode")) prefs.engine = travelModes[travMod]

+

+				let orgVal = url.searchParams.get("origin")

+				let destVal = url.searchParams.get("destination")

+

+				let org

+				addressToLatLng(orgVal, a => (org = a))

+				let dest

+				addressToLatLng(destVal, a => (dest = a))

+				prefs.route = `${org};${dest}`

+

+				let prefsEncoded = new URLSearchParams(prefs).toString()

+				return `${randomInstance}/directions?${prefsEncoded}${mapCentre}`

+			} else if (url.pathname.includes("data=") && url.pathname.match(dataLatLngRegex)) {

+				// Get marker from data attribute

+				// https://www.google.com/maps/place/41%C2%B001'58.2%22N+40%C2%B029'18.2%22E/@41.032833,40.4862063,17z/data=!3m1!4b1!4m6!3m5!1s0x0:0xf64286eaf72fc49d!7e2!8m2!3d41.0328329!4d40.4883948

+				//console.log("data life")

+

+				let [, mlat, mlon] = url.pathname.match(dataLatLngRegex)

+

+				return `${randomInstance}/search?query=${mlat}%2C${mlon}`

+			} else if (url.searchParams.has("ll")) {

+				// Get marker from ll param

+				// https://maps.google.com/?ll=38.882147,-76.99017

+				//console.log("ll life")

+

+				const [mlat, mlon] = url.searchParams.get("ll").split(",")

+

+				return `${randomInstance}/search?query=${mlat}%2C${mlon}`

+			} else if (url.searchParams.has("viewpoint")) {

+				// Get marker from viewpoint param.

+				// https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.857832,2.295226&heading=-45&pitch=38&fov=80

+				//console.log("viewpoint life")

+

+				const [mlat, mlon] = url.searchParams.get("viewpoint").split(",")

+

+				return `${randomInstance}/search?query=${mlat}%2C${mlon}`

+			} else {

+				// Use query as search if present.

+				//console.log("normal life")

+

+				let query

+				if (url.searchParams.has("q")) query = url.searchParams.get("q")

+				else if (url.searchParams.has("query")) query = url.searchParams.get("query")

+				else if (url.pathname.match(placeRegex)) query = url.pathname.match(placeRegex)[1]

+

+				let prefsEncoded = new URLSearchParams(prefs).toString()

+				if (query) return `${randomInstance}/search?query="${query}${mapCentre}&${prefsEncoded}`

+			}

+

+			let prefsEncoded = new URLSearchParams(prefs).toString()

+			console.log("mapCentre", mapCentre)

+			console.log("prefs", prefs)

+			console.log("prefsEncoded", prefsEncoded)

+			return `${randomInstance}/${mapCentre}&${prefsEncoded}`

+		}

+		case "facil": {

+			if (initiator && initiator.host === "earth.google.com") return

+			let travelModes = {

+				driving: "car",

+				walking: "pedestrian",

+				bicycling: "bicycle",

+				transit: "car", // not implemented on Facil, default to car.

+			}

+			const mapCentreData = convertMapCentre()

+			let mapCentre = "#"

+			if (mapCentreData[0] && mapCentreData[1] && mapCentreData[2]) mapCentre = `#${mapCentreData[0]}/${mapCentreData[1]}/${mapCentreData[2]}`

+

+			if (url.pathname.includes("/embed")) {

+				// Handle Google Maps Embed API

+				// https://www.google.com/maps/embed/v1/place?key=AIzaSyD4iE2xVSpkLLOXoyqT-RuPwURN3ddScAI&q=Eiffel+Tower,Paris+France

+				//console.log("embed life")

+

+				let query = ""

+				if (url.searchParams.has("q")) query = url.searchParams.get("q")

+				else if (url.searchParams.has("query")) query = url.searchParams.has("query")

+				else if (url.searchParams.has("pb"))

+					try {

+						query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1]

+					} catch (error) {

+						console.error(error)

+					} // Unable to find map marker in URL.

+

+				return `${randomInstance}/#q=${query}`

+			} else if (url.pathname.includes("/dir")) {

+				// Handle Google Maps Directions

+				// https://www.google.com/maps/dir/?api=1&origin=Space+Needle+Seattle+WA&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling

+

+				let travMod = url.searchParams.get("travelmode")

+

+				let orgVal = url.searchParams.get("origin")

+				let destVal = url.searchParams.get("destination")

+

+				return `${randomInstance}/#q=${orgVal}%20to%20${destVal}%20by%20${travelModes[travMod]}`

+			} else if (url.pathname.includes("data=") && url.pathname.match(dataLatLngRegex)) {

+				// Get marker from data attribute

+				// https://www.google.com/maps/place/41%C2%B001'58.2%22N+40%C2%B029'18.2%22E/@41.032833,40.4862063,17z/data=!3m1!4b1!4m6!3m5!1s0x0:0xf64286eaf72fc49d!7e2!8m2!3d41.0328329!4d40.4883948

+				//console.log("data life")

+

+				let [, mlat, mlon] = url.pathname.match(dataLatLngRegex)

+

+				return `${randomInstance}/#q=${mlat}%2C${mlon}`

+			} else if (url.searchParams.has("ll")) {

+				// Get marker from ll param

+				// https://maps.google.com/?ll=38.882147,-76.99017

+				//console.log("ll life")

+

+				const [mlat, mlon] = url.searchParams.get("ll").split(",")

+

+				return `${randomInstance}/#q=${mlat}%2C${mlon}`

+			} else if (url.searchParams.has("viewpoint")) {

+				// Get marker from viewpoint param.

+				// https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.857832,2.295226&heading=-45&pitch=38&fov=80

+				//console.log("viewpoint life")

+

+				const [mlat, mlon] = url.searchParams.get("viewpoint").split(",")

+

+				return `${randomInstance}/#q=${mlat}%2C${mlon}`

+			} else {

+				// Use query as search if present.

+				//console.log("normal life")

+

+				let query

+				if (url.searchParams.has("q")) query = url.searchParams.get("q")

+				else if (url.searchParams.has("query")) query = url.searchParams.get("query")

+				else if (url.pathname.match(placeRegex)) query = url.pathname.match(placeRegex)[1]

+

+				if (query) return `${randomInstance}/${mapCentre}/Mpnk/${query}`

+			}

+		}

+		case "wikiless":

+			let GETArguments = []

+			if (url.search.length > 0) {

+				let search = url.search.substring(1) //get rid of '?'

+				let argstrings = search.split("&")

+				for (let i = 0; i < argstrings.length; i++) {

+					let args = argstrings[i].split("=")

+					GETArguments.push([args[0], args[1]])

+				}

+			}

+

+			let link = `${randomInstance}${url.pathname}`

+			let urlSplit = url.host.split(".")

+			if (urlSplit[0] != "wikipedia" && urlSplit[0] != "www") {

+				if (urlSplit[0] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])

+				else GETArguments.push(["lang", urlSplit[0]])

+				if (urlSplit[1] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])

+				// wikiless doesn't have mobile view support yet

+			}

+			for (let i = 0; i < GETArguments.length; i++) link += (i == 0 ? "?" : "&") + GETArguments[i][0] + "=" + GETArguments[i][1]

+			return link

+

+		case "lingva":

+			let params_arr = url.search.split("&")

+			params_arr[0] = params_arr[0].substring(1)

+			let params = {}

+			for (let i = 0; i < params_arr.length; i++) {

+				let pair = params_arr[i].split("=")

+				params[pair[0]] = pair[1]

+			}

+			if (params.sl && params.tl && params.text) {

+				return `${randomInstance}/${params.sl}/${params.tl}/${params.text}`

+			}

+			return randomInstance

 		default:

 			return `${randomInstance}${url.pathname}${url.search}`

-	} // TODO: Wikiless, All youtube frontends by changing regex, lingva

+	}

 }

 

 function initDefaults() {

@@ -124,7 +371,7 @@ function initDefaults() {
 					for (service in config.services) {

 						for (defaultOption in service.defaults) {

 							browser.storage.local.set({

-								[defaultOption]: defaultOption.value,

+								[defaultOption]: service.defaults[defaultOption],

 							})

 						}

 						for (frontend in service.frontends) {