about summary refs log tree commit diff stats
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
parentMake redirect not return on a single instance frontend (diff)
downloadlibredirect-4cab752e05dd479c4c3da7c06c276de51ca9f637.zip
All irregular url structures completed
-rw-r--r--src/assets/javascripts/services.js259
-rw-r--r--src/config/config.json2
-rw-r--r--src/pages/background/background.js499
3 files changed, 505 insertions, 255 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) {

diff --git a/src/config/config.json b/src/config/config.json
index db991772..3d4d3f8b 100644
--- a/src/config/config.json
+++ b/src/config/config.json
@@ -64,7 +64,7 @@
 			},

 			"singleInstanceFrontends": ["freetube", "yatte"],

 			"targets": [

-				"^https?:\\/{2}(www\\.|music\\.|m\\.|)youtube.com(\\/.*|$)",

+				"^https?:\\/{2}(www\\.|music\\.|m\\.|)youtube.com(\\(?!iframe_api)/.*|$)",

 				"^https?:\\/{2}img\\.youtube.com\\/vi\\/.*\\/..*",

 				"^https?:\\/{2}(i|s)\\.ytimg.com\\/vi\\/.*\\/..*",

 				"^https?:\\/{2}(www\\.|music\\.|)youtube.com\\/watch?v=..*",

diff --git a/src/pages/background/background.js b/src/pages/background/background.js
index 87d498e4..e93e3d03 100644
--- a/src/pages/background/background.js
+++ b/src/pages/background/background.js
@@ -1,248 +1,251 @@
-"use strict"
-
-import generalHelper from "../../assets/javascripts/general.js"
-import utils from "../../assets/javascripts/utils.js"
-
-import youtubeHelper from "../../assets/javascripts/youtube/youtube.js"
-import youtubeMusicHelper from "../../assets/javascripts/youtubeMusic.js"
-import twitterHelper from "../../assets/javascripts/twitter.js"
-import instagramHelper from "../../assets/javascripts/instagram.js"
-import redditHelper from "../../assets/javascripts/reddit.js"
-import searchHelper from "../../assets/javascripts/search.js"
-import translateHelper from "../../assets/javascripts/translate/translate.js"
-import mapsHelper from "../../assets/javascripts/maps.js"
-import wikipediaHelper from "../../assets/javascripts/wikipedia.js"
-import mediumHelper from "../../assets/javascripts/medium.js"
-import quoraHelper from "../../assets/javascripts/quora.js"
-import libremdbHelper from "../../assets/javascripts/imdb.js"
-import reutersHelper from "../../assets/javascripts/reuters.js"
-import imgurHelper from "../../assets/javascripts/imgur.js"
-import tiktokHelper from "../../assets/javascripts/tiktok.js"
-import sendTargetsHelper from "../../assets/javascripts/sendTargets.js"
-import peertubeHelper from "../../assets/javascripts/peertube.js"
-import lbryHelper from "../../assets/javascripts/lbry.js"
-
-import servicesHelper from "../../assets/javascripts/services.js"
-
-window.browser = window.browser || window.chrome
-
-browser.runtime.onInstalled.addListener(details => {
-	function initDefaults() {
-		fetch("/instances/blacklist.json")
-			.then(response => response.text())
-			.then(async data => {
-				browser.storage.local.clear(() => {
-					browser.storage.local.set({ cloudflareBlackList: JSON.parse(data).cloudflare }, () => {
-						browser.storage.local.set({ authenticateBlackList: JSON.parse(data).authenticate }, () => {
-							browser.storage.local.set({ offlineBlackList: JSON.parse(data).offline }, () => {
-								generalHelper.initDefaults()
-								youtubeHelper.initDefaults()
-								youtubeMusicHelper.initDefaults()
-								twitterHelper.initDefaults()
-								instagramHelper.initDefaults()
-								mapsHelper.initDefaults()
-								searchHelper.initDefaults()
-								translateHelper.initDefaults()
-								mediumHelper.initDefaults()
-								quoraHelper.initDefaults()
-								libremdbHelper.initDefaults()
-								reutersHelper.initDefaults()
-								redditHelper.initDefaults()
-								wikipediaHelper.initDefaults()
-								imgurHelper.initDefaults()
-								tiktokHelper.initDefaults()
-								sendTargetsHelper.initDefaults()
-								peertubeHelper.initDefaults()
-								lbryHelper.initDefaults()
-							})
-						})
-					})
-				})
-			})
-	}
-	if (details.reason == "install") initDefaults()
-
-	// if (details.reason == 'install' || (details.reason == "update" && details.previousVersion != browser.runtime.getManifest().version)) {
-	//   if (details.reason == "update")
-	//     browser.storage.local.get(null, r => {
-	//       if (r.theme) {
-	//         const old = encodeURIComponent(JSON.stringify(r))
-	//         browser.tabs.create({ url: browser.runtime.getURL(`/pages/background/reset_warning.html?data=${old}`) });
-	//       }
-	//       initDefaults();
-	//     })
-	//   else initDefaults();
-	// }
-})
-
-let BYPASSTABs = []
-browser.webRequest.onBeforeRequest.addListener(
-	details => {
-		const url = new URL(details.url)
-		if (new RegExp(/^chrome-extension:\/{2}.*\/instances\/.*.json$/).test(url.href) && details.type == "xmlhttprequest") return
-		let initiator
-		try {
-			if (details.originUrl) initiator = new URL(details.originUrl)
-			else if (details.initiator) initiator = new URL(details.initiator)
-		} catch {
-			return null
-		}
-
-		/*
-		let newUrl = youtubeMusicHelper.redirect(url, details.type)
-		if (!newUrl) newUrl = youtubeHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = twitterHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = instagramHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = mapsHelper.redirect(url, initiator)
-		if (!newUrl) newUrl = redditHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = mediumHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = quoraHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = libremdbHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = reutersHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = imgurHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = tiktokHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = sendTargetsHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = peertubeHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = lbryHelper.redirect(url, details.type, initiator)
-		if (!newUrl) newUrl = translateHelper.redirect(url)
-		if (!newUrl) newUrl = searchHelper.redirect(url)
-		if (!newUrl) newUrl = wikipediaHelper.redirect(url)
-		*/
-		let newUrl = servicesHelper.redirect(url, details.type, initiator)
-
-		if (details.frameAncestors && details.frameAncestors.length > 0 && generalHelper.isException(new URL(details.frameAncestors[0].url))) newUrl = null
-
-		if (generalHelper.isException(url)) newUrl = "BYPASSTAB"
-		if (BYPASSTABs.includes(details.tabId)) newUrl = null
-
-		if (newUrl) {
-			if (newUrl === "CANCEL") {
-				console.log(`Canceled ${url}`)
-				return { cancel: true }
-			}
-			if (newUrl === "BYPASSTAB") {
-				console.log(`Bypassed ${details.tabId} ${url}`)
-				if (!BYPASSTABs.includes(details.tabId)) BYPASSTABs.push(details.tabId)
-				return null
-			}
-			console.info("Redirecting", url.href, "=>", newUrl)
-			return { redirectUrl: newUrl }
-		}
-		return null
-	},
-	{ urls: ["<all_urls>"] },
-	["blocking"]
-)
-
-browser.tabs.onRemoved.addListener(tabId => {
-	const i = BYPASSTABs.indexOf(tabId)
-	if (i > -1) {
-		BYPASSTABs.splice(i, 1)
-		console.log("Removed BYPASSTABs", tabId)
-	}
-})
-
-browser.webRequest.onHeadersReceived.addListener(
-	e => {
-		let response = youtubeHelper.removeXFrameOptions(e)
-		if (!response) response = twitterHelper.removeXFrameOptions(e)
-		return response
-	},
-	{ urls: ["<all_urls>"] },
-	["blocking", "responseHeaders"]
-)
-
-async function redirectOfflineInstance(url, tabId) {
-	let newUrl = await youtubeHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await twitterHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await instagramHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await redditHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await searchHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await translateHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await mediumHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await quoraHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await libremdbHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await tiktokHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await imgurHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await wikipediaHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await peertubeHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await lbryHelper.switchInstance(url, true)
-	if (!newUrl) newUrl = await youtubeMusicHelper.switchInstance(url, true)
-
-	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("autoRedirect", r => resolve(r.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({
-	id: "settings",
-	title: browser.i18n.getMessage("Settings"),
-	contexts: ["browser_action"],
-})
-
-browser.contextMenus.create({
-	id: "switchInstance",
-	title: browser.i18n.getMessage("switchInstance"),
-	contexts: ["browser_action"],
-})
-
-browser.contextMenus.create({
-	id: "copyRaw",
-	title: browser.i18n.getMessage("copyRaw"),
-	contexts: ["browser_action"],
-})
-
-browser.contextMenus.create({
-	id: "unify",
-	title: browser.i18n.getMessage("unifySettings"),
-	contexts: ["browser_action"],
-})
-
-browser.contextMenus.onClicked.addListener(info => {
-	if (info.menuItemId == "switchInstance") utils.switchInstance()
-	else if (info.menuItemId == "settings") browser.runtime.openOptionsPage()
-	else if (info.menuItemId == "copyRaw") utils.copyRaw()
-	else if (info.menuItemId == "unify") utils.unify()
-})
-
-browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
-	if (message.function === "unify") utils.unify(false).then(r => sendResponse({ response: r }))
-	return true
-})
-
-browser.storage.local.set({ version: browser.runtime.getManifest().version })
+"use strict"

+

+import generalHelper from "../../assets/javascripts/general.js"

+import utils from "../../assets/javascripts/utils.js"

+

+import youtubeHelper from "../../assets/javascripts/youtube/youtube.js"

+import youtubeMusicHelper from "../../assets/javascripts/youtubeMusic.js"

+import twitterHelper from "../../assets/javascripts/twitter.js"

+import instagramHelper from "../../assets/javascripts/instagram.js"

+import redditHelper from "../../assets/javascripts/reddit.js"

+import searchHelper from "../../assets/javascripts/search.js"

+import translateHelper from "../../assets/javascripts/translate/translate.js"

+import mapsHelper from "../../assets/javascripts/maps.js"

+import wikipediaHelper from "../../assets/javascripts/wikipedia.js"

+import mediumHelper from "../../assets/javascripts/medium.js"

+import quoraHelper from "../../assets/javascripts/quora.js"

+import libremdbHelper from "../../assets/javascripts/imdb.js"

+import reutersHelper from "../../assets/javascripts/reuters.js"

+import imgurHelper from "../../assets/javascripts/imgur.js"

+import tiktokHelper from "../../assets/javascripts/tiktok.js"

+import sendTargetsHelper from "../../assets/javascripts/sendTargets.js"

+import peertubeHelper from "../../assets/javascripts/peertube.js"

+import lbryHelper from "../../assets/javascripts/lbry.js"

+

+import servicesHelper from "../../assets/javascripts/services.js"

+

+window.browser = window.browser || window.chrome

+

+browser.runtime.onInstalled.addListener(details => {

+	function initDefaults() {

+		fetch("/instances/blacklist.json")

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

+			.then(async data => {

+				browser.storage.local.clear(() => {

+					browser.storage.local.set({ cloudflareBlackList: JSON.parse(data).cloudflare }, () => {

+						browser.storage.local.set({ authenticateBlackList: JSON.parse(data).authenticate }, () => {

+							browser.storage.local.set({ offlineBlackList: JSON.parse(data).offline }, () => {

+								generalHelper.initDefaults()

+								/*

+								youtubeHelper.initDefaults()

+								youtubeMusicHelper.initDefaults()

+								twitterHelper.initDefaults()

+								instagramHelper.initDefaults()

+								mapsHelper.initDefaults()

+								searchHelper.initDefaults()

+								translateHelper.initDefaults()

+								mediumHelper.initDefaults()

+								quoraHelper.initDefaults()

+								libremdbHelper.initDefaults()

+								reutersHelper.initDefaults()

+								redditHelper.initDefaults()

+								wikipediaHelper.initDefaults()

+								imgurHelper.initDefaults()

+								tiktokHelper.initDefaults()

+								sendTargetsHelper.initDefaults()

+								peertubeHelper.initDefaults()

+								lbryHelper.initDefaults()

+								*/

+								servicesHelper.initDefaults()

+							})

+						})

+					})

+				})

+			})

+	}

+	if (details.reason == "install") initDefaults()

+

+	// if (details.reason == 'install' || (details.reason == "update" && details.previousVersion != browser.runtime.getManifest().version)) {

+	//   if (details.reason == "update")

+	//     browser.storage.local.get(null, r => {

+	//       if (r.theme) {

+	//         const old = encodeURIComponent(JSON.stringify(r))

+	//         browser.tabs.create({ url: browser.runtime.getURL(`/pages/background/reset_warning.html?data=${old}`) });

+	//       }

+	//       initDefaults();

+	//     })

+	//   else initDefaults();

+	// }

+})

+

+let BYPASSTABs = []

+browser.webRequest.onBeforeRequest.addListener(

+	details => {

+		const url = new URL(details.url)

+		if (new RegExp(/^chrome-extension:\/{2}.*\/instances\/.*.json$/).test(url.href) && details.type == "xmlhttprequest") return

+		let initiator

+		try {

+			if (details.originUrl) initiator = new URL(details.originUrl)

+			else if (details.initiator) initiator = new URL(details.initiator)

+		} catch {

+			return null

+		}

+

+		/*

+		let newUrl = youtubeMusicHelper.redirect(url, details.type)

+		if (!newUrl) newUrl = youtubeHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = twitterHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = instagramHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = mapsHelper.redirect(url, initiator)

+		if (!newUrl) newUrl = redditHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = mediumHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = quoraHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = libremdbHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = reutersHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = imgurHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = tiktokHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = sendTargetsHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = peertubeHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = lbryHelper.redirect(url, details.type, initiator)

+		if (!newUrl) newUrl = translateHelper.redirect(url)

+		if (!newUrl) newUrl = searchHelper.redirect(url)

+		if (!newUrl) newUrl = wikipediaHelper.redirect(url)

+		*/

+		let newUrl = servicesHelper.redirect(url, details.type, initiator)

+

+		if (details.frameAncestors && details.frameAncestors.length > 0 && generalHelper.isException(new URL(details.frameAncestors[0].url))) newUrl = null

+

+		if (generalHelper.isException(url)) newUrl = "BYPASSTAB"

+		if (BYPASSTABs.includes(details.tabId)) newUrl = null

+

+		if (newUrl) {

+			if (newUrl === "CANCEL") {

+				console.log(`Canceled ${url}`)

+				return { cancel: true }

+			}

+			if (newUrl === "BYPASSTAB") {

+				console.log(`Bypassed ${details.tabId} ${url}`)

+				if (!BYPASSTABs.includes(details.tabId)) BYPASSTABs.push(details.tabId)

+				return null

+			}

+			console.info("Redirecting", url.href, "=>", newUrl)

+			return { redirectUrl: newUrl }

+		}

+		return null

+	},

+	{ urls: ["<all_urls>"] },

+	["blocking"]

+)

+

+browser.tabs.onRemoved.addListener(tabId => {

+	const i = BYPASSTABs.indexOf(tabId)

+	if (i > -1) {

+		BYPASSTABs.splice(i, 1)

+		console.log("Removed BYPASSTABs", tabId)

+	}

+})

+

+browser.webRequest.onHeadersReceived.addListener(

+	e => {

+		let response = youtubeHelper.removeXFrameOptions(e)

+		if (!response) response = twitterHelper.removeXFrameOptions(e)

+		return response

+	},

+	{ urls: ["<all_urls>"] },

+	["blocking", "responseHeaders"]

+)

+

+async function redirectOfflineInstance(url, tabId) {

+	let newUrl = await youtubeHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await twitterHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await instagramHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await redditHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await searchHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await translateHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await mediumHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await quoraHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await libremdbHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await tiktokHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await imgurHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await wikipediaHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await peertubeHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await lbryHelper.switchInstance(url, true)

+	if (!newUrl) newUrl = await youtubeMusicHelper.switchInstance(url, true)

+

+	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("autoRedirect", r => resolve(r.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({

+	id: "settings",

+	title: browser.i18n.getMessage("Settings"),

+	contexts: ["browser_action"],

+})

+

+browser.contextMenus.create({

+	id: "switchInstance",

+	title: browser.i18n.getMessage("switchInstance"),

+	contexts: ["browser_action"],

+})

+

+browser.contextMenus.create({

+	id: "copyRaw",

+	title: browser.i18n.getMessage("copyRaw"),

+	contexts: ["browser_action"],

+})

+

+browser.contextMenus.create({

+	id: "unify",

+	title: browser.i18n.getMessage("unifySettings"),

+	contexts: ["browser_action"],

+})

+

+browser.contextMenus.onClicked.addListener(info => {

+	if (info.menuItemId == "switchInstance") utils.switchInstance()

+	else if (info.menuItemId == "settings") browser.runtime.openOptionsPage()

+	else if (info.menuItemId == "copyRaw") utils.copyRaw()

+	else if (info.menuItemId == "unify") utils.unify()

+})

+

+browser.runtime.onMessage.addListener((message, sender, sendResponse) => {

+	if (message.function === "unify") utils.unify(false).then(r => sendResponse({ response: r }))

+	return true

+})

+

+browser.storage.local.set({ version: browser.runtime.getManifest().version })