diff options
Diffstat (limited to 'src/assets/javascripts/maps.js')
-rw-r--r-- | src/assets/javascripts/maps.js | 517 |
1 files changed, 282 insertions, 235 deletions
diff --git a/src/assets/javascripts/maps.js b/src/assets/javascripts/maps.js index fd65b1c5..9fb10b9d 100644 --- a/src/assets/javascripts/maps.js +++ b/src/assets/javascripts/maps.js @@ -1,247 +1,294 @@ -"use strict"; - -window.browser = window.browser || window.chrome; -import utils from './utils.js' - -const targets = /^https?:\/{2}(((www|maps)\.)?(google\.).*(\/maps)|maps\.(google\.).*)/; - -let redirects = { - 'osm': { - "normal": [ - "https://www.openstreetmap.org" - ] - }, - 'facil': { - "normal": [ - "https://facilmap.org" - ], - "tor": [], - "i2p": [], - "loki": [] - } -}; - - -let - disableMaps, - mapsFrontend, - protocol, - protocolFallback, - facilNormalRedirectsChecks, - facilNormalCustomRedirects, - facilTorCustomRedirects, - facilI2pCustomRedirects, - facilLokiCustomRedirects; +"use strict" -function init() { - browser.storage.local.get( - [ - "disableMaps", - "mapsFrontend", - "protocol", - "protocolFallback", - "facilNormalRedirectsChecks", - "facilNormalCustomRedirects", - "facilTorCustomRedirects", - "facilI2pCustomRedirects", - "facilLokiCustomRedirects" - ], - r => { - disableMaps = r.disableMaps; - mapsFrontend = r.mapsFrontend; - protocol = r.protocol; - protocolFallback = r.protocolFallback; - facilNormalRedirectsChecks = r.facilNormalRedirectsChecks; - facilNormalCustomRedirects = r.facilNormalCustomRedirects; - facilTorCustomRedirects = r.facilTorCustomRedirects; - facilI2pCustomRedirects = r.facilI2pCustomRedirects; - facilLokiCustomRedirects = r.facilLokiCustomRedirects; - } - ) -} +window.browser = window.browser || window.chrome +import utils from "./utils.js" -init(); -browser.storage.onChanged.addListener(init) +const targets = /^https?:\/{2}(((www|maps)\.)?(google\.).*(\/maps)|maps\.(google\.).*)/ -function redirect(url, initiator) { - if (disableMaps) return; - if (initiator && initiator.host === "earth.google.com") return; - if (!url.href.match(targets)) return; - 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\/(.*)\//; - const travelModes = { - driving: "fossgis_osrm_car", - walking: "fossgis_osrm_foot", - bicycling: "fossgis_osrm_bike", - transit: "fossgis_osrm_car", // not implemented on OSM, default to car. - }; - const travelModesFacil = { - driving: "car", - walking: "pedestrian", - bicycling: "bicycle", - transit: "car", // not implemented on Facil, default to car. - }; - const osmLayers = { - none: "S", - transit: "T", - traffic: "S", // not implemented on OSM, default to standard. - bicycling: "C", - }; - 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 randomInstance; - if (mapsFrontend == 'osm') randomInstance = utils.getRandomInstance(redirects.osm.normal); - - if (mapsFrontend == 'facil') { - if (protocol == 'loki') randomInstance = utils.getRandomInstance(...facilLokiCustomRedirects); - else if (protocol == 'i2p') randomInstance = utils.getRandomInstance(...facilI2pCustomRedirects); - else if (protocol == 'tor') randomInstance = utils.getRandomInstance(...facilTorCustomRedirects); - if ((randomInstance == "" && protocolFallback) || protocol == 'normal') { - randomInstance = utils.getRandomInstance([...facilNormalRedirectsChecks, ...facilNormalCustomRedirects]); - } - } - - let mapCentre = "#"; - let prefs = {}; - - if (url.pathname.match(mapCentreRegex)) { // Set map centre if present - var [, lat, lon, zoom] = url.pathname.match(mapCentreRegex); - } else if (url.searchParams.has("center")) { - var [lat, lon] = url.searchParams.get("center").split(","); - var zoom = url.searchParams.get("zoom") ?? "17"; - } - - if (lat && lon && zoom) { - if (mapsFrontend == 'osm') mapCentre = `#map=${zoom}/${lat}/${lon}`; - if (mapsFrontend == 'facil') mapCentre = `#${zoom}/${lat}/${lon}`; - } - - 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(); - if (mapsFrontend == 'osm') return `${randomInstance}/export/embed.html?${prefsEncoded}`; - if (mapsFrontend == 'facil') 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"); - 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(); - if (mapsFrontend == 'osm') return `${randomInstance}/directions?${prefsEncoded}${mapCentre}`; - if (mapsFrontend == 'facil') return `${randomInstance}/#q=${orgVal}%20to%20${destVal}%20by%20${travelModesFacil[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); - - if (mapsFrontend == 'osm') return `${randomInstance}/search?query=${mlat}%2C${mlon}`; - if (mapsFrontend == 'facil') 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(","); - - if (mapsFrontend == 'osm') return `${randomInstance}/search?query=${mlat}%2C${mlon}`; - if (mapsFrontend == 'facil') 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(","); - - if (mapsFrontend == 'osm') return `${randomInstance}/search?query=${mlat}%2C${mlon}`; - if (mapsFrontend == 'facil') 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]; - - let prefsEncoded = new URLSearchParams(prefs).toString(); - if (query) { - if (mapsFrontend == 'osm') return `${randomInstance}/search?query="${query}${mapCentre}&${prefsEncoded}`; - if (mapsFrontend == 'facil') return `${randomInstance}/${mapCentre}/Mpnk/${query}`; - } - } - - let prefsEncoded = new URLSearchParams(prefs).toString(); - console.log("mapCentre", mapCentre); - console.log("prefs", prefs); - console.log("prefsEncoded", prefsEncoded); - if (mapsFrontend == 'osm') return `${randomInstance}/${mapCentre}&${prefsEncoded}`; - if (mapsFrontend == 'facil') return `${randomInstance}/${mapCentre}/Mpnk`; +const frontends = new Array("facil") +const protocols = new Array("normal", "tor", "i2p", "loki") + +let redirects = {} + +for (let i = 0; i < frontends.length; i++) { + redirects[frontends[i]] = {} + for (let x = 0; x < protocols.length; x++) { + redirects[frontends[i]][protocols[x]] = [] + } +} + +redirects.osm = {} +redirects.osm.normal = ["https://www.openstreetmap.org"] + +function setRedirects(val) { + browser.storage.local.get("cloudflareBlackList", r => { + redirects.facil = val + facilNormalRedirectsChecks = [...redirects.facil.normal] + for (const instance of r.cloudflareBlackList) { + const a = facilNormalRedirectsChecks.indexOf(instance) + if (a > -1) facilNormalRedirectsChecks.splice(a, 1) + } + browser.storage.local.set({ + mapsRedirects: redirects, + facilNormalRedirectsChecks, + }) + }) } -async function initDefaults() { - return new Promise(resolve => - browser.storage.local.set({ - disableMaps: false, - mapsFrontend: 'osm', - mapsRedirects: redirects, - facilNormalRedirectsChecks: [...redirects.facil.normal], - facilNormalCustomRedirects: [], +let disableMaps, + mapsFrontend, + protocol, + protocolFallback, + facilNormalRedirectsChecks, + facilNormalCustomRedirects, + facilTorRedirectsChecks, + facilTorCustomRedirects, + facilI2pRedirectsChecks, + facilI2pCustomRedirects, + facilLokiRedirectsChecks, + facilLokiCustomRedirects - facilTorRedirectsChecks: [...redirects.facil.tor], - facilTorCustomRedirects: [], +function init() { + browser.storage.local.get( + [ + "disableMaps", + "mapsFrontend", + "protocol", + "protocolFallback", + "facilNormalRedirectsChecks", + "facilNormalCustomRedirects", + "facilTorRedirectsChecks", + "facilTorCustomRedirects", + "facilI2pRedirectsChecks", + "facilI2pCustomRedirects", + "facilLokiRedirectsChecks", + "facilLokiCustomRedirects", + ], + r => { + disableMaps = r.disableMaps + mapsFrontend = r.mapsFrontend + protocol = r.protocol + protocolFallback = r.protocolFallback + facilNormalRedirectsChecks = r.facilNormalRedirectsChecks + facilNormalCustomRedirects = r.facilNormalCustomRedirects + facilTorRedirectsChecks = r.facilTorRedirectsChecks + facilTorCustomRedirects = r.facilTorCustomRedirects + facilI2pRedirectsChecks = r.facilI2pRedirectsChecks + facilI2pCustomRedirects = r.facilI2pCustomRedirects + facilLokiRedirectsChecks = r.facilLokiRedirectsChecks + facilLokiCustomRedirects = r.facilLokiCustomRedirects + } + ) +} - facilI2pRedirectsChecks: [...redirects.facil.i2p], - facilI2pCustomRedirects: [], +init() +browser.storage.onChanged.addListener(init) - facilLokiRedirectsChecks: [...redirects.facil.loki], - facilLokiCustomRedirects: [] - }, () => resolve()) - ) +function redirect(url, initiator) { + if (disableMaps) return + if (initiator && initiator.host === "earth.google.com") return + if (!url.href.match(targets)) return + 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\/(.*)\// + const travelModes = { + driving: "fossgis_osrm_car", + walking: "fossgis_osrm_foot", + bicycling: "fossgis_osrm_bike", + transit: "fossgis_osrm_car", // not implemented on OSM, default to car. + } + const travelModesFacil = { + driving: "car", + walking: "pedestrian", + bicycling: "bicycle", + transit: "car", // not implemented on Facil, default to car. + } + const osmLayers = { + none: "S", + transit: "T", + traffic: "S", // not implemented on OSM, default to standard. + bicycling: "C", + } + 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 instancesList + switch (mapsFrontend) { + case "osm": + instancesList = [...redirects.osm.normal] + break + case "facil": + switch (protocol) { + case "loki": + instancesList = [...facilLokiRedirectsChecks, ...facilLokiCustomRedirects] + break + case "i2p": + instancesList = [...facilI2pRedirectsChecks, ...facilI2pCustomRedirects] + break + case "tor": + instancesList = [...facilTorRedirectsChecks, ...facilTorCustomRedirects] + } + if ((instancesList == "" && protocolFallback) || protocol == "normal") { + instancesList = [...facilNormalRedirectsChecks, ...facilNormalCustomRedirects] + } + } + const randomInstance = utils.getRandomInstance(instancesList) + + let mapCentre = "#" + let prefs = {} + + if (url.pathname.match(mapCentreRegex)) { + // Set map centre if present + var [, lat, lon, zoom] = url.pathname.match(mapCentreRegex) + } else if (url.searchParams.has("center")) { + var [lat, lon] = url.searchParams.get("center").split(",") + var zoom = url.searchParams.get("zoom") ?? "17" + } + + if (lat && lon && zoom) { + if (mapsFrontend == "osm") mapCentre = `#map=${zoom}/${lat}/${lon}` + if (mapsFrontend == "facil") mapCentre = `#${zoom}/${lat}/${lon}` + } + + 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() + if (mapsFrontend == "osm") return `${randomInstance}/export/embed.html?${prefsEncoded}` + if (mapsFrontend == "facil") 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") + 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() + if (mapsFrontend == "osm") return `${randomInstance}/directions?${prefsEncoded}${mapCentre}` + if (mapsFrontend == "facil") return `${randomInstance}/#q=${orgVal}%20to%20${destVal}%20by%20${travelModesFacil[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) + + if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}` + if (mapsFrontend == "facil") 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(",") + + if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}` + if (mapsFrontend == "facil") 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(",") + + if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}` + if (mapsFrontend == "facil") 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] + + let prefsEncoded = new URLSearchParams(prefs).toString() + if (query) { + if (mapsFrontend == "osm") return `${randomInstance}/search?query="${query}${mapCentre}&${prefsEncoded}` + if (mapsFrontend == "facil") return `${randomInstance}/${mapCentre}/Mpnk/${query}` + } + } + + let prefsEncoded = new URLSearchParams(prefs).toString() + console.log("mapCentre", mapCentre) + console.log("prefs", prefs) + console.log("prefsEncoded", prefsEncoded) + if (mapsFrontend == "osm") return `${randomInstance}/${mapCentre}&${prefsEncoded}` + if (mapsFrontend == "facil") return `${randomInstance}/${mapCentre}/Mpnk` +} +function initDefaults() { + return new Promise(async resolve => { + fetch("/instances/data.json") + .then(response => response.text()) + .then(async data => { + let dataJson = JSON.parse(data) + for (let i = 0; i < frontends.length; i++) { + redirects[frontends[i]] = dataJson[frontends[i]] + } + browser.storage.local.set( + { + disableMaps: false, + mapsFrontend: "osm", + mapsRedirects: redirects, + facilNormalRedirectsChecks: [...redirects.facil.normal], + facilNormalCustomRedirects: [], + + facilTorRedirectsChecks: [...redirects.facil.tor], + facilTorCustomRedirects: [], + + facilI2pRedirectsChecks: [...redirects.facil.i2p], + facilI2pCustomRedirects: [], + + facilLokiRedirectsChecks: [...redirects.facil.loki], + facilLokiCustomRedirects: [], + }, + () => resolve() + ) + }) + }) } export default { - redirect, - initDefaults, -}; + setRedirects, + redirect, + initDefaults, +} |