diff --git a/README.md b/README.md index 820daeb..ce9ee7d 100644 --- a/README.md +++ b/README.md @@ -5,32 +5,36 @@ [![Donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/SimonBrazell/donate) [![Buy me a coffee](assets/images/buy-me-a-coffee.png)](https://www.buymeacoffee.com/SimonBrazell) ## Get -[![Firefox Add-on](assets/images/badge-amo.png)](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/) -[![Chrome Extension](assets/images/badge-chrome.png)](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb) + +[![Firefox Add-on](assets/images/badge-amo.png)](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/) +[![Chrome Extension](assets/images/badge-chrome.png)](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb) [![Edge Extension](assets/images/badge-ms.png)](https://microsoftedge.microsoft.com/addons/detail/privacy-redirect/elnabkhcgpajchapppkhiaifkgikgihj) ## About -A web extension that redirects *Twitter, YouTube, Instagram, Google Maps & Non-Private Searches* requests to privacy friendly alternatives - [Nitter](https://github.com/zedeus/nitter), [Invidious](https://github.com/iv-org/invidious), [FreeTube](https://github.com/FreeTubeApp/FreeTube), [Bibliogram](https://sr.ht/~cadence/bibliogram/), [OpenStreetMap](https://www.openstreetmap.org/) & Private Search Engines like [DuckDuckGo](https://duckduckgo.com) and [Startpage](https://startpage.com). + +A web extension that redirects _Twitter, YouTube, Instagram, Google Maps & Non-Private Searches_ requests to privacy friendly alternatives - [Nitter](https://github.com/zedeus/nitter), [Invidious](https://github.com/iv-org/invidious), [FreeTube](https://github.com/FreeTubeApp/FreeTube), [Bibliogram](https://sr.ht/~cadence/bibliogram/), [OpenStreetMap](https://www.openstreetmap.org/) & Private Search Engines like [DuckDuckGo](https://duckduckgo.com) and [Startpage](https://startpage.com). It's possible to toggle all redirects on and off. The extension will default to using random instances if none are selected. If these instances are not working, you can try and set a custom instance from the list below. \*Instance for Search Engine redirect cannot be chosen at the moment. ### Custom instances + Privacy Redirect allows setting custom instances, instances can be found here: + - [Nitter instances](https://github.com/zedeus/nitter/wiki/Instances) - [Invidious instances](https://github.com/iv-org/invidious/wiki/Invidious-Instances) - [Bibliogram instances](https://git.sr.ht/~cadence/bibliogram-docs/tree/master/docs/Instances.md) - [OpenStreetMap tile servers](https://wiki.openstreetmap.org/wiki/Tile_servers) - Private Search Engine list - - [DuckDuckGo](https://duckduckgo.com) - - [Startpage](https://startpage.com) - - [Qwant](https://www.qwant.com) - - [Mojeek](https://www.mojeek.com) + - [DuckDuckGo](https://duckduckgo.com) + - [Startpage](https://startpage.com) + - [Qwant](https://www.qwant.com) + - [Mojeek](https://www.mojeek.com) ## Build 1. `npm install --global web-ext` 2. `web-ext build --overwrite-dest` -3. See `web-ext-artifacts/` for outputs. +3. `open web-ext-artifacts/` for outputs. ## License diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 3748db3..8f698af 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -23,6 +23,14 @@ "message": "OpenStreetMap Instance", "description": "Label for OSM instance field option (options)." }, + "redditInstance": { + "message": "Reddit Instance", + "description": "Label for Reddit instance field option (options)." + }, + "searchEngineInstance": { + "message": "Search Engine Instance", + "description": "Label for Search Engine instance field option (options)." + }, "disableNitter": { "message": "Nitter Redirects", "description": "Label for enable/disable Nitter redirects option (options & pop-up)." @@ -39,6 +47,14 @@ "message": "OpenStreetMap Redirects", "description": "Label for enable/disable OSM redirects option (options & pop-up)." }, + "disableReddit": { + "message": "Reddit Redirects", + "description": "Label for enable/disable Reddit redirects option (options & pop-up)." + }, + "disableSearchEngine": { + "message": "Search Engine Redirects", + "description": "Label for enable/disable Search Engine redirects option (options & pop-up)." + }, "alwaysProxy": { "message": "Always proxy videos through Invidious", "description": "Label for 'Always proxy videos through Invidious' option (options)." diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json index 30cee49..a993f04 100644 --- a/_locales/ru/messages.json +++ b/_locales/ru/messages.json @@ -39,7 +39,7 @@ "message": "Перенаправление на OpenStreetMap", "description": "Название настройки для включения/выключения перенаправления на OSM (в настройках и всплывающем окне)." }, - "disableOldReddit": { + "disableReddit": { "message": "Перенаправление на старый Reddit", "description": "Название настройки для включения/выключения перенаправления на старый Reddit (в настройках и всплывающем окне)." }, diff --git a/assets/javascript/remove-twitter-sw.js b/assets/javascript/remove-twitter-sw.js deleted file mode 100644 index f74ff89..0000000 --- a/assets/javascript/remove-twitter-sw.js +++ /dev/null @@ -1,92 +0,0 @@ -"use strict"; - -const nitterInstances = [ - "https://nitter.net", - "https://nitter.snopyta.org", - "https://nitter.42l.fr", - "https://nitter.nixnet.services", - "https://nitter.13ad.de", - "https://nitter.pussthecat.org", - "https://nitter.mastodont.cat", - "https://nitter", - "https://nitter.tedomum.net", - "https://nitter.cattube.org", - "https://nitter.fdn.fr", - "https://nitter.1d4.us", - "https://nitter.kavin.rocks", - "https://nitter.unixfox.eu", -]; - -let disableNitter; -let nitterInstance; -let redirectBypassFlag; -let exceptions; - -window.browser = window.browser || window.chrome; - -function getRandomInstance() { - return nitterInstances[~~(nitterInstances.length * Math.random())]; -} - -function isNotException(url) { - return !exceptions.some((regex) => regex.test(url.href)); -} - -function shouldRedirect(url) { - return ( - !redirectBypassFlag && - isNotException(url) && - !disableNitter && - url.host !== nitterInstance && - !url.pathname.includes("/home") - ); -} - -function redirectTwitter(url) { - if (url.host.split(".")[0] === "pbs") { - return `${nitterInstance}/pic/${encodeURIComponent(url.href)}`; - } else if (url.host.split(".")[0] === "video") { - return `${nitterInstance}/gif/${encodeURIComponent(url.href)}`; - } else { - return `${nitterInstance}${url.pathname}${url.search}`; - } -} - -browser.storage.sync.get( - [ - "nitterInstance", - "disableNitter", - "removeTwitterSW", - "redirectBypassFlag", - "exceptions", - ], - (result) => { - redirectBypassFlag = result.redirectBypassFlag; - browser.storage.sync.set({ - redirectBypassFlag: false, - }); - if (!result.removeTwitterSW) { - disableNitter = result.disableNitter; - nitterInstance = result.nitterInstance || getRandomInstance(); - exceptions = result.exceptions - ? result.exceptions.map((e) => { - return new RegExp(e); - }) - : []; - navigator.serviceWorker.getRegistrations().then((registrations) => { - for (let registration of registrations) { - if (registration.scope === "https://twitter.com/") { - registration.unregister(); - console.log("Unregistered Twitter SW", registration); - } - } - }); - const url = new URL(window.location); - if (shouldRedirect(url)) { - const redirect = redirectTwitter(url); - console.info("Redirecting", `"${url.href}"`, "=>", `"${redirect}"`); - window.location = redirect; - } - } - } -); diff --git a/manifest.json b/manifest.json index 0fc6f10..04ea6c1 100644 --- a/manifest.json +++ b/manifest.json @@ -1,28 +1,28 @@ { "name": "__MSG_extensionName__", "description": "__MSG_extensionDescription__", - "version": "1.1.43", + "version": "1.1.44", "manifest_version": 2, "background": { - "scripts": ["background.js"], + "page": "src/pages/background/background.html", "persistent": true }, "default_locale": "en", "icons": { - "16": "assets/images/icon16.png", - "32": "assets/images/icon32.png", - "48": "assets/images/icon48.png", - "128": "assets/images/icon128.png" + "16": "src/assets/images/icon16.png", + "32": "src/assets/images/icon32.png", + "48": "src/assets/images/icon48.png", + "128": "src/assets/images/icon128.png" }, "permissions": ["storage", "webRequest", "webRequestBlocking", ""], "browser_action": { "default_title": "Privacy Redirect", - "default_popup": "pages/popup/popup.html", + "default_popup": "src/pages/popup/popup.html", "default_icon": { - "16": "assets/images/icon16.png", - "32": "assets/images/icon32.png", - "48": "assets/images/icon48.png", - "128": "assets/images/icon128.png" + "16": "src/assets/images/icon16.png", + "32": "src/assets/images/icon32.png", + "48": "src/assets/images/icon48.png", + "128": "src/assets/images/icon128.png" } }, "content_scripts": [ @@ -34,39 +34,34 @@ "*://pbs.twimg.com/*", "*://video.twimg.com/*" ], - "js": ["assets/javascript/remove-twitter-sw.js"], + "js": ["src/assets/javascripts/remove-twitter-sw.js"], "run_at": "document_start" }, { "matches": [ "*://invidious.snopyta.org/*", - "*://yewtu.be/*", "*://invidious.xyz/*", - "*://invidious.site/*", + "*://invidious.kavin.rocks/*", + "*://tube.connect.cafe/*", + "*://invidious.zapashcanon.fr/*", "*://invidiou.site/*", - "*://invidious.ggc-project.de/*", - "*://invidious.13ad.de/*", - "*://invidious.toot.koeln/*", - "*://invidious.fdn.fr/*", - "*://watch.nettohikari.com/*", - "*://yt.iswleuven.be/*", - "*://yt.maisputain.ovh/*", - "*://kgg2m7yk5aybusll.onion/*", - "*://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid.onion/*", + "*://vid.mint.lgbt/*", + "*://invidious.site/*", + "*://yewtu.be/*", "*://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion/*", "*://qklhadlycap4cnod.onion/*", "*://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion/*", - "*://mfqczy4mysscub2s.onion/*", - "*://4l2dgddgsrkf2ous66i6seeyi6etzfgrue332grh2n7madpwopotugyd.onion/*" + "*://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion/*" ], - "js": ["assets/javascript/persist-invidious-prefs.js"], + "js": ["src/assets/javascripts/persist-invidious-prefs.js"], "run_at": "document_start" } ], "options_ui": { - "page": "pages/options/options.html", + "page": "src/pages/options/options.html", "open_in_tab": false }, + "web_accessible_resources": ["src/assets/javascripts/helpers/*"], "browser_specific_settings": { "gecko": { "id": "{b7f9d2cd-d772-4302-8c3f-eb941af36f76}" diff --git a/pages/options/options.html b/pages/options/options.html deleted file mode 100644 index bd7cee7..0000000 --- a/pages/options/options.html +++ /dev/null @@ -1,569 +0,0 @@ - - - - - - - - Privacy Redirect Options - - - -
- - - -
- -
-
- - - - - - - -
-

Nitter Redirects

-
-   - -
-
-
- - - - - - - -
-

- Invidious Redirects -

-
-   - -
-
-
- - - - - - - -
-

- Bibliogram Redirects -

-
-   - -
-
-
- - - - - - - -
-

- OpenStreetMap Redirects -

-
-   - -
-
-
- - - - - - - -
-

- Old Reddit Redirects -

-
-   - -
-
-
- - - - - - - -
-

- Search Engine Redirects -

-
-   - -
-
-
-

Nitter Instance

-
- -
-
-
-

Invidious Instance

-
- -
-
-
-

Bibliogram Instance

-
- -
-
-
-

OpenStreetMap Instance

-
- -
-
-
-

Old Reddit View (Desktop or Mobile)

-
- -
-
-
-

Theme

- -
-
- -
-
-

Invidious

-
-
-
-

- Invidious random instance pool (comma-separated) -

- -
-
- - - - - - - -
-

- Use FreeTube over Invidious when possible -

-
-   - -
-
-
- - - - - - - -
-

- Always proxy videos through Invidious -

-
-   - -
-
-
- - - - - - - -
-

- Only redirect embedded video to Invidious -

-
-   - -
-
-
-

Invidious Video Quality

- -
-
- - - - - - - -
-

- Invidious dark mode always on -

-
-   - -
-
-
-

- Invidious Volume -

- -
-
-

- Invidious Player Style -

- -
-
-

- Invidious Subtitles - language codes (comma-separated) -

- -
-
- - - - - - - -
-

- Invidious automatically play video on load -

-
-   - -
-
-
- - - - - - - -
-

- Persist Invidious preferences (as cookie) -

-
-   - -
-
-
-

Nitter

-
-
-
-

- Nitter random instance pool (comma-separated) -

- -
-
- - - - - - - -
-

- Proactively remove Twitter service worker -

-
-   - -
-
-
-

Bibliogram

-
-
-
-

- Bibliogram random instance pool (comma-separated) -

- -
-
- -
-
-

- Enter a URL or Regular Expression to be excluded from redirects. -

-

- All requests for or initiating from a URL that matches your exception - will be excluded from redirects. -

-

- Note - Supports JavaScript regular expressions, excluding the - enclosing forward slashes. -

-
-
- - - - - - - - - - - -
-

Add Exception

-
- - - - - - - - -
-
- -
- - - - - diff --git a/assets/images/Screen Shot Chrome 1.png b/src/assets/images/Screen Shot Chrome 1.png similarity index 100% rename from assets/images/Screen Shot Chrome 1.png rename to src/assets/images/Screen Shot Chrome 1.png diff --git a/assets/images/Screen Shot Chrome 2.png b/src/assets/images/Screen Shot Chrome 2.png similarity index 100% rename from assets/images/Screen Shot Chrome 2.png rename to src/assets/images/Screen Shot Chrome 2.png diff --git a/assets/images/Screen Shot Chrome 3.png b/src/assets/images/Screen Shot Chrome 3.png similarity index 100% rename from assets/images/Screen Shot Chrome 3.png rename to src/assets/images/Screen Shot Chrome 3.png diff --git a/assets/images/Screen Shot Chrome 4.png b/src/assets/images/Screen Shot Chrome 4.png similarity index 100% rename from assets/images/Screen Shot Chrome 4.png rename to src/assets/images/Screen Shot Chrome 4.png diff --git a/assets/images/Screen Shot Chrome 5.png b/src/assets/images/Screen Shot Chrome 5.png similarity index 100% rename from assets/images/Screen Shot Chrome 5.png rename to src/assets/images/Screen Shot Chrome 5.png diff --git a/assets/images/Screen Shot FF 1.png b/src/assets/images/Screen Shot FF 1.png similarity index 100% rename from assets/images/Screen Shot FF 1.png rename to src/assets/images/Screen Shot FF 1.png diff --git a/assets/images/Screen Shot FF 2.png b/src/assets/images/Screen Shot FF 2.png similarity index 100% rename from assets/images/Screen Shot FF 2.png rename to src/assets/images/Screen Shot FF 2.png diff --git a/assets/images/Screen Shot FF 3.png b/src/assets/images/Screen Shot FF 3.png similarity index 100% rename from assets/images/Screen Shot FF 3.png rename to src/assets/images/Screen Shot FF 3.png diff --git a/assets/images/Screen Shot FF 4.png b/src/assets/images/Screen Shot FF 4.png similarity index 100% rename from assets/images/Screen Shot FF 4.png rename to src/assets/images/Screen Shot FF 4.png diff --git a/assets/images/Screen Shot FF 5.png b/src/assets/images/Screen Shot FF 5.png similarity index 100% rename from assets/images/Screen Shot FF 5.png rename to src/assets/images/Screen Shot FF 5.png diff --git a/assets/images/badge-amo.png b/src/assets/images/badge-amo.png similarity index 100% rename from assets/images/badge-amo.png rename to src/assets/images/badge-amo.png diff --git a/assets/images/badge-chrome.png b/src/assets/images/badge-chrome.png similarity index 100% rename from assets/images/badge-chrome.png rename to src/assets/images/badge-chrome.png diff --git a/assets/images/badge-ms.png b/src/assets/images/badge-ms.png similarity index 100% rename from assets/images/badge-ms.png rename to src/assets/images/badge-ms.png diff --git a/assets/images/buy-me-a-coffee.png b/src/assets/images/buy-me-a-coffee.png similarity index 100% rename from assets/images/buy-me-a-coffee.png rename to src/assets/images/buy-me-a-coffee.png diff --git a/assets/images/chevron-down.svg b/src/assets/images/chevron-down.svg similarity index 100% rename from assets/images/chevron-down.svg rename to src/assets/images/chevron-down.svg diff --git a/assets/images/icon128.png b/src/assets/images/icon128.png similarity index 100% rename from assets/images/icon128.png rename to src/assets/images/icon128.png diff --git a/assets/images/icon16.png b/src/assets/images/icon16.png similarity index 100% rename from assets/images/icon16.png rename to src/assets/images/icon16.png diff --git a/assets/images/icon32.png b/src/assets/images/icon32.png similarity index 100% rename from assets/images/icon32.png rename to src/assets/images/icon32.png diff --git a/assets/images/icon48.png b/src/assets/images/icon48.png similarity index 100% rename from assets/images/icon48.png rename to src/assets/images/icon48.png diff --git a/assets/images/logo-small.png b/src/assets/images/logo-small.png similarity index 100% rename from assets/images/logo-small.png rename to src/assets/images/logo-small.png diff --git a/assets/images/logo-store.png b/src/assets/images/logo-store.png similarity index 100% rename from assets/images/logo-store.png rename to src/assets/images/logo-store.png diff --git a/assets/images/logo-tile.png b/src/assets/images/logo-tile.png similarity index 100% rename from assets/images/logo-tile.png rename to src/assets/images/logo-tile.png diff --git a/assets/images/logo.png b/src/assets/images/logo.png similarity index 100% rename from assets/images/logo.png rename to src/assets/images/logo.png diff --git a/src/assets/javascripts/helpers/common.js b/src/assets/javascripts/helpers/common.js new file mode 100644 index 0000000..6edd3d3 --- /dev/null +++ b/src/assets/javascripts/helpers/common.js @@ -0,0 +1,9 @@ +export default class { + static filterInstances(instances) { + return instances.filter((instance) => !instance.includes(".onion")); + } + + static getRandomInstance(instances) { + return instances[~~(instances.length * Math.random())]; + } +} diff --git a/src/assets/javascripts/helpers/google-maps.js b/src/assets/javascripts/helpers/google-maps.js new file mode 100644 index 0000000..3a041c6 --- /dev/null +++ b/src/assets/javascripts/helpers/google-maps.js @@ -0,0 +1,43 @@ +export default class { + static targets = /https?:\/\/(((www|maps)\.)?(google\.).*(\/maps)|maps\.(google\.).*)/; + static redirects = ["https://openstreetmap.org"]; + static mapCentreRegex = /@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/; + static dataLatLngRegex = /(!3d|!4d)(-?[0-9]{1,10}.[0-9]{1,10})/g; + static placeRegex = /\/place\/(.*)\//; + static travelModes = { + driving: "fossgis_osrm_car", + walking: "fossgis_osrm_foot", + bicycling: "fossgis_osrm_bike", + transit: "fossgis_osrm_car", // not implemented on OSM, default to car. + }; + static layers = { + none: "S", + transit: "T", + traffic: "S", // not implemented on OSM, default to standard. + bicycling: "C", + }; + static addressToLatLng(address, callback) { + const xmlhttp = new XMLHttpRequest(); + xmlhttp.onreadystatechange = () => { + if (xmlhttp.readyState === XMLHttpRequest.DONE) { + if (xmlhttp.status === 200) { + const json = JSON.parse(xmlhttp.responseText)[0]; + if (json) { + callback( + `${json.lat}%2C${json.lon}`, + `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}` + ); + } + } else { + console.info("Error: Status is " + xmlhttp.status); + } + } + }; + xmlhttp.open( + "GET", + `https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`, + false + ); + xmlhttp.send(); + } +} diff --git a/src/assets/javascripts/helpers/google-search.js b/src/assets/javascripts/helpers/google-search.js new file mode 100644 index 0000000..dc12042 --- /dev/null +++ b/src/assets/javascripts/helpers/google-search.js @@ -0,0 +1,9 @@ +export default class { + static targets = /https?:\/\/(((www|maps)\.)?(google\.).*(\/search)|search\.(google\.).*)/; + static redirects = [ + { link: "https://duckduckgo.com", q: "/" }, + { link: "https://startpage.com", q: "/search/" }, + { link: "https://www.qwant.com", q: "/" }, + { link: "https://www.mojeek.com", q: "/search" }, + ]; +} diff --git a/src/assets/javascripts/helpers/instagram.js b/src/assets/javascripts/helpers/instagram.js new file mode 100644 index 0000000..bd0ad9f --- /dev/null +++ b/src/assets/javascripts/helpers/instagram.js @@ -0,0 +1,47 @@ +export default class { + static targets = [ + "instagram.com", + "www.instagram.com", + "help.instagram.com", + "about.instagram.com", + ]; + static redirects = [ + "https://bibliogram.art", + "https://bibliogram.snopyta.org", + "https://bibliogram.pussthecat.org", + "https://bibliogram.nixnet.services", + "https://bg.endl.site", + "https://bibliogram.13ad.de", + "https://bibliogram.pixelfed.uno", + "https://bibliogram.ethibox.fr", + "https://bibliogram.hamster.dance", + "https://bibliogram.kavin.rocks", + "https://bibliogram.ggc-project.de", + ]; + static reservedPaths = [ + "about", + "explore", + "support", + "press", + "api", + "privacy", + "safety", + "admin", + "graphql", + "accounts", + "help", + "terms", + "contact", + "blog", + "igtv", + "u", + "p", + "fragment", + "imageproxy", + "videoproxy", + ".well-known", + "tv", + "reel", + ]; + static bypassPaths = /\/(accounts\/|embeds?.js)/; +} diff --git a/src/assets/javascripts/helpers/reddit.js b/src/assets/javascripts/helpers/reddit.js new file mode 100644 index 0000000..46fff4c --- /dev/null +++ b/src/assets/javascripts/helpers/reddit.js @@ -0,0 +1,24 @@ +export default class { + static targets = [ + "www.reddit.com", + "np.reddit.com", + "new.reddit.com", + "amp.reddit.com", + ]; + static redirects = [ + "https://old.reddit.com", // desktop + "https://i.reddit.com", // mobile + // teddit: privacy w/ old UI + "https://teddit.net", + "https://teddit.ggc-project.de", + "https://teddit.kavin.rocks", + "https://snew.notabug.io", // anti-censorship + // libreddit: privacy w/ modern UI + "https://libredd.it", + "https://libreddit.spike.codes", + "https://libreddit.kavin.rocks", + "https://libreddit.insanity.wtf", + "https://libreddit.dothq.co", + ]; + static bypassPaths = /\/(gallery\/poll\/rpan\/settings\/topics)/; +} diff --git a/src/assets/javascripts/helpers/twitter.js b/src/assets/javascripts/helpers/twitter.js new file mode 100644 index 0000000..1ebc025 --- /dev/null +++ b/src/assets/javascripts/helpers/twitter.js @@ -0,0 +1,38 @@ +export default class { + /* + Please remember to also update the manifest.json file + (content_scripts > matches, 'remove-twitter-sw.js') + when updating this list: + */ + static targets = [ + "twitter.com", + "www.twitter.com", + "mobile.twitter.com", + "pbs.twimg.com", + "video.twimg.com", + ]; + static redirects = [ + "https://nitter.net", + "https://nitter.snopyta.org", + "https://nitter.42l.fr", + "https://nitter.nixnet.services", + "https://nitter.13ad.de", + "https://nitter.pussthecat.org", + "https://nitter.mastodont.cat", + "https://nitter.dark.fail", + "https://nitter.tedomum.net", + "https://nitter.cattube.org", + "https://nitter.fdn.fr", + "https://nitter.1d4.us", + "https://nitter.kavin.rocks", + "https://tweet.lambda.dance", + "https://nitter.cc", + "https://nitter.weaponizedhumiliation.com", + "https://nitter.vxempire.xyz", + "https://nitter.unixfox.eu", + "http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion", + "http://nitter.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd.onion", + "http://nitterlgj3n5fgwesu3vxc5h67ruku33nqaoeoocae2mvlzhsu6k7fqd.onion", + "http://npf37k3mtzwxreiw52ccs5ay4e6qt2fkcs2ndieurdyn2cuzzsfyfvid.onion", + ]; +} diff --git a/src/assets/javascripts/helpers/youtube.js b/src/assets/javascripts/helpers/youtube.js new file mode 100644 index 0000000..3d1fcd2 --- /dev/null +++ b/src/assets/javascripts/helpers/youtube.js @@ -0,0 +1,33 @@ +export default class { + static targets = [ + "m.youtube.com", + "youtube.com", + "img.youtube.com", + "www.youtube.com", + "youtube-nocookie.com", + "www.youtube-nocookie.com", + "youtu.be", + "s.ytimg.com", + "music.youtube.com", + ]; + /* + Please remember to also update the manifest.json file + (content_scripts > matches, 'persist-invidious-prefs.js') + when updating this list: + */ + static redirects = [ + "https://invidious.snopyta.org", + "https://invidious.xyz", + "https://invidious.kavin.rocks", + "https://tube.connect.cafe", + "https://invidious.zapashcanon.fr", + "https://invidiou.site", + "https://vid.mint.lgbt", + "https://invidious.site", + "https://yewtu.be", + "http://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion", + "http://qklhadlycap4cnod.onion", + "http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion", + "http://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion", + ]; +} diff --git a/assets/javascript/localise.js b/src/assets/javascripts/localise.js similarity index 100% rename from assets/javascript/localise.js rename to src/assets/javascripts/localise.js diff --git a/assets/javascript/persist-invidious-prefs.js b/src/assets/javascripts/persist-invidious-prefs.js similarity index 100% rename from assets/javascript/persist-invidious-prefs.js rename to src/assets/javascripts/persist-invidious-prefs.js diff --git a/src/assets/javascripts/remove-twitter-sw.js b/src/assets/javascripts/remove-twitter-sw.js new file mode 100644 index 0000000..c39b4c9 --- /dev/null +++ b/src/assets/javascripts/remove-twitter-sw.js @@ -0,0 +1,89 @@ +"use strict"; + +let disableNitter; +let nitterInstance; +let redirectBypassFlag; +let exceptions; + +window.browser = window.browser || window.chrome; + +Promise.all([ + import(browser.extension.getURL("src/assets/javascripts/helpers/common.js")), + import(browser.extension.getURL("src/assets/javascripts/helpers/twitter.js")), +]).then( + (helpers) => { + let commonHelper; + let twitterHelper; + [commonHelper, twitterHelper] = helpers; + + function isNotException(url) { + return !exceptions.some((regex) => regex.test(url.href)); + } + + function shouldRedirect(url) { + return ( + !redirectBypassFlag && + isNotException(url) && + !disableNitter && + url.host !== nitterInstance && + !url.pathname.includes("/home") + ); + } + + function redirectTwitter(url) { + if (url.host.split(".")[0] === "pbs") { + return `${nitterInstance}/pic/${encodeURIComponent(url.href)}`; + } else if (url.host.split(".")[0] === "video") { + return `${nitterInstance}/gif/${encodeURIComponent(url.href)}`; + } else { + return `${nitterInstance}${url.pathname}${url.search}`; + } + } + + browser.storage.sync.get( + [ + "nitterInstance", + "disableNitter", + "removeTwitterSW", + "redirectBypassFlag", + "exceptions", + ], + (result) => { + redirectBypassFlag = result.redirectBypassFlag; + browser.storage.sync.set({ + redirectBypassFlag: false, + }); + if (!result.removeTwitterSW) { + disableNitter = result.disableNitter; + nitterInstance = + result.nitterInstance || + commonHelper.default.getRandomInstance( + twitterHelper.default.redirects + ); + exceptions = result.exceptions + ? result.exceptions.map((e) => { + return new RegExp(e); + }) + : []; + navigator.serviceWorker.getRegistrations().then((registrations) => { + for (let registration of registrations) { + if (registration.scope === "https://twitter.com/") { + registration.unregister(); + console.log("Unregistered Twitter SW", registration); + } + } + }); + const url = new URL(window.location); + if (shouldRedirect(url)) { + const redirect = redirectTwitter(url); + console.info("Redirecting", `"${url.href}"`, "=>", `"${redirect}"`); + window.location = redirect; + } + } + } + ); + }, + (error) => { + console.error(error); + } +); diff --git a/pages/styles.css b/src/assets/stylesheets/styles.css similarity index 90% rename from pages/styles.css rename to src/assets/stylesheets/styles.css index 022b96b..e11f313 100644 --- a/pages/styles.css +++ b/src/assets/stylesheets/styles.css @@ -23,7 +23,7 @@ body.light-theme { body { margin: 0; - max-width: 400px; + width: 400px; margin: auto; min-height: 572px; font-family: Sans-Serif; @@ -334,7 +334,7 @@ li { } .autocomplete input { - background: url(../assets/images/chevron-down.svg) right no-repeat; + background: url(../images/chevron-down.svg) right no-repeat; } .autocomplete-items { @@ -466,16 +466,51 @@ input[type="range"]::-moz-range-thumb { float: right; } -.subheading { - padding: 0 10px; -} - -.subheading h1 { +.collapsible { + background-color: var(--bg-main); + cursor: pointer; color: var(--active); + padding: 18px; + width: 100%; + border: none; + text-align: left; + outline: none; + font-size: 15px; + border-bottom: solid var(--active); + font-weight: bold; } -.subheading hr { - height: 1px; +.collapsible:after { + content: "\002B"; + color: var(--active); + font-weight: bold; + float: right; + margin-left: 5px; +} + +.collapsible-active, +.collapsible:hover, +.collapsible:hover::after { + background-color: var(--active); + color: var(--text-secondary); +} + +.collapsible-active:after { + content: "\002D"; + color: var(--text-secondary); + font-weight: bold; + float: right; + margin-left: 5px; +} + +.collapsible-content { + padding: 0 18px; + display: none; + overflow: hidden; +} + +hr { + height: 2px; background-color: var(--active); border: none; } diff --git a/src/pages/background/background.html b/src/pages/background/background.html new file mode 100644 index 0000000..2d0fb68 --- /dev/null +++ b/src/pages/background/background.html @@ -0,0 +1 @@ + diff --git a/background.js b/src/pages/background/background.js similarity index 66% rename from background.js rename to src/pages/background/background.js index 6fdce2d..d5a1966 100644 --- a/background.js +++ b/src/pages/background/background.js @@ -1,166 +1,47 @@ "use strict"; -const youtubeDomains = [ - "m.youtube.com", - "youtube.com", - "img.youtube.com", - "www.youtube.com", - "youtube-nocookie.com", - "www.youtube-nocookie.com", - "youtu.be", - "s.ytimg.com", - "music.youtube.com", -]; -const nitterInstances = [ - "https://nitter.net", - "https://nitter.snopyta.org", - "https://nitter.42l.fr", - "https://nitter.nixnet.services", - "https://nitter.13ad.de", - "https://nitter.pussthecat.org", - "https://nitter.mastodont.cat", - "https://nitter.dark.fail", - "https://nitter.tedomum.net", - "https://nitter.cattube.org", - "https://nitter.fdn.fr", - "https://nitter.1d4.us", - "https://nitter.kavin.rocks", - "https://tweet.lambda.dance", - "https://nitter.cc", - "https://nitter.weaponizedhumiliation.com", - "https://nitter.vxempire.xyz", - "https://nitter.unixfox.eu", - "http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion", - "http://nitter.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd.onion", - "http://nitterlgj3n5fgwesu3vxc5h67ruku33nqaoeoocae2mvlzhsu6k7fqd.onion", - "http://npf37k3mtzwxreiw52ccs5ay4e6qt2fkcs2ndieurdyn2cuzzsfyfvid.onion", -]; -const twitterDomains = [ - "twitter.com", - "www.twitter.com", - "mobile.twitter.com", - "pbs.twimg.com", - "video.twimg.com", -]; -const invidiousInstances = [ - "https://invidious.snopyta.org", - "https://invidious.xyz", - "https://invidious.kavin.rocks", - "https://tube.connect.cafe", - "https://invidious.zapashcanon.fr", - "https://invidiou.site", - "https://vid.mint.lgbt", - "https://invidious.site", - "https://yewtu.be", - "http://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion", - "http://qklhadlycap4cnod.onion", - "http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion", - "http://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion", -]; -const instagramDomains = [ - "instagram.com", - "www.instagram.com", - "help.instagram.com", - "about.instagram.com", -]; -const instagramReservedPaths = [ - "about", - "explore", - "support", - "press", - "api", - "privacy", - "safety", - "admin", - "graphql", - "accounts", - "help", - "terms", - "contact", - "blog", - "igtv", - "u", - "p", - "fragment", - "imageproxy", - "videoproxy", - ".well-known", - "tv", - "reel", -]; -const bibliogramBypassPaths = /\/(accounts\/|embeds?.js)/; -const bibliogramInstances = [ - "https://bibliogram.art", - "https://bibliogram.snopyta.org", - "https://bibliogram.pussthecat.org", - "https://bibliogram.nixnet.services", - "https://bg.endl.site", - "https://bibliogram.13ad.de", - "https://bibliogram.pixelfed.uno", - "https://bibliogram.ethibox.fr", - "https://bibliogram.hamster.dance", - "https://bibliogram.kavin.rocks", - "https://bibliogram.ggc-project.de", -]; -const osmDefault = "https://openstreetmap.org"; -const redditDomains = [ - "www.reddit.com", - "np.reddit.com", - "new.reddit.com", - "amp.reddit.com", -]; -const redditBypassPaths = /\/(gallery\/poll\/rpan\/settings\/topics)/; -const oldRedditViews = [ - // teddit: privacy w/ old UI - "https://teddit.net", - "https://teddit.ggc-project.de", - "https://teddit.kavin.rocks", - "https://snew.notabug.io", // anti-censorship - // libreddit: privacy w/ modern UI - "https://libredd.it", - "https://libreddit.spike.codes", - "https://libreddit.kavin.rocks", - "https://libreddit.insanity.wtf", - "https://libreddit.dothq.co", - "https://old.reddit.com", // desktop - "https://i.reddit.com" // mobile -]; -const oldRedditDefaultView = oldRedditViews[0]; -const googleMapsRegex = /https?:\/\/(((www|maps)\.)?(google\.).*(\/maps)|maps\.(google\.).*)/; -const mapCentreRegex = /@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/; -const dataLatLngRegex = /(!3d|!4d)(-?[0-9]{1,10}.[0-9]{1,10})/g; -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 layers = { - none: "S", - transit: "T", - traffic: "S", // not implemented on OSM, default to standard. - bicycling: "C", -}; -const googleSearchRegex = /https?:\/\/(((www|maps)\.)?(google\.).*(\/search)|search\.(google\.).*)/; -const privateSearchEngine = [ - { link: "https://duckduckgo.com", q: "/" }, - { link: "https://startpage.com", q: "/search/" }, - { link: "https://www.qwant.com", q: "/" }, - { link: "https://www.mojeek.com", q: "/search" }, -]; +import commonHelper from "../../assets/javascripts/helpers/common.js"; +import twitterHelper from "../../assets/javascripts/helpers/twitter.js"; +import youtubeHelper from "../../assets/javascripts/helpers/youtube.js"; +import instagramHelper from "../../assets/javascripts/helpers/instagram.js"; +import mapsHelper from "../../assets/javascripts/helpers/google-maps.js"; +import redditHelper from "../../assets/javascripts/helpers/reddit.js"; +import searchHelper from "../../assets/javascripts/helpers/google-search.js"; + +const nitterInstances = twitterHelper.redirects; +const twitterDomains = twitterHelper.targets; +const youtubeDomains = youtubeHelper.targets; +const invidiousInstances = youtubeHelper.redirects; +const instagramDomains = instagramHelper.targets; +const bibliogramInstances = instagramHelper.redirects; +const instagramReservedPaths = instagramHelper.reservedPaths; +const bibliogramBypassPaths = instagramHelper.bypassPaths; +const osmDefault = mapsHelper.redirects[0]; +const googleMapsRegex = mapsHelper.targets; +const mapCentreRegex = mapsHelper.mapCentreRegex; +const dataLatLngRegex = mapsHelper.dataLatLngRegex; +const placeRegex = mapsHelper.placeRegex; +const travelModes = mapsHelper.travelModes; +const layers = mapsHelper.layers; +const redditInstances = redditHelper.redirects; +const redditDomains = redditHelper.targets; +const redditBypassPaths = redditHelper.bypassPaths; +const redditDefault = redditHelper.redirects[0]; +const googleSearchRegex = searchHelper.targets; +const searchEngineInstances = searchHelper.redirects; let disableNitter; let disableInvidious; let disableBibliogram; let disableOsm; -let disableOldReddit; +let disableReddit; let disableSearchEngine; let nitterInstance; let invidiousInstance; let bibliogramInstance; let osmInstance; -let oldRedditView; +let redditInstance; +let searchEngineInstance; let alwaysProxy; let onlyEmbeddedVideo; let videoQuality; @@ -177,22 +58,19 @@ let exceptions; window.browser = window.browser || window.chrome; -function filterInstances(instances) { - return instances.filter((instance) => !instance.includes(".onion")); -} - browser.storage.sync.get( [ "nitterInstance", "invidiousInstance", "bibliogramInstance", "osmInstance", - "oldRedditView", + "redditInstance", + "searchEngineInstance", "disableNitter", "disableInvidious", "disableBibliogram", "disableOsm", - "disableOldReddit", + "disableReddit", "disableSearchEngine", "alwaysProxy", "onlyEmbeddedVideo", @@ -209,17 +87,18 @@ browser.storage.sync.get( "exceptions", ], (result) => { - disableNitter = result.disableNitter; - disableInvidious = result.disableInvidious; - disableBibliogram = result.disableBibliogram; - disableOsm = result.disableOsm; - disableOldReddit = result.disableOldReddit; - disableSearchEngine = result.disableSearchEngine; nitterInstance = result.nitterInstance; invidiousInstance = result.invidiousInstance; bibliogramInstance = result.bibliogramInstance; osmInstance = result.osmInstance || osmDefault; - oldRedditView = result.oldRedditView || oldRedditDefaultView; + redditInstance = result.redditInstance || redditDefault; + searchEngineInstance = result.searchEngineInstance; + disableNitter = result.disableNitter; + disableInvidious = result.disableInvidious; + disableBibliogram = result.disableBibliogram; + disableOsm = result.disableOsm; + disableReddit = result.disableReddit; + disableSearchEngine = result.disableSearchEngine; alwaysProxy = result.alwaysProxy; onlyEmbeddedVideo = result.onlyEmbeddedVideo; videoQuality = result.videoQuality; @@ -236,13 +115,13 @@ browser.storage.sync.get( useFreeTube = result.useFreeTube; nitterRandomPool = result.nitterRandomPool ? result.nitterRandomPool.split(",") - : filterInstances(nitterInstances); + : commonHelper.filterInstances(nitterInstances); invidiousRandomPool = result.invidiousRandomPool ? result.invidiousRandomPool.split(",") - : filterInstances(invidiousInstances); + : commonHelper.filterInstances(invidiousInstances); bibliogramRandomPool = result.bibliogramRandomPool ? result.bibliogramRandomPool.split(",") - : filterInstances(bibliogramInstances); + : commonHelper.filterInstances(bibliogramInstances); } ); @@ -259,8 +138,11 @@ browser.storage.onChanged.addListener((changes) => { if ("osmInstance" in changes) { osmInstance = changes.osmInstance.newValue || osmDefault; } - if ("oldRedditView" in changes) { - oldRedditView = changes.oldRedditView.newValue || oldRedditDefaultView; + if ("redditInstance" in changes) { + redditInstance = changes.redditInstance.newValue || redditDefault; + } + if ("searchEngineInstance" in changes) { + searchEngineInstance = changes.searchEngineInstance.newValue; } if ("disableNitter" in changes) { disableNitter = changes.disableNitter.newValue; @@ -274,8 +156,8 @@ browser.storage.onChanged.addListener((changes) => { if ("disableOsm" in changes) { disableOsm = changes.disableOsm.newValue; } - if ("disableOldReddit" in changes) { - disableOldReddit = changes.disableOldReddit.newValue; + if ("disableReddit" in changes) { + disableReddit = changes.disableReddit.newValue; } if ("disableSearchEngine" in changes) { disableSearchEngine = changes.disableSearchEngine.newValue; @@ -323,35 +205,6 @@ browser.storage.onChanged.addListener((changes) => { } }); -function getRandomInstance(instanceList) { - return instanceList[~~(instanceList.length * Math.random())]; -} - -function addressToLatLng(address, callback) { - const xmlhttp = new XMLHttpRequest(); - xmlhttp.onreadystatechange = () => { - if (xmlhttp.readyState === XMLHttpRequest.DONE) { - if (xmlhttp.status === 200) { - const json = JSON.parse(xmlhttp.responseText)[0]; - if (json) { - callback( - `${json.lat}%2C${json.lon}`, - `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}` - ); - } - } else { - console.info("Error: Status is " + xmlhttp.status); - } - } - }; - xmlhttp.open( - "GET", - `https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`, - false - ); - xmlhttp.send(); -} - function isException(url, initiator) { return ( exceptions.some((regex) => regex.test(url.href)) || @@ -411,7 +264,7 @@ function redirectYouTube(url, initiator, type) { url.searchParams.append("autoplay", invidiousAutoplay ? 1 : 0); return `${ - invidiousInstance || getRandomInstance(invidiousRandomPool) + invidiousInstance || commonHelper.getRandomInstance(invidiousRandomPool) }${url.pathname.replace("/shorts", "")}${url.search}`; } @@ -436,20 +289,20 @@ function redirectTwitter(url, initiator) { } if (url.host.split(".")[0] === "pbs") { return `${ - nitterInstance || getRandomInstance(nitterRandomPool) + nitterInstance || commonHelper.getRandomInstance(nitterRandomPool) }/pic/${encodeURIComponent(url.href)}`; } else if (url.host.split(".")[0] === "video") { return `${ - nitterInstance || getRandomInstance(nitterRandomPool) + nitterInstance || commonHelper.getRandomInstance(nitterRandomPool) }/gif/${encodeURIComponent(url.href)}`; } else if (url.pathname.includes("tweets")) { return `${ - nitterInstance || getRandomInstance(nitterRandomPool) + nitterInstance || commonHelper.getRandomInstance(nitterRandomPool) }${url.pathname.replace("/tweets", "")}${url.search}`; } else { - return `${nitterInstance || getRandomInstance(nitterRandomPool)}${ - url.pathname - }${url.search}`; + return `${ + nitterInstance || commonHelper.getRandomInstance(nitterRandomPool) + }${url.pathname}${url.search}`; } } @@ -474,14 +327,14 @@ function redirectInstagram(url, initiator, type) { url.pathname === "/" || instagramReservedPaths.includes(url.pathname.split("/")[1]) ) { - return `${bibliogramInstance || getRandomInstance(bibliogramRandomPool)}${ - url.pathname - }${url.search}`; + return `${ + bibliogramInstance || commonHelper.getRandomInstance(bibliogramRandomPool) + }${url.pathname}${url.search}`; } else { // Likely a user profile, redirect to '/u/...' - return `${bibliogramInstance || getRandomInstance(bibliogramRandomPool)}/u${ - url.pathname - }${url.search}`; + return `${ + bibliogramInstance || commonHelper.getRandomInstance(bibliogramRandomPool) + }/u${url.pathname}${url.search}`; } } @@ -523,7 +376,7 @@ function redirectGoogleMaps(url, initiator) { } } let marker, bbox; - addressToLatLng(query, (coords, boundingbox) => { + mapsHelper.addressToLatLng(query, (coords, boundingbox) => { marker = coords; bbox = boundingbox; }); @@ -533,13 +386,16 @@ function redirectGoogleMaps(url, initiator) { const travelMode = travelModes[url.searchParams.get("travelmode")] || travelModes["driving"]; let origin; - addressToLatLng(url.searchParams.get("origin"), (coords) => { + mapsHelper.addressToLatLng(url.searchParams.get("origin"), (coords) => { origin = coords; }); let destination; - addressToLatLng(url.searchParams.get("destination"), (coords) => { - destination = coords; - }); + mapsHelper.addressToLatLng( + url.searchParams.get("destination"), + (coords) => { + destination = coords; + } + ); redirect = `${osmInstance}/directions?engine=${travelMode}&route=${origin}%3B${destination}${mapCentre}${params}`; // Get marker from data attribute } else if ( @@ -578,13 +434,13 @@ function redirectGoogleMaps(url, initiator) { } function redirectReddit(url, initiator, type) { - if (disableOldReddit || isException(url, initiator)) { + if (disableReddit || isException(url, initiator)) { return null; } // Do not redirect when already on the selected view if ( - (initiator && initiator.origin === oldRedditView) || - url.origin === oldRedditView + (initiator && initiator.origin === redditInstance) || + url.origin === redditInstance ) { return null; } @@ -592,7 +448,7 @@ function redirectReddit(url, initiator, type) { if (type !== "main_frame" || url.pathname.match(redditBypassPaths)) { return null; } - return `${oldRedditView}${url.pathname}${url.search}`; + return `${redditInstance}${url.pathname}${url.search}`; } function redirectSearchEngine(url, initiator) { @@ -600,7 +456,9 @@ function redirectSearchEngine(url, initiator) { return null; } - let searchEngine = getRandomInstance(privateSearchEngine); + const searchEngine = + searchEngineInstance || + commonHelper.getRandomInstance(searchEngineInstances); let search = ""; url.search .slice(1) @@ -608,7 +466,6 @@ function redirectSearchEngine(url, initiator) { .forEach(function (input) { if (input.startsWith("q=")) search = input; }); - console.log("search: ", search); return `${searchEngine.link}${searchEngine.q}?${search}`; } @@ -640,7 +497,7 @@ browser.webRequest.onBeforeRequest.addListener( }; } else if ( redditDomains.includes(url.host) || - oldRedditViews.includes(url.origin) + redditInstances.includes(url.origin) ) { redirect = { redirectUrl: redirectReddit(url, initiator, details.type), diff --git a/src/pages/options/options.html b/src/pages/options/options.html new file mode 100644 index 0000000..af7bd41 --- /dev/null +++ b/src/pages/options/options.html @@ -0,0 +1,585 @@ + + + + + + + + Privacy Redirect Options + + + +
+ + + +
+ +
+
+ + + + + + + +
+

Nitter Redirects

+
+   + +
+
+
+ + + + + + + +
+

+ Invidious Redirects +

+
+   + +
+
+
+ + + + + + + +
+

+ Bibliogram Redirects +

+
+   + +
+
+
+ + + + + + + +
+

+ OpenStreetMap Redirects +

+
+   + +
+
+
+ + + + + + + +
+

+ Reddit Redirects +

+
+   + +
+
+
+ + + + + + + +
+

+ Search Engine Redirects +

+
+   + +
+
+
+

Nitter Instance

+
+ +
+
+
+

Invidious Instance

+
+ +
+
+
+

Bibliogram Instance

+
+ +
+
+
+

OpenStreetMap Instance

+
+ +
+
+
+

Reddit Instance

+
+ +
+
+
+

Search Engine Instance

+
+ +
+
+
+

Theme

+ +
+
+ +
+ +
+
+

+ Invidious random instance pool (comma-separated) +

+ +
+
+ + + + + + + +
+

+ Use FreeTube over Invidious when possible +

+
+   + +
+
+
+ + + + + + + +
+

+ Always proxy videos through Invidious +

+
+   + +
+
+
+ + + + + + + +
+

+ Only redirect embedded video to Invidious +

+
+   + +
+
+
+

Invidious Video Quality

+ +
+
+ + + + + + + +
+

+ Invidious dark mode always on +

+
+   + +
+
+
+

+ Invidious Volume +

+ +
+
+

+ Invidious Player Style +

+ +
+
+

+ Invidious Subtitles - language codes (comma-separated) +

+ +
+
+ + + + + + + +
+

+ Invidious automatically play video on load +

+
+   + +
+
+
+ + + + + + + +
+

+ Persist Invidious preferences (as cookie) +

+
+   + +
+
+
+
+ +
+
+

+ Nitter random instance pool (comma-separated) +

+ +
+
+ + + + + + + +
+

+ Proactively remove Twitter service worker +

+
+   + +
+
+
+
+ +
+
+

+ Bibliogram random instance pool (comma-separated) +

+ +
+
+
+
+ +
+
+

+ Enter a URL or Regular Expression to be excluded from redirects. +

+

+ All requests for or initiating from a URL that matches your exception + will be excluded from redirects. +

+

+ Note - Supports JavaScript regular expressions, excluding the + enclosing forward slashes. +

+
+
+ + + + + + + + + + + +
+

Add Exception

+
+ + + + + + + + +
+
+ +
+ + + + + diff --git a/pages/options/options.js b/src/pages/options/options.js similarity index 80% rename from pages/options/options.js rename to src/pages/options/options.js index 2530a32..e6bd224 100644 --- a/pages/options/options.js +++ b/src/pages/options/options.js @@ -1,77 +1,43 @@ "use strict"; -const nitterInstances = [ - "https://nitter.net", - "https://nitter.snopyta.org", - "https://nitter.42l.fr", - "https://nitter.nixnet.services", - "https://nitter.13ad.de", - "https://nitter.pussthecat.org", - "https://nitter.mastodont.cat", - "https://nitter.dark.fail", - "https://nitter.tedomum.net", - "https://nitter.cattube.org", - "https://nitter.fdn.fr", - "https://nitter.1d4.us", - "https://nitter.kavin.rocks", - "https://tweet.lambda.dance", - "https://nitter.cc", - "https://nitter.weaponizedhumiliation.com", - "https://nitter.vxempire.xyz", - "https://nitter.unixfox.eu", - "http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion", - "http://nitter.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd.onion", - "http://nitterlgj3n5fgwesu3vxc5h67ruku33nqaoeoocae2mvlzhsu6k7fqd.onion", - "http://npf37k3mtzwxreiw52ccs5ay4e6qt2fkcs2ndieurdyn2cuzzsfyfvid.onion", -]; -const invidiousInstances = [ - "https://invidious.snopyta.org", - "https://invidious.xyz", - "https://invidious.kavin.rocks", - "https://tube.connect.cafe", - "https://invidious.zapashcanon.fr", - "https://invidiou.site", - "https://vid.mint.lgbt", - "https://invidious.site", - "http://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion", - "http://qklhadlycap4cnod.onion", - "http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion", - "http://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion", -]; -const bibliogramInstances = [ - "https://bibliogram.art", - "https://bibliogram.snopyta.org", - "https://bibliogram.pussthecat.org", - "https://bibliogram.nixnet.services", - "https://bg.endl.site", - "https://bibliogram.13ad.de", - "https://bibliogram.pixelfed.uno", - "https://bibliogram.ethibox.fr", - "https://bibliogram.hamster.dance", - "https://bibliogram.kavin.rocks", - "https://bibliogram.ggc-project.de", -]; -const osmInstances = ["https://openstreetmap.org"]; -const oldRedditViews = ["https://old.reddit.com", "https://i.reddit.com"]; +import commonHelper from "../../assets/javascripts/helpers/common.js"; +import twitterHelper from "../../assets/javascripts/helpers/twitter.js"; +import youtubeHelper from "../../assets/javascripts/helpers/youtube.js"; +import instagramHelper from "../../assets/javascripts/helpers/instagram.js"; +import mapsHelper from "../../assets/javascripts/helpers/google-maps.js"; +import redditHelper from "../../assets/javascripts/helpers/reddit.js"; +import searchHelper from "../../assets/javascripts/helpers/google-search.js"; + +const nitterInstances = twitterHelper.redirects; +const invidiousInstances = youtubeHelper.redirects; +const bibliogramInstances = instagramHelper.redirects; +const osmInstances = mapsHelper.redirects; +const redditInstances = redditHelper.redirects; +const searchEngineInstances = searchHelper.redirects; const autocompletes = [ { id: "nitter-instance", instances: nitterInstances }, { id: "invidious-instance", instances: invidiousInstances }, { id: "bibliogram-instance", instances: bibliogramInstances }, { id: "osm-instance", instances: osmInstances }, - { id: "old-reddit-view", instances: oldRedditViews }, + { id: "reddit-instance", instances: redditInstances }, + { + id: "search-engine-instance", + instances: searchEngineInstances.map((instance) => instance.link), + }, ]; let nitterInstance = document.getElementById("nitter-instance"); let invidiousInstance = document.getElementById("invidious-instance"); let bibliogramInstance = document.getElementById("bibliogram-instance"); let osmInstance = document.getElementById("osm-instance"); -let oldRedditView = document.getElementById("old-reddit-view"); +let redditInstance = document.getElementById("reddit-instance"); +let searchEngineInstance = document.getElementById("search-engine-instance"); let disableNitter = document.getElementById("disable-nitter"); let disableInvidious = document.getElementById("disable-invidious"); let disableBibliogram = document.getElementById("disable-bibliogram"); let disableOsm = document.getElementById("disable-osm"); -let disableOldReddit = document.getElementById("disable-old-reddit"); -let disableSearchEngine = document.getElementById("disable-searchEngine"); +let disableReddit = document.getElementById("disable-reddit"); +let disableSearchEngine = document.getElementById("disable-search-engine"); let alwaysProxy = document.getElementById("always-proxy"); let onlyEmbeddedVideo = document.getElementById("only-embed"); let videoQuality = document.getElementById("video-quality"); @@ -113,22 +79,19 @@ function prependExceptionsItem(item, index) { }); } -function filterInstances(instances) { - return instances.filter((instance) => !instance.includes(".onion")).join(); -} - browser.storage.sync.get( [ "nitterInstance", "invidiousInstance", "bibliogramInstance", "osmInstance", - "oldRedditView", + "redditInstance", + "searchEngineInstance", "disableNitter", "disableInvidious", "disableBibliogram", "disableOsm", - "disableOldReddit", + "disableReddit", "disableSearchEngine", "alwaysProxy", "onlyEmbeddedVideo", @@ -154,12 +117,14 @@ browser.storage.sync.get( invidiousInstance.value = result.invidiousInstance || ""; bibliogramInstance.value = result.bibliogramInstance || ""; osmInstance.value = result.osmInstance || ""; - oldRedditView.value = result.oldRedditView || ""; + redditInstance.value = result.redditInstance || ""; + searchEngineInstance.value = + (result.searchEngineInstance && result.searchEngineInstance.link) || ""; disableNitter.checked = !result.disableNitter; disableInvidious.checked = !result.disableInvidious; disableBibliogram.checked = !result.disableBibliogram; disableOsm.checked = !result.disableOsm; - disableOldReddit.checked = !result.disableOldReddit; + disableReddit.checked = !result.disableReddit; disableSearchEngine.checked = !result.disableSearchEngine; alwaysProxy.checked = result.alwaysProxy; onlyEmbeddedVideo.checked = result.onlyEmbeddedVideo; @@ -178,11 +143,13 @@ browser.storage.sync.get( invidiousAutoplay.checked = result.invidiousAutoplay; useFreeTube.checked = result.useFreeTube; nitterRandomPool.value = - result.nitterRandomPool || filterInstances(nitterInstances); + result.nitterRandomPool || commonHelper.filterInstances(nitterInstances); invidiousRandomPool.value = - result.invidiousRandomPool || filterInstances(invidiousInstances); + result.invidiousRandomPool || + commonHelper.filterInstances(invidiousInstances); bibliogramRandomPool.value = - result.bibliogramRandomPool || filterInstances(bibliogramInstances); + result.bibliogramRandomPool || + commonHelper.filterInstances(bibliogramInstances); } ); @@ -274,7 +241,7 @@ function parseURL(urlString) { } } -let nitterInstanceChange = debounce(() => { +const nitterInstanceChange = debounce(() => { if (nitterInstance.checkValidity()) { browser.storage.sync.set({ nitterInstance: parseURL(nitterInstance.value), @@ -283,7 +250,7 @@ let nitterInstanceChange = debounce(() => { }, 500); nitterInstance.addEventListener("input", nitterInstanceChange); -let invidiousInstanceChange = debounce(() => { +const invidiousInstanceChange = debounce(() => { if (invidiousInstance.checkValidity()) { browser.storage.sync.set({ invidiousInstance: parseURL(invidiousInstance.value), @@ -292,7 +259,7 @@ let invidiousInstanceChange = debounce(() => { }, 500); invidiousInstance.addEventListener("input", invidiousInstanceChange); -let bibliogramInstanceChange = debounce(() => { +const bibliogramInstanceChange = debounce(() => { if (bibliogramInstance.checkValidity()) { browser.storage.sync.set({ bibliogramInstance: parseURL(bibliogramInstance.value), @@ -301,7 +268,7 @@ let bibliogramInstanceChange = debounce(() => { }, 500); bibliogramInstance.addEventListener("input", bibliogramInstanceChange); -let osmInstanceChange = debounce(() => { +const osmInstanceChange = debounce(() => { if (osmInstance.checkValidity()) { browser.storage.sync.set({ osmInstance: parseURL(osmInstance.value), @@ -310,14 +277,28 @@ let osmInstanceChange = debounce(() => { }, 500); osmInstance.addEventListener("input", osmInstanceChange); -let oldRedditViewChange = debounce(() => { - if (oldRedditView.checkValidity()) { +const redditInstanceChange = debounce(() => { + if (redditInstance.checkValidity()) { browser.storage.sync.set({ - oldRedditView: parseURL(oldRedditView.value), + redditInstance: parseURL(redditInstance.value), }); } }, 500); -oldRedditView.addEventListener("input", oldRedditViewChange); +redditInstance.addEventListener("input", redditInstanceChange); + +const searchEngineInstanceChange = debounce(() => { + const instance = searchEngineInstances.find( + (instance) => instance.link === searchEngineInstance.value + ); + if (instance || !searchEngineInstance.value) { + browser.storage.sync.set({ + searchEngineInstance: instance || searchEngineInstance.value, + }); + } else { + searchEngineInstance.setCustomValidity("Must be an instance from the list"); + } +}, 500); +searchEngineInstance.addEventListener("input", searchEngineInstanceChange); disableNitter.addEventListener("change", (event) => { browser.storage.sync.set({ disableNitter: !event.target.checked }); @@ -335,8 +316,8 @@ disableOsm.addEventListener("change", (event) => { browser.storage.sync.set({ disableOsm: !event.target.checked }); }); -disableOldReddit.addEventListener("change", (event) => { - browser.storage.sync.set({ disableOldReddit: !event.target.checked }); +disableReddit.addEventListener("change", (event) => { + browser.storage.sync.set({ disableReddit: !event.target.checked }); }); disableSearchEngine.addEventListener("change", (event) => { @@ -373,7 +354,7 @@ useFreeTube.addEventListener("change", (event) => { browser.storage.sync.set({ useFreeTube: event.target.checked }); }); -let invidiousVolumeChange = debounce(() => { +const invidiousVolumeChange = debounce(() => { document.querySelector( "#volume-value" ).textContent = `${invidiousVolume.value}%`; @@ -390,7 +371,7 @@ invidiousPlayerStyle.addEventListener("change", (event) => { }); }); -let invidiousSubtitlesChange = debounce(() => { +const invidiousSubtitlesChange = debounce(() => { browser.storage.sync.set({ invidiousSubtitles: invidiousSubtitles.value }); }, 500); invidiousSubtitles.addEventListener("input", invidiousSubtitlesChange); @@ -399,17 +380,17 @@ invidiousAutoplay.addEventListener("change", (event) => { browser.storage.sync.set({ invidiousAutoplay: event.target.checked }); }); -let nitterRandomPoolChange = debounce(() => { +const nitterRandomPoolChange = debounce(() => { browser.storage.sync.set({ nitterRandomPool: nitterRandomPool.value }); }, 500); nitterRandomPool.addEventListener("input", nitterRandomPoolChange); -let invidiousRandomPoolChange = debounce(() => { +const invidiousRandomPoolChange = debounce(() => { browser.storage.sync.set({ invidiousRandomPool: invidiousRandomPool.value }); }, 500); invidiousRandomPool.addEventListener("input", invidiousRandomPoolChange); -let bibliogramRandomPoolChange = debounce(() => { +const bibliogramRandomPoolChange = debounce(() => { browser.storage.sync.set({ bibliogramRandomPool: bibliogramRandomPool.value, }); @@ -524,3 +505,18 @@ function autocomplete(input, list) { autocompletes.forEach((value) => { autocomplete(document.getElementById(value.id), value.instances); }); + +var coll = document.getElementsByClassName("collapsible"); +var i; + +for (i = 0; i < coll.length; i++) { + coll[i].addEventListener("click", function () { + this.classList.toggle("collapsible-active"); + var content = this.nextElementSibling; + if (content.style.display === "block") { + content.style.display = "none"; + } else { + content.style.display = "block"; + } + }); +} diff --git a/pages/popup/popup.html b/src/pages/popup/popup.html similarity index 91% rename from pages/popup/popup.html rename to src/pages/popup/popup.html index af44b23..43a4a1a 100644 --- a/pages/popup/popup.html +++ b/src/pages/popup/popup.html @@ -4,7 +4,7 @@ - + @@ -121,30 +121,30 @@ -

- Old Reddit Redirects -

+

Reddit Redirects

  - + - +
-

Search Engine Redirects

+

+ Search Engine Redirects +

- - + + diff --git a/pages/popup/popup.js b/src/pages/popup/popup.js similarity index 86% rename from pages/popup/popup.js rename to src/pages/popup/popup.js index 6d4c3ff..0afb2f9 100644 --- a/pages/popup/popup.js +++ b/src/pages/popup/popup.js @@ -4,7 +4,7 @@ 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 disableOldReddit = document.querySelector("#disable-old-reddit"); +let disableReddit = document.querySelector("#disable-reddit"); let disableSearchEngine = document.querySelector("#disable-searchEngine"); let version = document.querySelector("#version"); @@ -16,7 +16,7 @@ browser.storage.sync.get( "disableInvidious", "disableBibliogram", "disableOsm", - "disableOldReddit", + "disableReddit", "disableSearchEngine", "theme", ], @@ -26,7 +26,7 @@ browser.storage.sync.get( disableInvidious.checked = !result.disableInvidious; disableBibliogram.checked = !result.disableBibliogram; disableOsm.checked = !result.disableOsm; - disableOldReddit.checked = !result.disableOldReddit; + disableReddit.checked = !result.disableReddit; disableSearchEngine.checked = !result.disableSearchEngine; } ); @@ -49,8 +49,8 @@ disableOsm.addEventListener("change", (event) => { browser.storage.sync.set({ disableOsm: !event.target.checked }); }); -disableOldReddit.addEventListener("change", (event) => { - browser.storage.sync.set({ disableOldReddit: !event.target.checked }); +disableReddit.addEventListener("change", (event) => { + browser.storage.sync.set({ disableReddit: !event.target.checked }); }); disableSearchEngine.addEventListener("change", (event) => {