diff --git a/background.js b/background.js index ab04f95..70fc0c2 100644 --- a/background.js +++ b/background.js @@ -7,30 +7,40 @@ const twitterRegex = /((www|mobile)\.)?twitter\.com/; const bibliogramDefault = 'https://bibliogram.art'; const instagramRegex = /((www|about|help)\.)?instagram\.com/; const instagramPathsRegex = /(\/a|\/admin|\/api|\/favicon.ico|\/static|\/imageproxy|\/p|\/u|\/developer|\/about|\/legal|\/explore|\/director)/; +const osmDefault = 'https://openstreetmap.org'; +const googleMapsRegex = /(google).*(\/maps)/; +const latLngZoomRegex = /@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/; +const dataLatLngRegex = /(!3d|!4d)(-?[0-9]{1,10}.[0-9]{1,10})/g; let nitterInstance; let invidiousInstance; let bibliogramInstance; +let osmInstance; let disableNitter; let disableInvidious; let disableBibliogram; +let disableOsm; chrome.storage.sync.get( [ 'nitterInstance', 'invidiousInstance', 'bibliogramInstance', + 'osmInstance', 'disableNitter', 'disableInvidious', 'disableBibliogram', + 'disableOsm' ], result => { disableNitter = result.disableNitter; disableInvidious = result.disableInvidious; disableBibliogram = result.disableBibliogram; + disableOsm = result.disableOsm; nitterInstance = result.nitterInstance || nitterDefault; invidiousInstance = result.invidiousInstance || invidiousDefault; bibliogramInstance = result.bibliogramInstance || bibliogramDefault; + osmInstance = result.osmInstance || osmDefault; } ); @@ -44,6 +54,9 @@ chrome.storage.onChanged.addListener(changes => { if ('bibliogramInstance' in changes) { bibliogramInstance = changes.bibliogramInstance.newValue || bibliogramDefault; } + if ('osmInstance' in changes) { + osmInstance = changes.osmInstance.newValue || osmDefault; + } if ('disableNitter' in changes) { disableNitter = changes.disableNitter.newValue; } @@ -53,8 +66,61 @@ chrome.storage.onChanged.addListener(changes => { if ('disableBibliogram' in changes) { disableBibliogram = changes.disableBibliogram.newValue; } + if ('disableOsm' in changes) { + disableOsm = changes.disableOsm.newValue; + } }); +// https://github.com/tankaru/ReplaceG2O +function deg2rad(deg) { + return deg / 360 * 2 * Math.PI; +} + +function rad2deg(rad) { + return rad / 2 / Math.PI * 360.0; +} + +function getTileNumber(lat, lon, zoom) { + xtile = Math.round((lon + 180.0) / 360.0 * 2 ** zoom); + ytile = Math.round((1 - Math.log(Math.tan(deg2rad(lat)) + 1 / (Math.cos(deg2rad(lat)))) / Math.PI) / 2 * 2 ** zoom); + return [xtile, ytile]; +} + +function getLonLat(xtile, ytile, zoom) { + n = 2 ** zoom; + lon = xtile / n * 360.0 - 180.0; + lat = rad2deg(Math.atan(Math.sinh(Math.PI * (1 - 2 * ytile / n)))); + return [lon, lat]; +} + +function LonLat_to_bbox(lat, lon, zoom) { + width = 600; + height = 450; + tile_size = 256; + + [xtile, ytile] = getTileNumber(lat, lon, zoom); + + xtile_s = (xtile * tile_size - width / 2) / tile_size; + ytile_s = (ytile * tile_size - height / 2) / tile_size; + xtile_e = (xtile * tile_size + width / 2) / tile_size; + ytile_e = (ytile * tile_size + height / 2) / tile_size; + + [lon_s, lat_s] = getLonLat(xtile_s, ytile_s, zoom); + [lon_e, lat_e] = getLonLat(xtile_e, ytile_e, zoom); + + return [lon_s, lat_s, lon_e, lat_e]; +} + +//make a bbox, 0.001 should be modified based on zoom value +function bbox(lat, lon, zoom) { + return LonLat_to_bbox(lat, lon, zoom); + +} + +function zoom(satelliteZoom) { + return -1.4436 * Math.log(satelliteZoom) + 28.7; +} + function redirectYouTube(url) { if (url.host.split('.')[0] === 'studio') { // Avoid redirecting `studio.youtube.com` @@ -90,6 +156,34 @@ function redirectInstagram(url) { } } +function redirectGoogleMaps(url, type) { + let query = ''; + let lat = ''; + let lon = ''; + let zoom = ''; + if (url.pathname.match(latLngZoomRegex)) { + [, lat, lon, zoom] = url.pathname.match(latLngZoomRegex); + } + if (type === 'main_frame') { + if (url.pathname.includes('data=')) { + const [mlat, mlon] = url.pathname.match(dataLatLngRegex); + return `${osmInstance}/?mlat=${mlat.replace('!3d', '')}&mlon=${mlon.replace('!4d', '')}#map=${zoom}/${lat}/${lon}`; + } else if (url.search.includes('q=')) { + query = encodeURI(url.searchParams.get('q')); + } else { + query = url.pathname.split('/')[3]; + } + return `${osmInstance}/search?query=${query}#map=${zoom}/${lat}/${lon}`; + } else if (type === 'sub_frame' && url.pathname.match(latLngZoomRegex)) { + const [mapleft, mapbottom, mapright, maptop] = bbox(Number(lat), Number(lon), zoom(z)); + if (url.pathname.includes('data=')) { + const [mlat, mlon] = url.pathname.match(dataLatLngRegex); + return `${osmInstance}/export/embed.html?bbox=${mapleft}%2C${mapbottom}'%2C'${mapright}'%2C'${maptop}'&layer=mapnik&marker=${mlat}%2C${mlon}'`; + } + return `${osmInstance}/export/embed.html?bbox=${mapleft}%2C${mapbottom}'%2C'${mapright}'%2C'${maptop}'&layer=mapnik'`; + } +} + chrome.webRequest.onBeforeRequest.addListener( details => { const url = new URL(details.url); @@ -112,6 +206,12 @@ chrome.webRequest.onBeforeRequest.addListener( redirectUrl: redirectInstagram(url) }; } + } else if (url.href.match(googleMapsRegex)) { + if (!disableOsm) { + redirect = { + redirectUrl: redirectGoogleMaps(url, details.type) + }; + } } if (redirect && redirect.redirectUrl) { console.log( diff --git a/manifest.json b/manifest.json index 6f93540..4356a20 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "Privacy Redirect", "description": "Redirects Twitter, YouTube & Instagram requests to privacy friendly alternatives - Nitter, Invidious, & Bibliogram.", - "version": "1.1.9", + "version": "1.1.10", "manifest_version": 2, "background": { "scripts": [ diff --git a/pages/popup/popup.html b/pages/popup/popup.html index f0c4b3d..40cf3e7 100644 --- a/pages/popup/popup.html +++ b/pages/popup/popup.html @@ -45,6 +45,15 @@ +
+
+

OpenStreetMap Redirects

+   + +
+
+

Nitter Instance

@@ -74,6 +83,11 @@
diff --git a/pages/popup/popup.js b/pages/popup/popup.js index 4eb15ba..16d5826 100644 --- a/pages/popup/popup.js +++ b/pages/popup/popup.js @@ -3,9 +3,11 @@ let nitterInstance = document.querySelector('#nitter-instance'); let invidiousInstance = document.querySelector('#invidious-instance'); let bibliogramInstance = document.querySelector('#bibliogram-instance'); +let osmInstance = document.querySelector('#osm-instance'); let disableNitter = document.querySelector('#disable-nitter'); let disableInvidious = document.querySelector('#disable-invidious'); let disableBibliogram = document.querySelector('#disable-bibliogram'); +let disableOsm = document.querySelector('#disable-osm'); let version = document.querySelector('#version'); chrome.storage.sync.get( @@ -13,17 +15,21 @@ chrome.storage.sync.get( 'nitterInstance', 'invidiousInstance', 'bibliogramInstance', + 'osmInstance', 'disableNitter', 'disableInvidious', - 'disableBibliogram' + 'disableBibliogram', + 'disableOsm' ], result => { nitterInstance.value = result.nitterInstance || ''; invidiousInstance.value = result.invidiousInstance || ''; bibliogramInstance.value = result.bibliogramInstance || ''; + osmInstance.value = result.osmInstance || ''; disableNitter.checked = !result.disableNitter; disableInvidious.checked = !result.disableInvidious; disableBibliogram.checked = !result.disableBibliogram; + disableOsm.checked = !result.disableOsm; } ); @@ -71,6 +77,15 @@ let bibliogramInstanceChange = debounce(() => { }, 500); bibliogramInstance.addEventListener('input', bibliogramInstanceChange); +let osmInstanceChange = debounce(() => { + if (osmInstance.checkValidity()) { + chrome.storage.sync.set({ + osmInstance: osmInstance.value ? new URL(osmInstance.value).origin : '' + }); + } +}, 500); +osmInstance.addEventListener('input', osmInstanceChange); + disableNitter.addEventListener('change', event => { chrome.storage.sync.set({ disableNitter: !event.target.checked }); }); @@ -82,3 +97,7 @@ disableInvidious.addEventListener('change', event => { disableBibliogram.addEventListener('change', event => { chrome.storage.sync.set({ disableBibliogram: !event.target.checked }); }); + +disableOsm.addEventListener('change', event => { + chrome.storage.sync.set({ disableOsm: !event.target.checked }); +}); diff --git a/pages/styles.css b/pages/styles.css index 20453a1..89ae5a8 100644 --- a/pages/styles.css +++ b/pages/styles.css @@ -13,8 +13,8 @@ body { color: var(--text-secondary); margin: 0; max-width: 400px; - min-width: 240px; - background-color: var(--dark-grey) + min-width: 300px; + background-color: var(--dark-grey); } header {