aboutsummaryrefslogtreecommitdiffstats
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,
}