aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-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 })