diff --git a/README.md b/README.md index 6e7f768a..25054855 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,17 @@ ## About -A web extension that redirects _Twitter, YouTube, Instagram, Google Maps, Reddit, Google Search, & Google Translate_ requests to privacy friendly alternative frontends for those sites - [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/), [SimplyTranslate](https://git.sr.ht/~metalune/simplytranslate_web) & Private Search Engines like [DuckDuckGo](https://duckduckgo.com) and [Startpage](https://startpage.com). +A web extension that redirects _Twitter, YouTube, Instagram, Google Maps, +Reddit, Medium, Google Search, & Google Translate_ requests to privacy friendly +alternatives for those sites - [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/), +[Scribe](https://sr.ht/~edwardloveall/scribe/), +[SimplyTranslate](https://git.sr.ht/~metalune/simplytranslate_web) & +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. @@ -47,6 +57,10 @@ Privacy Redirect allows setting custom instances, instances can be found here: - [Mojeek](https://www.mojeek.com) - [Presearch](https://www.presearch.org) - [Whoogle](https://benbusby.com/projects/whoogle-search/) +- [Scribe](https://sr.ht/~edwardloveall/scribe/) instances:, an alternative frontend for Medium: + - [scribe.rip](https://scribe.rip/) + - [NixNet scribe](https://scribe.nixnet.services/) + - [Citizen4 scribe](https://scribe.citizen4.eu/) ## Development diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 18a4754e..b2988eca 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -11,6 +11,10 @@ "message": "Nitter Instance", "description": "Label for Nitter instance field option (options)." }, + "scribeInstance": { + "message": "Scribe Instance", + "description": "Label for Scribe instance field option (options)." + }, "invidiousInstance": { "message": "Invidious Instance", "description": "Label for Invidious instance field option (options)." @@ -43,6 +47,10 @@ "message": "Nitter Redirects", "description": "Label for enable/disable Nitter redirects option (options & pop-up)." }, + "disableScribe": { + "message": "Scribe Redirects", + "description": "Label for enable/disable Scribe redirects option (options & pop-up)." + }, "disableInvidious": { "message": "Invidious Redirects", "description": "Label for enable/disable Invidious redirects option (options & pop-up)." @@ -147,6 +155,10 @@ "message": "Nitter random instance pool (comma-separated)", "description": "Label for 'Nitter random instance pool (comma-separated)' option (options)." }, + "scribeRandomPool": { + "message": "Scribe random instance pool (comma-separated)", + "description": "Label for 'Scribe random instance pool (comma-separated)' option (options)." + }, "invidiousRandomPool": { "message": "Invidious random instance pool (comma-separated)", "description": "Label for 'Invidious random instance pool (comma-separated)' option (options)." diff --git a/src/assets/javascripts/helpers/medium.js b/src/assets/javascripts/helpers/medium.js new file mode 100644 index 00000000..7d4007d6 --- /dev/null +++ b/src/assets/javascripts/helpers/medium.js @@ -0,0 +1,27 @@ +const targets = [ + "medium.com", + /.*.medium.com/, + /* Other domains of medium blogs, source(s): + * https://findingtom.com/best-medium-blogs-to-follow/#1-forge + * */ + "towardsdatascience.com", + "uxdesign.cc", + "uxplanet.org", + "betterprogramming.pub", + "aninjusticemag.com", + "betterhumans.pub", + "psiloveyou.xyz", + "entrepreneurshandbook.co", + "blog.coinbase.com" +]; + +const redirects = [ + "https://scribe.rip", + "https://scribe.nixnet.services" + "https://scribe.citizen4.eu" +]; + +export default { + targets, + redirects, +}; diff --git a/src/pages/background/background.js b/src/pages/background/background.js index 9b8c3a13..741bf6a1 100644 --- a/src/pages/background/background.js +++ b/src/pages/background/background.js @@ -5,6 +5,7 @@ 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 mediumHelper from "../../assets/javascripts/helpers/medium.js"; import redditHelper from "../../assets/javascripts/helpers/reddit.js"; import searchHelper from "../../assets/javascripts/helpers/google-search.js"; import googleTranslateHelper from "../../assets/javascripts/helpers/google-translate.js"; @@ -13,6 +14,9 @@ import wikipediaHelper from "../../assets/javascripts/helpers/wikipedia.js"; const nitterInstances = twitterHelper.redirects; const twitterDomains = twitterHelper.targets; const youtubeDomains = youtubeHelper.targets; +const mediumDomains = mediumHelper.targets; +const scribeInstances = mediumHelper.redirects; +const scribeDefault = mediumHelper.redirects[0]; const invidiousInstances = youtubeHelper.redirects; const instagramDomains = instagramHelper.targets; const bibliogramInstances = instagramHelper.redirects; @@ -43,6 +47,7 @@ let disableInvidious; let disableBibliogram; let disableOsm; let disableReddit; +let disableScribe; let disableSearchEngine; let disableSimplyTranslate; let disableWikipedia; @@ -50,6 +55,7 @@ let nitterInstance; let invidiousInstance; let bibliogramInstance; let osmInstance; +let scribeInstance; let redditInstance; let searchEngineInstance; let simplyTranslateInstance; @@ -66,6 +72,7 @@ let useFreeTube; let nitterRandomPool; let invidiousRandomPool; let bibliogramRandomPool; +let scribeRandomPool; let exceptions; window.browser = window.browser || window.chrome; @@ -77,6 +84,7 @@ browser.storage.sync.get( "bibliogramInstance", "osmInstance", "redditInstance", + "scribeInstance", "searchEngineInstance", "simplyTranslateInstance", "wikipediaInstance", @@ -85,6 +93,7 @@ browser.storage.sync.get( "disableBibliogram", "disableOsm", "disableReddit", + "disableScribe", "disableSearchEngine", "disableSimplyTranslate", "disableWikipedia", @@ -100,6 +109,7 @@ browser.storage.sync.get( "nitterRandomPool", "invidiousRandomPool", "bibliogramRandomPool", + "scribeRandomPool", "exceptions", ], (result) => { @@ -108,11 +118,13 @@ browser.storage.sync.get( bibliogramInstance = result.bibliogramInstance; osmInstance = result.osmInstance || osmDefault; redditInstance = result.redditInstance || redditDefault; + scribeInstance = result.scribeInstance; searchEngineInstance = result.searchEngineInstance; simplyTranslateInstance = result.simplyTranslateInstance || simplyTranslateDefault; wikipediaInstance = result.wikipediaInstance || wikipediaDefault; disableNitter = result.disableNitter; + disableScribe = result.disableScribe; disableInvidious = result.disableInvidious; disableBibliogram = result.disableBibliogram; disableOsm = result.disableOsm; @@ -143,6 +155,9 @@ browser.storage.sync.get( bibliogramRandomPool = result.bibliogramRandomPool ? result.bibliogramRandomPool.split(",") : commonHelper.filterInstances(bibliogramInstances); + scribeRandomPool = result.scribeRandomPool + ? result.scribeRandomPool.split(",") + : commonHelper.filterInstances(scribeInstances); } ); @@ -169,12 +184,18 @@ browser.storage.onChanged.addListener((changes) => { if ("redditInstance" in changes) { redditInstance = changes.redditInstance.newValue || redditDefault; } + if ("scribeInstance" in changes) { + scribeInstance = changes.scribeInstance.newValue || scribeDefault; + } if ("searchEngineInstance" in changes) { searchEngineInstance = changes.searchEngineInstance.newValue; } if ("disableNitter" in changes) { disableNitter = changes.disableNitter.newValue; } + if ("disableScribe" in changes) { + disableScribe = changes.disableScribe.newValue; + } if ("disableInvidious" in changes) { disableInvidious = changes.disableInvidious.newValue; } @@ -232,6 +253,9 @@ browser.storage.onChanged.addListener((changes) => { if ("bibliogramRandomPool" in changes) { bibliogramRandomPool = changes.bibliogramRandomPool.newValue.split(","); } + if ("scribeRandomPool" in changes) { + scribeRandomPool = changes.scribeRandomPool.newValue.split(","); + } if ("exceptions" in changes) { exceptions = changes.exceptions.newValue.map((e) => { return new RegExp(e); @@ -515,6 +539,27 @@ function redirectReddit(url, initiator, type) { return `${redditInstance}${url.pathname}${url.search}`; } +function redirectMedium(url, initiator) { + if (disableScribe || isException(url, initiator)) { + return null; + } + if ( + isFirefox() && + initiator && + (initiator.origin === scribeInstance || + scribeInstances.includes(initiator.origin) || + mediumDomains.includes(initiator.host)) + ) { + browser.storage.sync.set({ + redirectBypassFlag: true, + }); + return null; + } + return `${ + scribeInstance || commonHelper.getRandomInstance(scribeRandomPool) + }${url.pathname}${url.search}`; +} + function redirectSearchEngine(url, initiator) { if (disableSearchEngine || isException(url, initiator)) { return null; @@ -607,6 +652,10 @@ browser.webRequest.onBeforeRequest.addListener( redirect = { redirectUrl: redirectReddit(url, initiator, details.type), }; + } else if (mediumDomains.includes(url.host)) { + redirect = { + redirectUrl: redirectMedium(url, initiator), + }; } else if (url.href.match(googleSearchRegex)) { redirect = { redirectUrl: redirectSearchEngine(url, initiator), diff --git a/src/pages/options/options.html b/src/pages/options/options.html index 65f1e9ab..5b68ed10 100644 --- a/src/pages/options/options.html +++ b/src/pages/options/options.html @@ -141,6 +141,28 @@

+ +
+ + + + + + + +
+

+ Scribe Redirects +

+
+   + +
@@ -188,7 +210,7 @@

SimplyTranslate Redirects

-

Wikipedia Redirects

+

Wikipedia Redirects

Reddit Instance /> +
+

Scribe Instance

+
+ +
+

Search Engine Instance

@@ -557,6 +592,16 @@

type="text" />

+
+

+ Scribe random instance pool (comma-separated) +

+ +

diff --git a/src/pages/options/options.js b/src/pages/options/options.js index 91e7ac05..4a148dfd 100644 --- a/src/pages/options/options.js +++ b/src/pages/options/options.js @@ -6,6 +6,7 @@ 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 mediumHelper from "../../assets/javascripts/helpers/medium.js"; import searchHelper from "../../assets/javascripts/helpers/google-search.js"; import googleTranslateHelper from "../../assets/javascripts/helpers/google-translate.js"; import wikipediaHelper from "../../assets/javascripts/helpers/wikipedia.js"; @@ -15,6 +16,7 @@ const invidiousInstances = youtubeHelper.redirects; const bibliogramInstances = instagramHelper.redirects; const osmInstances = mapsHelper.redirects; const redditInstances = redditHelper.redirects; +const scribeInstances = mediumHelper.redirects; const searchEngineInstances = searchHelper.redirects; const simplyTranslateInstances = googleTranslateHelper.redirects; const wikipediaInstances = wikipediaHelper.redirects; @@ -24,6 +26,7 @@ const autocompletes = [ { id: "bibliogram-instance", instances: bibliogramInstances }, { id: "osm-instance", instances: osmInstances }, { id: "reddit-instance", instances: redditInstances }, + { id: "scribe-instance", instances: scribeInstances }, { id: "search-engine-instance", instances: searchEngineInstances.map((instance) => instance.link), @@ -38,6 +41,7 @@ let invidiousInstance = document.getElementById("invidious-instance"); let bibliogramInstance = document.getElementById("bibliogram-instance"); let osmInstance = document.getElementById("osm-instance"); let redditInstance = document.getElementById("reddit-instance"); +let scribeInstance = document.getElementById("scribe-instance"); let searchEngineInstance = document.getElementById("search-engine-instance"); let simplyTranslateInstance = document.getElementById( "simply-translate-instance" @@ -48,6 +52,7 @@ let disableInvidious = document.getElementById("disable-invidious"); let disableBibliogram = document.getElementById("disable-bibliogram"); let disableOsm = document.getElementById("disable-osm"); let disableReddit = document.getElementById("disable-reddit"); +let disableScribe = document.getElementById("disable-scribe"); let disableSearchEngine = document.getElementById("disable-search-engine"); let disableSimplyTranslate = document.getElementById( "disable-simply-translate" @@ -68,6 +73,7 @@ let useFreeTube = document.getElementById("use-freetube"); let nitterRandomPool = document.getElementById("nitter-random-pool"); let invidiousRandomPool = document.getElementById("invidious-random-pool"); let bibliogramRandomPool = document.getElementById("bibliogram-random-pool"); +let scribeRandomPool = document.getElementById("scribe-random-pool"); let exceptions; window.browser = window.browser || window.chrome; @@ -103,6 +109,7 @@ browser.storage.sync.get( "bibliogramInstance", "osmInstance", "redditInstance", + "scribeInstance", "searchEngineInstance", "simplyTranslateInstance", "wikipediaInstance", @@ -111,6 +118,7 @@ browser.storage.sync.get( "disableBibliogram", "disableOsm", "disableReddit", + "disableScribe", "disableSearchEngine", "disableSimplyTranslate", "disableWikipedia", @@ -130,6 +138,7 @@ browser.storage.sync.get( "nitterRandomPool", "invidiousRandomPool", "bibliogramRandomPool", + "scribeRandomPool", ], (result) => { theme.value = result.theme || ""; @@ -139,6 +148,7 @@ browser.storage.sync.get( bibliogramInstance.value = result.bibliogramInstance || ""; osmInstance.value = result.osmInstance || ""; redditInstance.value = result.redditInstance || ""; + scribeInstance.value = result.scribeInstance || ""; searchEngineInstance.value = (result.searchEngineInstance && result.searchEngineInstance.link) || ""; simplyTranslateInstance.value = result.simplyTranslateInstance || ""; @@ -148,6 +158,7 @@ browser.storage.sync.get( disableBibliogram.checked = !result.disableBibliogram; disableOsm.checked = !result.disableOsm; disableReddit.checked = !result.disableReddit; + disableScribe.checked = !result.disableScribe; disableSearchEngine.checked = !result.disableSearchEngine; disableSimplyTranslate.checked = !result.disableSimplyTranslate; disableWikipedia.checked = !result.disableWikipedia; @@ -175,6 +186,9 @@ browser.storage.sync.get( bibliogramRandomPool.value = result.bibliogramRandomPool || commonHelper.filterInstances(bibliogramInstances); + scribeRandomPool.value = + result.scribeRandomPool || + commonHelper.filterInstances(scribeInstances); } ); @@ -311,6 +325,15 @@ const redditInstanceChange = debounce(() => { }, 500); redditInstance.addEventListener("input", redditInstanceChange); +const scribeInstanceChange = debounce(() => { + if (scribeInstance.checkValidity()) { + browser.storage.sync.set({ + scribeInstance: parseURL(scribeInstance.value), + }); + } +}, 500); +scribeInstance.addEventListener("input", scribeInstanceChange); + const searchEngineInstanceChange = debounce(() => { const instance = searchEngineInstances.find( (instance) => instance.link === searchEngineInstance.value @@ -369,6 +392,10 @@ disableReddit.addEventListener("change", (event) => { browser.storage.sync.set({ disableReddit: !event.target.checked }); }); +disableScribe.addEventListener("change", (event) => { + browser.storage.sync.set({ disableScribe: !event.target.checked }); +}); + disableSearchEngine.addEventListener("change", (event) => { browser.storage.sync.set({ disableSearchEngine: !event.target.checked }); }); @@ -454,6 +481,13 @@ const bibliogramRandomPoolChange = debounce(() => { }, 500); bibliogramRandomPool.addEventListener("input", bibliogramRandomPoolChange); +const scribeRandomPoolChange = debounce(() => { + browser.storage.sync.set({ + scribeRandomPool: scribeRandomPool.value, + }); +}, 500); +scribeRandomPool.addEventListener("input", scribeRandomPoolChange); + theme.addEventListener("change", (event) => { const value = event.target.options[theme.selectedIndex].value; switch (value) { diff --git a/src/pages/popup/popup.html b/src/pages/popup/popup.html index 9df46862..6b084880 100644 --- a/src/pages/popup/popup.html +++ b/src/pages/popup/popup.html @@ -187,24 +187,46 @@

+ + + + + + +
+

+ Wikipedia Redirects +

+
+   + +
+
+ +
+ diff --git a/src/pages/popup/popup.js b/src/pages/popup/popup.js index 4309c601..13d04f6b 100644 --- a/src/pages/popup/popup.js +++ b/src/pages/popup/popup.js @@ -8,6 +8,7 @@ let disableReddit = document.querySelector("#disable-reddit"); let disableSearchEngine = document.querySelector("#disable-searchEngine"); let disableSimplyTranslate = document.querySelector("#disable-simplyTranslate"); let disableWikipedia = document.querySelector("#disable-wikipedia"); +let disableScribe = document.querySelector("#disable-scribe"); let version = document.querySelector("#version"); window.browser = window.browser || window.chrome; @@ -22,6 +23,7 @@ browser.storage.sync.get( "disableSearchEngine", "disableSimplyTranslate", "disableWikipedia", + "disableScribe", "theme", ], (result) => { @@ -34,6 +36,7 @@ browser.storage.sync.get( disableSearchEngine.checked = !result.disableSearchEngine; disableSimplyTranslate.checked = !result.disableSimplyTranslate; disableWikipedia.checked = !result.disableWikipedia; + disableScribe.checked = !result.disableScribe; } ); @@ -71,6 +74,10 @@ disableWikipedia.addEventListener("change", (event) => { browser.storage.sync.set({ disableWikipedia: !event.target.checked }); }); +disableScribe.addEventListener("change", (event) => { + browser.storage.sync.set({ disableScribe: !event.target.checked }); +}); + document.querySelector("#more-options").addEventListener("click", () => { browser.runtime.openOptionsPage(); });

- Wikipedia Redirects + Scribe Redirects

  - +