about summary refs log tree commit diff stats
path: root/src/assets/javascripts/utils.js
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-09-11 18:44:14 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-09-11 18:44:14 +0200
commit2af0f5e64e47c59e575802249983feb8968959b1 (patch)
treea2d80749d6b297ef05b1893949081b678f9e8677 /src/assets/javascripts/utils.js
parentchore(Merge): remote-tracking branch 'origin/master' (diff)
parentTranslated using Weblate (Arabic) (diff)
downloadlibredirect-2af0f5e64e47c59e575802249983feb8968959b1.zip
chore(merge): Merge remote-tracking branch 'origin/master'
Following Conflicts have been resolved:
        README.md
        src/_locales/bs/messages.json
        src/_locales/de/messages.json
        src/_locales/en/messages.json
        src/_locales/fr/messages.json
        src/_locales/ko/messages.json
        src/_locales/nb_NO/messages.json
        src/_locales/pt/messages.json
        src/_locales/pt_BR/messages.json
        src/_locales/sr/messages.json
        src/_locales/vi/messages.json
        src/assets/images/libredirect.svg
        src/assets/javascripts/services.js
        src/config.json
        src/manifest.json
        src/updates/updates.xml
Diffstat (limited to 'src/assets/javascripts/utils.js')
-rw-r--r--src/assets/javascripts/utils.js345
1 files changed, 199 insertions, 146 deletions
diff --git a/src/assets/javascripts/utils.js b/src/assets/javascripts/utils.js
index fe08e576..e5b8ba46 100644
--- a/src/assets/javascripts/utils.js
+++ b/src/assets/javascripts/utils.js
@@ -1,11 +1,11 @@
 window.browser = window.browser || window.chrome
 
 /**
- * @param {Array.<T>} instances 
+ * @param {Array.<T>} instances
  * @returns {T}
  */
 function getRandomInstance(instances) {
-	return instances[~~(instances.length * Math.random())]
+  return instances[~~(instances.length * Math.random())]
 }
 
 /**
@@ -14,32 +14,24 @@ function getRandomInstance(instances) {
  * @returns {T}
  */
 function getNextInstance(currentInstanceUrl, instances) {
-	const currentInstanceIndex = instances.indexOf(currentInstanceUrl);
-
-	if (currentInstanceIndex === -1){
-		return getRandomInstance(instances);
-	}
-
-	const nextInstanceIndex = (currentInstanceIndex + 1) % instances.length;
-
-	return instances[nextInstanceIndex];
-}
-
-/**
- * @param {string} str
- */
-function camelCase(str) {
-	return str.charAt(0).toUpperCase() + str.slice(1)
+  const currentInstanceIndex = instances.indexOf(currentInstanceUrl)
+  if (currentInstanceIndex === -1) return getRandomInstance(instances)
+  const nextInstanceIndex = (currentInstanceIndex + 1) % instances.length
+  return instances[nextInstanceIndex]
 }
 
 /**
  * @param {URL} url
  */
 function protocolHost(url) {
-	if (url.username && url.password) return `${url.protocol}//${url.username}:${url.password}@${url.host}`
-	if (url.pathname == "/TekstoLibre/" && url.host.endsWith("github.io")) // workaround
-		return `${url.protocol}//${url.host}${url.pathname.slice(0, -1)}`
-	return `${url.protocol}//${url.host}`
+  url.pathname = url.pathname.replace(/\/$/, "")
+  if (url.username && url.password) return `${url.protocol}//${url.username}:${url.password}@${url.host}${url.pathname}`
+
+  // workaround
+  if (url.pathname == "/TekstoLibre/" && url.host.endsWith("github.io"))
+    return `${url.protocol}//${url.host}${url.pathname.slice(0, -1)}`
+
+  return `${url.protocol}//${url.host}${url.pathname}`
 }
 
 /**
@@ -64,14 +56,14 @@ function protocolHost(url) {
  * @returns {Promise<Config>}
  */
 function getConfig() {
-	return new Promise(resolve => {
-		fetch("/config.json")
-			.then(response => response.text())
-			.then(json => {
-				resolve(JSON.parse(json))
-				return
-			})
-	})
+  return new Promise(resolve => {
+    fetch("/config.json")
+      .then(response => response.text())
+      .then(json => {
+        resolve(JSON.parse(json))
+        return
+      })
+  })
 }
 
 /**
@@ -83,144 +75,205 @@ function getConfig() {
  * @returns {Promise<Object.<string, Option | string[]>>}
  */
 function getOptions() {
-	return new Promise(resolve =>
-		browser.storage.local.get("options", r => {
-			resolve(r.options)
-		})
-	)
+  return new Promise(resolve => browser.storage.local.get("options", r => resolve(r.options)))
 }
 
 function getPingCache() {
-	return new Promise(resolve =>
-		browser.storage.local.get("pingCache", r => {
-			resolve(r.pingCache ?? {})
-		})
-	)
+  return new Promise(resolve => browser.storage.local.get("pingCache", r => resolve(r.pingCache ?? {})))
 }
 
 function getBlacklist(options) {
-	return new Promise(resolve => {
-		let url
-		if (options.fetchInstances == 'github') {
-			url = 'https://raw.githubusercontent.com/libredirect/instances/main/blacklist.json'
-		}
-		else if (options.fetchInstances == 'codeberg') {
-			url = 'https://codeberg.org/LibRedirect/instances/raw/branch/main/blacklist.json'
-		}
-		else {
-			resolve('disabled')
-			return
-		}
-		const http = new XMLHttpRequest()
-		http.open("GET", url, true)
-		http.onreadystatechange = () => {
-			if (http.status === 200 && http.readyState == XMLHttpRequest.DONE) {
-				resolve(JSON.parse(http.responseText))
-				return
-			}
-		}
-		http.onerror = () => {
-			resolve()
-			return
-		}
-		http.ontimeout = () => {
-			resolve()
-			return
-		}
-		http.send(null)
-	})
+  return new Promise(resolve => {
+    let url
+    if (options.fetchInstances == "github")
+      url = "https://raw.githubusercontent.com/libredirect/instances/main/blacklist.json"
+    else if (options.fetchInstances == "codeberg")
+      url = "https://codeberg.org/LibRedirect/instances/raw/branch/main/blacklist.json"
+    else return resolve("disabled")
+    const http = new XMLHttpRequest()
+    http.open("GET", url, true)
+    http.onreadystatechange = () => {
+      if (http.status === 200 && http.readyState == XMLHttpRequest.DONE) resolve(JSON.parse(http.responseText))
+    }
+    http.onerror = () => resolve()
+    http.ontimeout = () => resolve()
+    http.send(null)
+  })
 }
 
 function getList(options) {
-	return new Promise(resolve => {
-		let url
-		if (options.fetchInstances == 'github') {
-			url = 'https://raw.githubusercontent.com/libredirect/instances/main/data.json'
-		}
-		else if (options.fetchInstances == 'codeberg') {
-			url = 'https://codeberg.org/LibRedirect/instances/raw/branch/main/data.json'
-		}
-		else {
-			resolve('disabled')
-			return
-		}
-		const http = new XMLHttpRequest()
-		http.open("GET", url, true)
-		http.onreadystatechange = () => {
-			if (http.status === 200 && http.readyState == XMLHttpRequest.DONE) {
-				resolve(JSON.parse(http.responseText))
-				return
-			}
-		}
-		http.onerror = () => {
-			resolve()
-			return
-		}
-		http.ontimeout = () => {
-			resolve()
-			return
-		}
-		http.send(null)
-	})
+  return new Promise(resolve => {
+    let url
+    if (options.fetchInstances == "github")
+      url = "https://raw.githubusercontent.com/libredirect/instances/main/data.json"
+    else if (options.fetchInstances == "codeberg")
+      url = "https://codeberg.org/LibRedirect/instances/raw/branch/main/data.json"
+    else return resolve("disabled")
+    const http = new XMLHttpRequest()
+    http.open("GET", url, true)
+    http.onreadystatechange = () => {
+      if (http.status === 200 && http.readyState == XMLHttpRequest.DONE) return resolve(JSON.parse(http.responseText))
+    }
+    http.onerror = () => resolve()
+    http.ontimeout = () => resolve()
+    http.send(null)
+  })
 }
 
 /**
  * @param {string} href
  */
 function pingOnce(href) {
-	return new Promise(async resolve => {
-		let started
-		let http = new XMLHttpRequest()
-		http.timeout = 5000
-		http.ontimeout = () => resolve(5000)
-		http.onerror = () => resolve()
-		http.onreadystatechange = () => {
-			if (http.readyState == 2) {
-				if (http.status == 200) {
-					let ended = new Date().getTime()
-					http.abort()
-					resolve(ended - started)
-				} else {
-					resolve(5000 + http.status)
-				}
-			}
-		}
-		http.open("GET", `${href}?_=${new Date().getTime()}`, true)
-		started = new Date().getTime()
-		http.send(null)
-	})
+  return new Promise(async resolve => {
+    let started
+    let http = new XMLHttpRequest()
+    http.timeout = 5000
+    http.ontimeout = () => resolve(5000)
+    http.onerror = () => resolve()
+    http.onreadystatechange = () => {
+      if (http.readyState == 2) {
+        if (http.status == 200) {
+          let ended = new Date().getTime()
+          http.abort()
+          resolve(ended - started)
+        } else {
+          resolve(5000 + http.status)
+        }
+      }
+    }
+    http.open("GET", `${href}?_=${new Date().getTime()}`, true)
+    started = new Date().getTime()
+    http.send(null)
+  })
 }
 
 /**
  * @param {string} href
  */
 function ping(href) {
-	return new Promise(async resolve => {
-		let average = 0
-		let time
-		for (let i = 0; i < 3; i++) {
-			time = await pingOnce(href)
-			if (i == 0) continue
-			if (time >= 5000) {
-				resolve(time)
-				return
-			}
-			average += time
-		}
-		average = parseInt(average / 3)
-		resolve(average)
-	})
+  return new Promise(async resolve => {
+    let average = 0
+    let time
+    for (let i = 0; i < 3; i++) {
+      time = await pingOnce(href)
+      if (i == 0) continue
+      if (time >= 5000) {
+        resolve(time)
+        return
+      }
+      average += time
+    }
+    average = parseInt(average / 3)
+    resolve(average)
+  })
+}
+
+function addressToLatLng(address) {
+  const http = new XMLHttpRequest()
+  http.open(
+    "GET",
+    `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(address)}&format=json&limit=1`,
+    false
+  )
+  http.send()
+  if (http.status == 200) {
+    const json = JSON.parse(http.responseText)[0]
+    if (json) {
+      return {
+        coordinate: `${json.lat},${json.lon}`,
+        boundingbox: `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}`,
+      }
+    }
+    return {}
+  }
+}
+
+function getQuery(url) {
+  let query = ""
+  if (url.searchParams.has("q")) query = url.searchParams.get("q")
+  else if (url.searchParams.has("query")) query = url.searchParams.has("query")
+  return query
+}
+function prefsEncoded(prefs) {
+  return new URLSearchParams(prefs).toString()
+}
+
+function convertMapCentre(url) {
+  let [lat, lon, zoom] = [null, null, null]
+  const reg = url.pathname.match(/@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/)
+  if (reg) {
+    ;[, lon, lat, zoom] = reg
+  } else if (url.searchParams.has("center")) {
+    // Set map centre if present
+    ;[lat, lon] = url.searchParams.get("center").split(",")
+    zoom = url.searchParams.get("zoom") ?? "17"
+  }
+  return { zoom, lon, lat }
+}
+
+export function randomInstances(clearnet, n) {
+  let instances = []
+  if (n > clearnet.length) n = clearnet.length
+  for (let i = 0; i < n; i++) {
+    const randomNumber = Math.floor(Math.random() * clearnet.length)
+    const randomInstance = clearnet[randomNumber]
+    instances.push(randomInstance)
+  }
+  return instances
+}
+export function style(options, window) {
+  const vars = cssVariables(options, window)
+  return `--text: ${vars.text};
+  --bg-main: ${vars.bgMain};
+  --bg-secondary: ${vars.bgSecondary};
+  --active: ${vars.active};
+  --danger: ${vars.danger};
+  --light-grey: ${vars.lightGrey};`
+}
+
+function cssVariables(options, window) {
+  const dark = {
+    text: "#fff",
+    bgMain: "#121212",
+    bgSecondary: "#202020",
+    active: "#fbc117",
+    danger: "#f04141",
+    lightGrey: "#c3c3c3",
+  }
+
+  const light = {
+    text: "black",
+    bgMain: "white",
+    bgSecondary: "#e4e4e4",
+    active: "#fb9817",
+    danger: "#f04141",
+    lightGrey: "#c3c3c3",
+  }
+  if (options.theme == "dark") {
+    return dark
+  } else if (options.theme == "light") {
+    return light
+  } else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
+    return dark
+  } else {
+    return light
+  }
 }
 
 export default {
-	getRandomInstance,
-	getNextInstance,
-	protocolHost,
-	getList,
-	getBlacklist,
-	camelCase,
-	getConfig,
-	getOptions,
-	getPingCache,
-	ping,
+  getRandomInstance,
+  getNextInstance,
+  protocolHost,
+  getList,
+  getBlacklist,
+  getConfig,
+  getOptions,
+  getPingCache,
+  ping,
+  addressToLatLng,
+  getQuery,
+  prefsEncoded,
+  convertMapCentre,
+  randomInstances,
+  style,
 }