diff options
-rw-r--r-- | README.md | 20 | ||||
-rw-r--r-- | _locales/en/messages.json | 16 | ||||
-rw-r--r-- | _locales/ru/messages.json | 2 | ||||
-rw-r--r-- | assets/javascript/remove-twitter-sw.js | 92 | ||||
-rw-r--r-- | manifest.json | 49 | ||||
-rw-r--r-- | pages/options/options.html | 569 | ||||
-rw-r--r-- | src/assets/images/Screen Shot Chrome 1.png (renamed from assets/images/Screen Shot Chrome 1.png) | bin | 331026 -> 331026 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot Chrome 2.png (renamed from assets/images/Screen Shot Chrome 2.png) | bin | 704517 -> 704517 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot Chrome 3.png (renamed from assets/images/Screen Shot Chrome 3.png) | bin | 180386 -> 180386 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot Chrome 4.png (renamed from assets/images/Screen Shot Chrome 4.png) | bin | 1038484 -> 1038484 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot Chrome 5.png (renamed from assets/images/Screen Shot Chrome 5.png) | bin | 191954 -> 191954 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot FF 1.png (renamed from assets/images/Screen Shot FF 1.png) | bin | 335716 -> 335716 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot FF 2.png (renamed from assets/images/Screen Shot FF 2.png) | bin | 2093693 -> 2093693 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot FF 3.png (renamed from assets/images/Screen Shot FF 3.png) | bin | 228957 -> 228957 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot FF 4.png (renamed from assets/images/Screen Shot FF 4.png) | bin | 2866335 -> 2866335 bytes | |||
-rw-r--r-- | src/assets/images/Screen Shot FF 5.png (renamed from assets/images/Screen Shot FF 5.png) | bin | 256223 -> 256223 bytes | |||
-rw-r--r-- | src/assets/images/badge-amo.png (renamed from assets/images/badge-amo.png) | bin | 2750 -> 2750 bytes | |||
-rw-r--r-- | src/assets/images/badge-chrome.png (renamed from assets/images/badge-chrome.png) | bin | 2391 -> 2391 bytes | |||
-rw-r--r-- | src/assets/images/badge-ms.png (renamed from assets/images/badge-ms.png) | bin | 9320 -> 9320 bytes | |||
-rw-r--r-- | src/assets/images/buy-me-a-coffee.png (renamed from assets/images/buy-me-a-coffee.png) | bin | 3926 -> 3926 bytes | |||
-rw-r--r-- | src/assets/images/chevron-down.svg (renamed from assets/images/chevron-down.svg) | 0 | ||||
-rw-r--r-- | src/assets/images/icon128.png (renamed from assets/images/icon128.png) | bin | 1773 -> 1773 bytes | |||
-rw-r--r-- | src/assets/images/icon16.png (renamed from assets/images/icon16.png) | bin | 709 -> 709 bytes | |||
-rw-r--r-- | src/assets/images/icon32.png (renamed from assets/images/icon32.png) | bin | 1162 -> 1162 bytes | |||
-rw-r--r-- | src/assets/images/icon48.png (renamed from assets/images/icon48.png) | bin | 690 -> 690 bytes | |||
-rw-r--r-- | src/assets/images/logo-small.png (renamed from assets/images/logo-small.png) | bin | 14128 -> 14128 bytes | |||
-rw-r--r-- | src/assets/images/logo-store.png (renamed from assets/images/logo-store.png) | bin | 89803 -> 89803 bytes | |||
-rw-r--r-- | src/assets/images/logo-tile.png (renamed from assets/images/logo-tile.png) | bin | 14751 -> 14751 bytes | |||
-rw-r--r-- | src/assets/images/logo.png (renamed from assets/images/logo.png) | bin | 16364 -> 16364 bytes | |||
-rw-r--r-- | src/assets/javascripts/helpers/common.js | 9 | ||||
-rw-r--r-- | src/assets/javascripts/helpers/google-maps.js | 43 | ||||
-rw-r--r-- | src/assets/javascripts/helpers/google-search.js | 9 | ||||
-rw-r--r-- | src/assets/javascripts/helpers/instagram.js | 47 | ||||
-rw-r--r-- | src/assets/javascripts/helpers/reddit.js | 24 | ||||
-rw-r--r-- | src/assets/javascripts/helpers/twitter.js | 38 | ||||
-rw-r--r-- | src/assets/javascripts/helpers/youtube.js | 33 | ||||
-rw-r--r-- | src/assets/javascripts/localise.js (renamed from assets/javascript/localise.js) | 0 | ||||
-rw-r--r-- | src/assets/javascripts/persist-invidious-prefs.js (renamed from assets/javascript/persist-invidious-prefs.js) | 0 | ||||
-rw-r--r-- | src/assets/javascripts/remove-twitter-sw.js | 89 | ||||
-rw-r--r-- | src/assets/stylesheets/styles.css (renamed from pages/styles.css) | 49 | ||||
-rw-r--r-- | src/pages/background/background.html | 1 | ||||
-rw-r--r-- | src/pages/background/background.js (renamed from background.js) | 305 | ||||
-rw-r--r-- | src/pages/options/options.html | 585 | ||||
-rw-r--r-- | src/pages/options/options.js (renamed from pages/options/options.js) | 162 | ||||
-rw-r--r-- | src/pages/popup/popup.html (renamed from pages/popup/popup.html) | 20 | ||||
-rw-r--r-- | src/pages/popup/popup.js (renamed from pages/popup/popup.js) | 10 |
46 files changed, 1146 insertions, 1026 deletions
diff --git a/README.md b/README.md index 820daebb..ce9ee7de 100644 --- a/README.md +++ b/README.md @@ -5,32 +5,36 @@ [](https://liberapay.com/SimonBrazell/donate) [](https://www.buymeacoffee.com/SimonBrazell) ## Get -[](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/) -[](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb) + +[](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/) +[](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb) [](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 3748db3b..8f698af8 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 30cee49f..a993f042 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 f74ff89f..00000000 --- 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 0fc6f104..04ea6c16 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", "<all_urls>"], "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 bd7cee7e..00000000 --- a/pages/options/options.html +++ /dev/null @@ -1,569 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <title></title> - <link href="../styles.css" rel="stylesheet" /> - <title>Privacy Redirect Options</title> - </head> - - <body> - <div class="tab"> - <button - class="tablinks" - id="general-tab" - data-localise="__MSG_generalTab__" - > - General - </button> - <button - class="tablinks" - id="advanced-tab" - data-localise="__MSG_advancedTab__" - > - Advanced - </button> - <button - class="tablinks" - id="exceptions-tab" - data-localise="__MSG_exceptionsTab__" - > - Exceptions - </button> - </div> - - <div id="general" class="tabcontent"> - <section class="settings-block"> - <table class="option" aria-label="Toggle Nitter redirects"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_disableNitter__">Nitter Redirects</h1> - </td> - <td> - <input - aria-hidden="true" - id="disable-nitter" - type="checkbox" - checked - /> - <label for="disable-nitter" class="checkbox-label"></label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <table class="option" aria-label="Toggle Invidious redirects"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_disableInvidious__"> - Invidious Redirects - </h1> - </td> - <td> - <input - aria-hidden="true" - id="disable-invidious" - type="checkbox" - checked - /> - <label for="disable-invidious" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <table class="option" aria-label="Toggle Bibliogram redirects"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_disableBibliogram__"> - Bibliogram Redirects - </h1> - </td> - <td> - <input - aria-hidden="true" - id="disable-bibliogram" - type="checkbox" - checked - /> - <label for="disable-bibliogram" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <table class="option" aria-label="Toggle OpenStreetMap redirects"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_disableOsm__"> - OpenStreetMap Redirects - </h1> - </td> - <td> - <input - aria-hidden="true" - id="disable-osm" - type="checkbox" - checked - /> - <label for="disable-osm" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <table class="option" aria-label="Toggle old Reddit redirects"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_disableOldReddit__"> - Old Reddit Redirects - </h1> - </td> - <td> - <input - aria-hidden="true" - id="disable-old-reddit" - type="checkbox" - checked - /> - <label for="disable-old-reddit" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <table class="option" aria-label="Toggle Search Engine redirects"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_disableSearchEngine__"> - Search Engine Redirects - </h1> - </td> - <td> - <input - aria-hidden="true" - id="disable-searchEngine" - type="checkbox" - checked - /> - <label for="disable-searchEngine" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_nitterInstance__">Nitter Instance</h1> - <div class="autocomplete"> - <input - id="nitter-instance" - type="url" - name="nitter-instance" - placeholder="Random instance (none selected)" - /> - </div> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_invidiousInstance__">Invidious Instance</h1> - <div class="autocomplete"> - <input - id="invidious-instance" - type="url" - placeholder="Random instance (none selected)" - /> - </div> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_bibliogramInstance__">Bibliogram Instance</h1> - <div class="autocomplete"> - <input - id="bibliogram-instance" - type="url" - placeholder="Random instance (none selected)" - /> - </div> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_osmInstance__">OpenStreetMap Instance</h1> - <div class="autocomplete"> - <input - id="osm-instance" - type="url" - placeholder="https://openstreetmap.org" - /> - </div> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_oldRedditView__">Old Reddit View (Desktop or Mobile)</h1> - <div class="autocomplete"> - <input - id="old-reddit-view" - type="url" - placeholder="https://old.reddit.com" - /> - </div> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_theme__">Theme</h1> - <select id="theme"> - <option value="">System</option> - <option value="light-theme">Light</option> - <option value="dark-theme">Dark</option> - </select> - </section> - </div> - - <div id="advanced" class="tabcontent"> - <div class="subheading"> - <h1>Invidious</h1> - <hr> - </div> - <section class="settings-block"> - <h1 data-localise="__MSG_invidiousRandomPool__"> - Invidious random instance pool (comma-separated) - </h1> - <input - id="invidious-random-pool" - name="invidious-random-pool" - type="text" - /> - </section> - <section class="settings-block"> - <table - class="option" - aria-label="Redirect YouTube to FreeTube where possible" - > - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_useFreeTube__"> - Use FreeTube over Invidious when possible - </h1> - </td> - <td> - <input - aria-hidden="true" - id="use-freetube" - type="checkbox" - checked - /> - <label for="use-freetube" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <table - class="option" - aria-label="Always proxy videos through Invidious" - > - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_alwaysProxy__"> - Always proxy videos through Invidious - </h1> - </td> - <td> - <input - aria-hidden="true" - id="always-proxy" - type="checkbox" - checked - /> - <label for="always-proxy" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <table - class="option" - aria-label="Only redirect embedded video to Invidious" - > - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_onlyEmbeddedVideo__"> - Only redirect embedded video to Invidious - </h1> - </td> - <td> - <input - aria-hidden="true" - id="only-embed" - type="checkbox" - checked - /> - <label for="only-embed" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_videoQuality__">Invidious Video Quality</h1> - <select id="video-quality"> - <option value="">Default</option> - <option value="hd720">720p</option> - <option value="medium">480p</option> - <option value="dash">DASH (Dynamic Adaptive Streaming over HTTP)</option> - </option> - </select> - </section> - <section class="settings-block"> - <table class="option" aria-label="Invidious dark mode aways on"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_invidiousDarkMode__"> - Invidious dark mode always on - </h1> - </td> - <td> - <input - aria-hidden="true" - id="invidious-dark-mode" - type="checkbox" - checked - /> - <label for="invidious-dark-mode" class="checkbox-label"> - </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_invidiousVolume__"> - Invidious Volume - </h1> - <input - id="invidious-volume" - name="invidious-volume" - type="range" - min="0" - max="100" - step="1" - /><span id="volume-value"></span> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_invidiousPlayerStyle__"> - Invidious Player Style - </h1> - <select id="invidious-player-style"> - <option value="">Invidious</option> - <option value="youtube">YouTube</option> - </select> - </section> - <section class="settings-block"> - <h1 data-localise="__MSG_invidiousSubtitles__"> - Invidious Subtitles - language codes (comma-separated) - </h1> - <input - id="invidious-subtitles" - name="invidious-subtitles" - type="text" - /> - </section> - <section class="settings-block"> - <table - class="option" - aria-label="Invidious automatically play video on load" - > - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_invidiousAutoplay__"> - Invidious automatically play video on load - </h1> - </td> - <td> - <input - aria-hidden="true" - id="invidious-autoplay" - type="checkbox" - checked - /> - <label for="invidious-autoplay" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <section class="settings-block"> - <table class="option" aria-label="Persist Invidious preferences"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_persistInvidiousPrefs__"> - Persist Invidious preferences (as cookie) - </h1> - </td> - <td> - <input - aria-hidden="true" - id="persist-invidious-prefs" - type="checkbox" - checked - /> - <label for="persist-invidious-prefs" class="checkbox-label"> - </label> - </td> - </tr> - </tbody> - </table> - </section> - <div class="subheading"> - <h1>Nitter</h1> - <hr> - </div> - <section class="settings-block"> - <h1 data-localise="__MSG_nitterRandomPool__"> - Nitter random instance pool (comma-separated) - </h1> - <input - id="nitter-random-pool" - name="nitter-random-pool" - type="text" - /> - </section> - <section class="settings-block"> - <table - class="option" - aria-label="Proactively remove Twitter service worker" - > - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_removeTwitterSW__"> - Proactively remove Twitter service worker - </h1> - </td> - <td> - <input - aria-hidden="true" - id="remove-twitter-sw" - type="checkbox" - checked - /> - <label for="remove-twitter-sw" class="checkbox-label"> </label> - </td> - </tr> - </tbody> - </table> - </section> - <div class="subheading"> - <h1>Bibliogram</h1> - <hr> - </div> - <section class="settings-block"> - <h1 data-localise="__MSG_bibliogramRandomPool__"> - Bibliogram random instance pool (comma-separated) - </h1> - <input - id="bibliogram-random-pool" - name="bibliogram-random-pool" - type="text" - /> - </section> - </div> - - <div id="exceptions" class="tabcontent"> - <section class="settings-block"> - <p data-localise="__MSG_exceptionsDescriptionP1__"> - Enter a URL or Regular Expression to be excluded from redirects. - </p> - <p data-localise="__MSG_exceptionsDescriptionP2__"> - All requests for or initiating from a URL that matches your exception - will be excluded from redirects. - </p> - <p data-localise="__MSG_exceptionsDescriptionP3__"> - Note - Supports JavaScript regular expressions, excluding the - enclosing forward slashes. - </p> - </section> - <section class="settings-block"> - <table class="exceptions option"> - <tbody> - <tr> - <td> - <h1 data-localise="__MSG_addException__">Add Exception</h1> - </td> - </tr> - <tr> - <td> - <input - id="new-exceptions-item" - type="text" - placeholder="URL or RegExp" - /> - </td> - <td> - <input type="radio" id="url" name="type" value="URL" checked /> - <label class="radio" for="url">URL</label> - <input type="radio" id="regExp" name="type" value="RegExp" /> - <label class="radio" for="regExp">RegExp</label> - </td> - <td> - <button id="add-to-exceptions"> - <svg - xmlns="http://www.w3.org/2000/svg" - width="512" - height="512" - viewBox="0 0 512 512" - > - <line - x1="256" - y1="112" - x2="256" - y2="400" - style=" - fill: none; - stroke: #fff; - stroke-linecap: round; - stroke-linejoin: round; - stroke-width: 32px; - " - /> - <line - x1="400" - y1="256" - x2="112" - y2="256" - style=" - fill: none; - stroke: #fff; - stroke-linecap: round; - stroke-linejoin: round; - stroke-width: 32px; - " - /> - </svg> - </button> - </td> - </tr> - </tbody> - </table> - </section> - <ul id="exceptions-items"></ul> - </div> - - <script src="./options.js"></script> - <script src="../../assets/javascript/localise.js"></script> - </body> -</html> diff --git a/assets/images/Screen Shot Chrome 1.png b/src/assets/images/Screen Shot Chrome 1.png index 1628b509..1628b509 100644 --- a/assets/images/Screen Shot Chrome 1.png +++ b/src/assets/images/Screen Shot Chrome 1.png Binary files differdiff --git a/assets/images/Screen Shot Chrome 2.png b/src/assets/images/Screen Shot Chrome 2.png index 61eed643..61eed643 100644 --- a/assets/images/Screen Shot Chrome 2.png +++ b/src/assets/images/Screen Shot Chrome 2.png Binary files differdiff --git a/assets/images/Screen Shot Chrome 3.png b/src/assets/images/Screen Shot Chrome 3.png index 42c92014..42c92014 100644 --- a/assets/images/Screen Shot Chrome 3.png +++ b/src/assets/images/Screen Shot Chrome 3.png Binary files differdiff --git a/assets/images/Screen Shot Chrome 4.png b/src/assets/images/Screen Shot Chrome 4.png index 8bae0410..8bae0410 100644 --- a/assets/images/Screen Shot Chrome 4.png +++ b/src/assets/images/Screen Shot Chrome 4.png Binary files differdiff --git a/assets/images/Screen Shot Chrome 5.png b/src/assets/images/Screen Shot Chrome 5.png index d3f54841..d3f54841 100644 --- a/assets/images/Screen Shot Chrome 5.png +++ b/src/assets/images/Screen Shot Chrome 5.png Binary files differdiff --git a/assets/images/Screen Shot FF 1.png b/src/assets/images/Screen Shot FF 1.png index 7ae2e614..7ae2e614 100644 --- a/assets/images/Screen Shot FF 1.png +++ b/src/assets/images/Screen Shot FF 1.png Binary files differdiff --git a/assets/images/Screen Shot FF 2.png b/src/assets/images/Screen Shot FF 2.png index a995478a..a995478a 100644 --- a/assets/images/Screen Shot FF 2.png +++ b/src/assets/images/Screen Shot FF 2.png Binary files differdiff --git a/assets/images/Screen Shot FF 3.png b/src/assets/images/Screen Shot FF 3.png index fc3232b6..fc3232b6 100644 --- a/assets/images/Screen Shot FF 3.png +++ b/src/assets/images/Screen Shot FF 3.png Binary files differdiff --git a/assets/images/Screen Shot FF 4.png b/src/assets/images/Screen Shot FF 4.png index f230fed2..f230fed2 100644 --- a/assets/images/Screen Shot FF 4.png +++ b/src/assets/images/Screen Shot FF 4.png Binary files differdiff --git a/assets/images/Screen Shot FF 5.png b/src/assets/images/Screen Shot FF 5.png index 420838d9..420838d9 100644 --- a/assets/images/Screen Shot FF 5.png +++ b/src/assets/images/Screen Shot FF 5.png Binary files differdiff --git a/assets/images/badge-amo.png b/src/assets/images/badge-amo.png index 9dbb7e46..9dbb7e46 100644 --- a/assets/images/badge-amo.png +++ b/src/assets/images/badge-amo.png Binary files differdiff --git a/assets/images/badge-chrome.png b/src/assets/images/badge-chrome.png index afd2c6b2..afd2c6b2 100644 --- a/assets/images/badge-chrome.png +++ b/src/assets/images/badge-chrome.png Binary files differdiff --git a/assets/images/badge-ms.png b/src/assets/images/badge-ms.png index 1b1dcbc9..1b1dcbc9 100644 --- a/assets/images/badge-ms.png +++ b/src/assets/images/badge-ms.png Binary files differdiff --git a/assets/images/buy-me-a-coffee.png b/src/assets/images/buy-me-a-coffee.png index 8d9ea893..8d9ea893 100644 --- a/assets/images/buy-me-a-coffee.png +++ b/src/assets/images/buy-me-a-coffee.png Binary files differdiff --git a/assets/images/chevron-down.svg b/src/assets/images/chevron-down.svg index 7679f267..7679f267 100644 --- a/assets/images/chevron-down.svg +++ b/src/assets/images/chevron-down.svg diff --git a/assets/images/icon128.png b/src/assets/images/icon128.png index cd16befd..cd16befd 100644 --- a/assets/images/icon128.png +++ b/src/assets/images/icon128.png Binary files differdiff --git a/assets/images/icon16.png b/src/assets/images/icon16.png index f896608b..f896608b 100644 --- a/assets/images/icon16.png +++ b/src/assets/images/icon16.png Binary files differdiff --git a/assets/images/icon32.png b/src/assets/images/icon32.png index c5b417cf..c5b417cf 100644 --- a/assets/images/icon32.png +++ b/src/assets/images/icon32.png Binary files differdiff --git a/assets/images/icon48.png b/src/assets/images/icon48.png index 24dd5af7..24dd5af7 100644 --- a/assets/images/icon48.png +++ b/src/assets/images/icon48.png Binary files differdiff --git a/assets/images/logo-small.png b/src/assets/images/logo-small.png index 27ca660a..27ca660a 100644 --- a/assets/images/logo-small.png +++ b/src/assets/images/logo-small.png Binary files differdiff --git a/assets/images/logo-store.png b/src/assets/images/logo-store.png index f321de43..f321de43 100644 --- a/assets/images/logo-store.png +++ b/src/assets/images/logo-store.png Binary files differdiff --git a/assets/images/logo-tile.png b/src/assets/images/logo-tile.png index 101c6b3a..101c6b3a 100644 --- a/assets/images/logo-tile.png +++ b/src/assets/images/logo-tile.png Binary files differdiff --git a/assets/images/logo.png b/src/assets/images/logo.png index ad854aaa..ad854aaa 100644 --- a/assets/images/logo.png +++ b/src/assets/images/logo.png Binary files differdiff --git a/src/assets/javascripts/helpers/common.js b/src/assets/javascripts/helpers/common.js new file mode 100644 index 00000000..6edd3d3c --- /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 00000000..3a041c67 --- /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 00000000..dc12042f --- /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 00000000..bd0ad9f5 --- /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 00000000..46fff4cf --- /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 00000000..1ebc025b --- /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 00000000..3d1fcd27 --- /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 index cbe5c191..cbe5c191 100644 --- a/assets/javascript/localise.js +++ b/src/assets/javascripts/localise.js diff --git a/assets/javascript/persist-invidious-prefs.js b/src/assets/javascripts/persist-invidious-prefs.js index 4c13a310..4c13a310 100644 --- a/assets/javascript/persist-invidious-prefs.js +++ b/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 00000000..c39b4c9e --- /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 index 022b96bd..e11f313b 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; +.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 h1 { +.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; } -.subheading hr { - height: 1px; +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 00000000..2d0fb686 --- /dev/null +++ b/src/pages/background/background.html @@ -0,0 +1 @@ +<script type="module" src="background.js"></script> diff --git a/background.js b/src/pages/background/background.js index 6fdce2d7..d5a19662 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) => { + nitterInstance = result.nitterInstance; + invidiousInstance = result.invidiousInstance; + bibliogramInstance = result.bibliogramInstance; + osmInstance = result.osmInstance || osmDefault; + redditInstance = result.redditInstance || redditDefault; + searchEngineInstance = result.searchEngineInstance; disableNitter = result.disableNitter; disableInvidious = result.disableInvidious; disableBibliogram = result.disableBibliogram; disableOsm = result.disableOsm; - disableOldReddit = result.disableOldReddit; + disableReddit = result.disableReddit; disableSearchEngine = result.disableSearchEngine; - nitterInstance = result.nitterInstance; - invidiousInstance = result.invidiousInstance; - bibliogramInstance = result.bibliogramInstance; - osmInstance = result.osmInstance || osmDefault; - oldRedditView = result.oldRedditView || oldRedditDefaultView; 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 00000000..af7bd41a --- /dev/null +++ b/src/pages/options/options.html @@ -0,0 +1,585 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title></title> + <link href="../../assets/stylesheets/styles.css" rel="stylesheet" /> + <title>Privacy Redirect Options</title> + </head> + + <body> + <div class="tab"> + <button + class="tablinks" + id="general-tab" + data-localise="__MSG_generalTab__" + > + General + </button> + <button + class="tablinks" + id="advanced-tab" + data-localise="__MSG_advancedTab__" + > + Advanced + </button> + <button + class="tablinks" + id="exceptions-tab" + data-localise="__MSG_exceptionsTab__" + > + Exceptions + </button> + </div> + + <div id="general" class="tabcontent"> + <section class="settings-block"> + <table class="option" aria-label="Toggle Nitter redirects"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_disableNitter__">Nitter Redirects</h1> + </td> + <td> + <input + aria-hidden="true" + id="disable-nitter" + type="checkbox" + checked + /> + <label for="disable-nitter" class="checkbox-label"></label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <table class="option" aria-label="Toggle Invidious redirects"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_disableInvidious__"> + Invidious Redirects + </h1> + </td> + <td> + <input + aria-hidden="true" + id="disable-invidious" + type="checkbox" + checked + /> + <label for="disable-invidious" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <table class="option" aria-label="Toggle Bibliogram redirects"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_disableBibliogram__"> + Bibliogram Redirects + </h1> + </td> + <td> + <input + aria-hidden="true" + id="disable-bibliogram" + type="checkbox" + checked + /> + <label for="disable-bibliogram" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <table class="option" aria-label="Toggle OpenStreetMap redirects"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_disableOsm__"> + OpenStreetMap Redirects + </h1> + </td> + <td> + <input + aria-hidden="true" + id="disable-osm" + type="checkbox" + checked + /> + <label for="disable-osm" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <table class="option" aria-label="Toggle Reddit redirects"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_disableReddit__"> + Reddit Redirects + </h1> + </td> + <td> + <input + aria-hidden="true" + id="disable-reddit" + type="checkbox" + checked + /> + <label for="disable-reddit" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <table class="option" aria-label="Toggle Search Engine redirects"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_disableSearchEngine__"> + Search Engine Redirects + </h1> + </td> + <td> + <input + aria-hidden="true" + id="disable-search-engine" + type="checkbox" + checked + /> + <label for="disable-search-engine" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_nitterInstance__">Nitter Instance</h1> + <div class="autocomplete"> + <input + id="nitter-instance" + type="url" + name="nitter-instance" + placeholder="Random instance (none selected)" + /> + </div> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_invidiousInstance__">Invidious Instance</h1> + <div class="autocomplete"> + <input + id="invidious-instance" + type="url" + placeholder="Random instance (none selected)" + /> + </div> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_bibliogramInstance__">Bibliogram Instance</h1> + <div class="autocomplete"> + <input + id="bibliogram-instance" + type="url" + placeholder="Random instance (none selected)" + /> + </div> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_osmInstance__">OpenStreetMap Instance</h1> + <div class="autocomplete"> + <input + id="osm-instance" + type="url" + placeholder="https://openstreetmap.org" + /> + </div> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_redditInstance__">Reddit Instance</h1> + <div class="autocomplete"> + <input + id="reddit-instance" + type="url" + placeholder="https://old.reddit.com" + /> + </div> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_searchEngineInstance__">Search Engine Instance</h1> + <div class="autocomplete"> + <input + id="search-engine-instance" + type="url" + placeholder="Random instance (none selected)" + /> + </div> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_theme__">Theme</h1> + <select id="theme"> + <option value="">System</option> + <option value="light-theme">Light</option> + <option value="dark-theme">Dark</option> + </select> + </section> + </div> + + <div id="advanced" class="tabcontent"> + <button type="button" class="collapsible"> + Invidious + </button> + <div class="collapsible-content"> + <section class="settings-block"> + <h1 data-localise="__MSG_invidiousRandomPool__"> + Invidious random instance pool (comma-separated) + </h1> + <input + id="invidious-random-pool" + name="invidious-random-pool" + type="text" + /> + </section> + <section class="settings-block"> + <table + class="option" + aria-label="Redirect YouTube to FreeTube where possible" + > + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_useFreeTube__"> + Use FreeTube over Invidious when possible + </h1> + </td> + <td> + <input + aria-hidden="true" + id="use-freetube" + type="checkbox" + checked + /> + <label for="use-freetube" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <table + class="option" + aria-label="Always proxy videos through Invidious" + > + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_alwaysProxy__"> + Always proxy videos through Invidious + </h1> + </td> + <td> + <input + aria-hidden="true" + id="always-proxy" + type="checkbox" + checked + /> + <label for="always-proxy" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <table + class="option" + aria-label="Only redirect embedded video to Invidious" + > + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_onlyEmbeddedVideo__"> + Only redirect embedded video to Invidious + </h1> + </td> + <td> + <input + aria-hidden="true" + id="only-embed" + type="checkbox" + checked + /> + <label for="only-embed" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_videoQuality__">Invidious Video Quality</h1> + <select id="video-quality"> + <option value="">Default</option> + <option value="hd720">720p</option> + <option value="medium">480p</option> + <option value="dash">DASH (Dynamic Adaptive Streaming over HTTP)</option> + </option> + </select> + </section> + <section class="settings-block"> + <table class="option" aria-label="Invidious dark mode aways on"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_invidiousDarkMode__"> + Invidious dark mode always on + </h1> + </td> + <td> + <input + aria-hidden="true" + id="invidious-dark-mode" + type="checkbox" + checked + /> + <label for="invidious-dark-mode" class="checkbox-label"> + </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_invidiousVolume__"> + Invidious Volume + </h1> + <input + id="invidious-volume" + name="invidious-volume" + type="range" + min="0" + max="100" + step="1" + /><span id="volume-value"></span> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_invidiousPlayerStyle__"> + Invidious Player Style + </h1> + <select id="invidious-player-style"> + <option value="">Invidious</option> + <option value="youtube">YouTube</option> + </select> + </section> + <section class="settings-block"> + <h1 data-localise="__MSG_invidiousSubtitles__"> + Invidious Subtitles - language codes (comma-separated) + </h1> + <input + id="invidious-subtitles" + name="invidious-subtitles" + type="text" + /> + </section> + <section class="settings-block"> + <table + class="option" + aria-label="Invidious automatically play video on load" + > + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_invidiousAutoplay__"> + Invidious automatically play video on load + </h1> + </td> + <td> + <input + aria-hidden="true" + id="invidious-autoplay" + type="checkbox" + checked + /> + <label for="invidious-autoplay" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <section class="settings-block"> + <table class="option" aria-label="Persist Invidious preferences"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_persistInvidiousPrefs__"> + Persist Invidious preferences (as cookie) + </h1> + </td> + <td> + <input + aria-hidden="true" + id="persist-invidious-prefs" + type="checkbox" + checked + /> + <label for="persist-invidious-prefs" class="checkbox-label"> + </label> + </td> + </tr> + </tbody> + </table> + </section> + <hr> + </div> + <button type="button" class="collapsible"> + Nitter + </button> + <div class="collapsible-content"> + <section class="settings-block"> + <h1 data-localise="__MSG_nitterRandomPool__"> + Nitter random instance pool (comma-separated) + </h1> + <input + id="nitter-random-pool" + name="nitter-random-pool" + type="text" + /> + </section> + <section class="settings-block"> + <table + class="option" + aria-label="Proactively remove Twitter service worker" + > + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_removeTwitterSW__"> + Proactively remove Twitter service worker + </h1> + </td> + <td> + <input + aria-hidden="true" + id="remove-twitter-sw" + type="checkbox" + checked + /> + <label for="remove-twitter-sw" class="checkbox-label"> </label> + </td> + </tr> + </tbody> + </table> + </section> + <hr> + </div> + <button type="button" class="collapsible"> + Bibliogram + </button> + <div class="collapsible-content"> + <section class="settings-block"> + <h1 data-localise="__MSG_bibliogramRandomPool__"> + Bibliogram random instance pool (comma-separated) + </h1> + <input + id="bibliogram-random-pool" + name="bibliogram-random-pool" + type="text" + /> + </section> + <hr> + </div> + </div> + + <div id="exceptions" class="tabcontent"> + <section class="settings-block"> + <p data-localise="__MSG_exceptionsDescriptionP1__"> + Enter a URL or Regular Expression to be excluded from redirects. + </p> + <p data-localise="__MSG_exceptionsDescriptionP2__"> + All requests for or initiating from a URL that matches your exception + will be excluded from redirects. + </p> + <p data-localise="__MSG_exceptionsDescriptionP3__"> + Note - Supports JavaScript regular expressions, excluding the + enclosing forward slashes. + </p> + </section> + <section class="settings-block"> + <table class="exceptions option"> + <tbody> + <tr> + <td> + <h1 data-localise="__MSG_addException__">Add Exception</h1> + </td> + </tr> + <tr> + <td> + <input + id="new-exceptions-item" + type="text" + placeholder="URL or RegExp" + /> + </td> + <td> + <input type="radio" id="url" name="type" value="URL" checked /> + <label class="radio" for="url">URL</label> + <input type="radio" id="regExp" name="type" value="RegExp" /> + <label class="radio" for="regExp">RegExp</label> + </td> + <td> + <button id="add-to-exceptions"> + <svg + xmlns="http://www.w3.org/2000/svg" + width="512" + height="512" + viewBox="0 0 512 512" + > + <line + x1="256" + y1="112" + x2="256" + y2="400" + style=" + fill: none; + stroke: #fff; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 32px; + " + /> + <line + x1="400" + y1="256" + x2="112" + y2="256" + style=" + fill: none; + stroke: #fff; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 32px; + " + /> + </svg> + </button> + </td> + </tr> + </tbody> + </table> + </section> + <ul id="exceptions-items"></ul> + </div> + + <script type="module" src="./options.js"></script> + <script src="../../assets/javascripts/localise.js"></script> + </body> +</html> diff --git a/pages/options/options.js b/src/pages/options/options.js index 2530a328..e6bd224a 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 index af44b23e..43a4a1a8 100644 --- a/pages/popup/popup.html +++ b/src/pages/popup/popup.html @@ -4,7 +4,7 @@ <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title></title> - <link href="../styles.css" rel="stylesheet" /> + <link href="../../assets/stylesheets/styles.css" rel="stylesheet" /> </head> <body class="popup"> @@ -121,30 +121,30 @@ <tbody> <tr> <td> - <h1 data-localise="__MSG_disableOldReddit__"> - Old Reddit Redirects - </h1> + <h1 data-localise="__MSG_disableReddit__">Reddit Redirects</h1> </td> <td> <input aria-hidden="true" - id="disable-old-reddit" + id="disable-reddit" type="checkbox" checked /> - <label for="disable-old-reddit" class="checkbox-label"> </label> + <label for="disable-reddit" class="checkbox-label"> </label> </td> </tr> </tbody> </table> </section> - + <section class="settings-block"> <table class="option" aria-label="Toggle Search Engine redirects"> <tbody> <tr> <td> - <h1 data-localise="__MSG_disableSearchEngine__">Search Engine Redirects</h1> + <h1 data-localise="__MSG_disableSearchEngine__"> + Search Engine Redirects + </h1> </td> <td> <input @@ -208,7 +208,7 @@ </a> </footer> - <script src="./popup.js"></script> - <script src="../../assets/javascript/localise.js"></script> + <script type="module" src="./popup.js"></script> + <script src="../../assets/javascripts/localise.js"></script> </body> </html> diff --git a/pages/popup/popup.js b/src/pages/popup/popup.js index 6d4c3ff7..0afb2f97 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) => { |