diff --git a/README.md b/README.md index 60cf566..f323d63 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,9 @@ - [Chrome Extension](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb) - [Firefox Add-on](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/) -A simple browser extension that redirects Twitter, YouTube & Instagram requests to privacy friendly alternatives - [Nitter](https://github.com/zedeus/nitter), [Invidious](https://github.com/omarroth/invidious) & [Bibliogram](https://github.com/cloudrac3r/bibliogram). +A simple web extension that redirects Twitter, YouTube, Instagram & Google Maps requests to privacy friendly alternatives - [Nitter](https://github.com/zedeus/nitter), [Invidious](https://github.com/omarroth/invidious), [Bibliogram](https://github.com/cloudrac3r/bibliogram) & [OpenStreetMap](https://www.openstreetmap.org/). -Listens for and redirects requests made to the following: - - **Twitter -** `twitter.com`, `www.twitter.com`, `mobile.twitter.com` - - **YouTube -** `youtube.com`, `www.youtube.com`, `youtube-nocookie.com`, `www.youtube-nocookie.com`, `m.youtube.com` - - **Instagram -** `instagram.com`, `www.instagram.com`, `help.instagram.com`, `about.instagram.com`. - -Allows for setting custom [Nitter](https://github.com/zedeus/nitter/wiki/Instances), [Invidious](https://github.com/omarroth/invidious/wiki/Invidious-Instances) & [Bibliogram](https://github.com/cloudrac3r/bibliogram/wiki/Instances) instances and toggling redirects on & off. +Allows for setting custom [Nitter](https://github.com/zedeus/nitter/wiki/Instances), [Invidious](https://github.com/omarroth/invidious/wiki/Invidious-Instances), [Bibliogram](https://github.com/cloudrac3r/bibliogram/wiki/Instances) & OpenStreetMap instances and toggling all redirects on & off. ## Build diff --git a/background.js b/background.js index 70fc0c2..dd620d8 100644 --- a/background.js +++ b/background.js @@ -8,7 +8,7 @@ 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 googleMapsRegex = /https?:\/\/((www|maps)\.)?(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; @@ -21,7 +21,9 @@ let disableInvidious; let disableBibliogram; let disableOsm; -chrome.storage.sync.get( +window.browser = window.browser || window.chrome; + +browser.storage.sync.get( [ 'nitterInstance', 'invidiousInstance', @@ -44,7 +46,7 @@ chrome.storage.sync.get( } ); -chrome.storage.onChanged.addListener(changes => { +browser.storage.onChanged.addListener(changes => { if ('nitterInstance' in changes) { nitterInstance = changes.nitterInstance.newValue || nitterDefault; } @@ -71,66 +73,16 @@ chrome.storage.onChanged.addListener(changes => { } }); -// 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` return null; } else if (url.pathname.match(/iframe_api/)) { // Redirect requests for YouTube Player API to local files instead - return chrome.runtime.getURL('assets/iframe_api.js'); + return browser.runtime.getURL('assets/iframe_api.js'); } else if (url.pathname.match(/www-widgetapi/)) { // Redirect requests for YouTube Player API to local files instead - return chrome.runtime.getURL('assets/www-widgetapi.js'); + return browser.runtime.getURL('assets/www-widgetapi.js'); } else { // Proxy video through the server url.searchParams.append('local', true); @@ -156,35 +108,27 @@ function redirectInstagram(url) { } } -function redirectGoogleMaps(url, type) { - let query = ''; +function redirectGoogleMaps(url) { + // Do not redirect embedded maps + if (url.pathname.includes('/embed')) { + return; + } 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]; - } + 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 { + const query = encodeURI(url.searchParams.get('q')) || 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( +browser.webRequest.onBeforeRequest.addListener( details => { const url = new URL(details.url); let redirect; @@ -209,7 +153,7 @@ chrome.webRequest.onBeforeRequest.addListener( } else if (url.href.match(googleMapsRegex)) { if (!disableOsm) { redirect = { - redirectUrl: redirectGoogleMaps(url, details.type) + redirectUrl: redirectGoogleMaps(url) }; } } @@ -222,12 +166,7 @@ chrome.webRequest.onBeforeRequest.addListener( return redirect; }, { - urls: [""], - types: [ - "main_frame", - "sub_frame", - "script" - ] + urls: [""] }, ['blocking'] ); diff --git a/manifest.json b/manifest.json index 4356a20..5f96e22 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name": "Privacy Redirect", - "description": "Redirects Twitter, YouTube & Instagram requests to privacy friendly alternatives - Nitter, Invidious, & Bibliogram.", + "description": "Redirects Twitter, YouTube, Instagram & Google Maps requests to privacy friendly alternatives.", "version": "1.1.10", "manifest_version": 2, "background": { @@ -22,6 +22,7 @@ "" ], "browser_action": { + "default_title": "Privacy Redirect", "default_popup": "pages/popup/popup.html", "default_icon": { "16": "images/icon16.png", diff --git a/pages/options/options.js b/pages/options/options.js index 62a9cad..4c12721 100644 --- a/pages/options/options.js +++ b/pages/options/options.js @@ -7,7 +7,9 @@ let disableNitter = document.querySelector('#disable-nitter'); let disableInvidious = document.querySelector('#disable-invidious'); let disableBibliogram = document.querySelector('#disable-bibliogram'); -chrome.storage.sync.get( +window.browser = window.browser || window.chrome; + +browser.storage.sync.get( [ 'nitterInstance', 'invidiousInstance', @@ -27,7 +29,7 @@ chrome.storage.sync.get( ); document.querySelector('#save').addEventListener('click', () => { - chrome.storage.sync.set({ + browser.storage.sync.set({ nitterInstance: nitterInstance.value && nitterInstance.checkValidity() ? new URL(nitterInstance.value).origin : '', invidiousInstance: invidiousInstance.value && invidiousInstance.checkValidity() ? new URL(invidiousInstance.value).origin : '', bibliogramInstance: bibliogramInstance.value && bibliogramInstance.checkValidity() ? new URL(bibliogramInstance.value).origin : '', diff --git a/pages/popup/popup.js b/pages/popup/popup.js index 16d5826..9b30c03 100644 --- a/pages/popup/popup.js +++ b/pages/popup/popup.js @@ -10,7 +10,9 @@ let disableBibliogram = document.querySelector('#disable-bibliogram'); let disableOsm = document.querySelector('#disable-osm'); let version = document.querySelector('#version'); -chrome.storage.sync.get( +window.browser = window.browser || window.chrome; + +browser.storage.sync.get( [ 'nitterInstance', 'invidiousInstance', @@ -33,7 +35,7 @@ chrome.storage.sync.get( } ); -version.textContent = chrome.runtime.getManifest().version; +version.textContent = browser.runtime.getManifest().version; function debounce(func, wait, immediate) { let timeout; @@ -52,7 +54,7 @@ function debounce(func, wait, immediate) { let nitterInstanceChange = debounce(() => { if (nitterInstance.checkValidity()) { - chrome.storage.sync.set({ + browser.storage.sync.set({ nitterInstance: nitterInstance.value ? new URL(nitterInstance.value).origin : '' }); } @@ -61,7 +63,7 @@ nitterInstance.addEventListener('input', nitterInstanceChange); let invidiousInstanceChange = debounce(() => { if (invidiousInstance.checkValidity()) { - chrome.storage.sync.set({ + browser.storage.sync.set({ invidiousInstance: invidiousInstance.value ? new URL(invidiousInstance.value).origin : '' }); } @@ -70,7 +72,7 @@ invidiousInstance.addEventListener('input', invidiousInstanceChange); let bibliogramInstanceChange = debounce(() => { if (bibliogramInstance.checkValidity()) { - chrome.storage.sync.set({ + browser.storage.sync.set({ bibliogramInstance: bibliogramInstance.value ? new URL(bibliogramInstance.value).origin : '' }); } @@ -79,7 +81,7 @@ bibliogramInstance.addEventListener('input', bibliogramInstanceChange); let osmInstanceChange = debounce(() => { if (osmInstance.checkValidity()) { - chrome.storage.sync.set({ + browser.storage.sync.set({ osmInstance: osmInstance.value ? new URL(osmInstance.value).origin : '' }); } @@ -87,17 +89,17 @@ let osmInstanceChange = debounce(() => { osmInstance.addEventListener('input', osmInstanceChange); disableNitter.addEventListener('change', event => { - chrome.storage.sync.set({ disableNitter: !event.target.checked }); + browser.storage.sync.set({ disableNitter: !event.target.checked }); }); disableInvidious.addEventListener('change', event => { - chrome.storage.sync.set({ disableInvidious: !event.target.checked }); + browser.storage.sync.set({ disableInvidious: !event.target.checked }); }); disableBibliogram.addEventListener('change', event => { - chrome.storage.sync.set({ disableBibliogram: !event.target.checked }); + browser.storage.sync.set({ disableBibliogram: !event.target.checked }); }); disableOsm.addEventListener('change', event => { - chrome.storage.sync.set({ disableOsm: !event.target.checked }); + browser.storage.sync.set({ disableOsm: !event.target.checked }); });