|
@ -0,0 +1,2 @@
|
|||
liberapay: SimonBrazell
|
||||
custom: https://www.buymeacoffee.com/SimonBrazell
|
15
README.md
|
@ -1,9 +1,10 @@
|
|||
# ![privacy-redirect](images/icon32.png) Privacy Redirect
|
||||
# ![privacy-redirect](assets/images/logo-small.png)
|
||||
|
||||
[![Donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/SimonBrazell/donate) [![Buy me a coffee](images/buy-me-a-coffee.png)](https://www.buymeacoffee.com/SimonBrazell)
|
||||
[![Awesome Humane Tech](https://raw.githubusercontent.com/humanetech-community/awesome-humane-tech/main/humane-tech-badge.svg?sanitize=true)](https://github.com/humanetech-community/awesome-humane-tech)
|
||||
|
||||
- [Chrome Extension](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb)
|
||||
- [Firefox Add-on](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/)
|
||||
[![Donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/SimonBrazell/donate) [![Buy me a coffee](assets/images/buy-me-a-coffee.png)](https://www.buymeacoffee.com/SimonBrazell)
|
||||
|
||||
[![Firefox Add-on](assets/images/badge-amo.png)](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/) [![Chrome Extension](assets/images/badge-chrome.png)](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb) [![Edge Extension](assets/images/badge-ms.png)](https://microsoftedge.microsoft.com/addons/detail/privacy-redirect/elnabkhcgpajchapppkhiaifkgikgihj)
|
||||
|
||||
A web extension that redirects Twitter, YouTube, Instagram & Google Maps requests to privacy friendly alternatives - [Nitter](https://github.com/zedeus/nitter), [Invidious](https://github.com/omarroth/invidious), [Bibliogram](https://github.com/cloudrac3r/bibliogram) & [OpenStreetMap](https://www.openstreetmap.org/).
|
||||
|
||||
|
@ -12,9 +13,13 @@ Allows for setting custom [Nitter](https://github.com/zedeus/nitter/wiki/Instanc
|
|||
## Build
|
||||
|
||||
1. `npm install --global web-ext`
|
||||
2. `web-ext build`
|
||||
2. `web-ext build --overwrite-dest`
|
||||
3. See `web-ext-artifacts/` for outputs.
|
||||
|
||||
## License
|
||||
|
||||
Code released under [the MIT license](LICENSE.txt).
|
||||
|
||||
## Privacy Policy
|
||||
|
||||
See the [Project Wiki](https://github.com/SimonBrazell/privacy-redirect/wiki/Privacy-Policy).
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"extensionName": {
|
||||
"message": "Privacy Redirect",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"extensionDescription": {
|
||||
"message": "Leitet Anfragen von Twitter, YouTube, Instagram & Google Maps auf datenschutzfreundliche Alternativen weiter.",
|
||||
"description": "Description of the extension."
|
||||
},
|
||||
"nitterInstance": {
|
||||
"message": "Nitter-Instanz",
|
||||
"description": "Label for Nitter instance field option (options)."
|
||||
},
|
||||
"invidiousInstance": {
|
||||
"message": "Invidious-Instanz",
|
||||
"description": "Label for Invidious instance field option (options)."
|
||||
},
|
||||
"bibliogramInstance": {
|
||||
"message": "Bibliogram-Instanz",
|
||||
"description": "Label for Bibliogram instance field option (options)."
|
||||
},
|
||||
"osmInstance": {
|
||||
"message": "OpenStreetMap-Instanz",
|
||||
"description": "Label for OSM instance field option (options)."
|
||||
},
|
||||
"disableNitter": {
|
||||
"message": "Nitter-Weiterleitungen",
|
||||
"description": "Label for enable/disable Nitter redirects option (options & pop-up)."
|
||||
},
|
||||
"disableInvidious": {
|
||||
"message": "Invidious-Weiterleitungen",
|
||||
"description": "Label for enable/disable Invidious redirects option (options & pop-up)."
|
||||
},
|
||||
"disableBibliogram": {
|
||||
"message": "Bibliogram-Weiterleitungen",
|
||||
"description": "Label for enable/disable Bibliogram redirects option (options & pop-up)."
|
||||
},
|
||||
"disableOsm": {
|
||||
"message": "OpenStreetMap-Weiterleitungen",
|
||||
"description": "Label for enable/disable OSM redirects option (options & pop-up)."
|
||||
},
|
||||
"alwaysProxy": {
|
||||
"message": "Videos immer durch Invidious-Proxy leiten",
|
||||
"description": "Label for 'Always proxy videos through Invidious' option (options)."
|
||||
},
|
||||
"onlyEmbeddedVideo": {
|
||||
"message": "Nur eingebettete Videos zu Invidious weiterleiten",
|
||||
"description": "Label for 'Only redirect embedded video to Invidious' option (options)."
|
||||
},
|
||||
"videoQuality": {
|
||||
"message": "Videoqualität bei Invidious",
|
||||
"description": "Label for 'Invidious Video Quality' option (options)."
|
||||
},
|
||||
"removeTwitterSW": {
|
||||
"message": "Twitter-Serviceworker proaktiv entfernen",
|
||||
"description": "Label for 'Proactively remove Twitter service worker' option (options)."
|
||||
},
|
||||
"invidiousDarkMode": {
|
||||
"message": "Dunklen Modus auf Invidious immer anschalten",
|
||||
"description": "Label for 'Invidious dark mode always on' option (options)."
|
||||
},
|
||||
"persistInvidiousPrefs": {
|
||||
"message": "Invidious-Einstellungen dauerhaft beibehalten (als Cookie)",
|
||||
"description": "Label for 'Persist Invidious preferences (as cookie)' option (options)."
|
||||
},
|
||||
"generalTab": {
|
||||
"message": "Allgmein",
|
||||
"description": "General tab (options)."
|
||||
},
|
||||
"advancedTab": {
|
||||
"message": "Erweitert",
|
||||
"description": "Advanced tab (options)."
|
||||
},
|
||||
"exceptionsTab": {
|
||||
"message": "Ausnahmen",
|
||||
"description": "Exceptions tab (options)."
|
||||
},
|
||||
"exceptionsDescriptionP1": {
|
||||
"message": "Gib eine URL oder einen regulären Ausdruck (Regex) ein, die/der von Weiterleitungen ausgeschlossen werden soll.",
|
||||
"description": "A description of the 'Exceptions' feature paragraph 1 (options)."
|
||||
},
|
||||
"exceptionsDescriptionP2": {
|
||||
"message": "Alle Anfragen für oder ausgehend von einer URL, die auf die Ausnahme zutrifft, werden von Weiterleitungen ausgeschlossen.",
|
||||
"description": "A description of the 'Exceptions' feature paragraph 2 (options)."
|
||||
},
|
||||
"exceptionsDescriptionP3": {
|
||||
"message": "Hinweis – Unterstützt reguläre JavaScript-Ausdrücke (Regex), mit Ausnahme der einschließenden Schrägstriche.",
|
||||
"description": "A description of the 'Exceptions' feature paragraph 3 (options)."
|
||||
},
|
||||
"addException": {
|
||||
"message": "Ausnahme hinzufügen",
|
||||
"description": "'Add Exceptions' button (options)."
|
||||
},
|
||||
"moreOptions": {
|
||||
"message": "Weitere Optionen",
|
||||
"description": "More Options button (pop-up)."
|
||||
},
|
||||
"privacy": {
|
||||
"message": "Privacy",
|
||||
"description": "Extension title - Privacy (pop-up)."
|
||||
},
|
||||
"redirect": {
|
||||
"message": "Redirect",
|
||||
"description": "Extension title - Redirect (pop-up)."
|
||||
},
|
||||
"version": {
|
||||
"message": "Version",
|
||||
"description": "Version"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
# Extension Store (AMO & Chrome Web Store) Listing
|
||||
|
||||
## Summary:
|
||||
```
|
||||
Eine einfache Browser-Erweiterung, die Anfragen an Twitter, YouTube, Instagram & Google Maps zu datenschutzfreundlichen Alternativen weiterleitet.
|
||||
```
|
||||
## Description:
|
||||
```
|
||||
Leitet Anfragen an Twitter, YouTube, Instagram & Google Maps zu datenschutzfreundlichen Alternativen weiter – <a href='https://nitter.net/'>Nitter</a>, <a href='https://invidio.us/'>Invidious</a>, <a href='https://bibliogram.art/'>Bibliogram</a>, & <a href='https://www.openstreetmap.org'>OpenStreetMap</a>.
|
||||
|
||||
Erlaubt das Einstellen benutzerdefinierter Instanzen, das Ein- und Ausschalten aller Weiterleitungen und vieles mehr.
|
||||
|
||||
<b>★ Weitere Infos: ℹ️</b>
|
||||
<ul>
|
||||
<li><a href='https://github.com/zedeus/nitter#nitter-wip'>Nitter</a></li>
|
||||
<li><a href='https://github.com/omarroth/invidious#invidious'>Invidious</a></li>
|
||||
<li><a href='https://github.com/cloudrac3r/bibliogram#bibliogram'>Bibliogram</a></li>
|
||||
<li><a href='https://wiki.openstreetmap.org/'>OpenStreetMap</a></li>
|
||||
</ul>
|
||||
|
||||
Der Code dieser Browser-Erweiterung ist verfügbar auf <a href='https://github.com/SimonBrazell/privacy-redirect'>Github</a>.
|
||||
|
||||
<b>★ Spenden: 👨🏻💻</b>
|
||||
Wenn Ihnen diese Erweiterung gefällt und Sie finanziell in der Lage sind, erwägen Sie bitte <a href='https://www.buymeacoffee.com/SimonBrazell'> mir auf BuyMeACoffee einen Kaffee zu kaufen</a> ☕️ ️ um Ihre Wertschätzung zu zeigen und die Fortsetzung des Projekts zu unterstützen.
|
||||
|
||||
<b>★ Was ist neu in dieser Version (v1.1.36) 🆕</b>
|
||||
<ul>
|
||||
<li>Russische Übersetzung hinzugefügt</li>
|
||||
<li>Invidious-Autoplay-Parameter gefixt</li>
|
||||
</ul>
|
||||
|
||||
<b>★ Berechtigungen: ℹ️</b>
|
||||
<ul>
|
||||
<li>Bitte beachten Sie, dass der Zugriff auf alle Website-Navigationsereignisse ( alle URLs), nicht nur auf die Zieldomains, erforderlich ist, damit eingebettete Video-Weiterleitungen stattfinden können. Zur Zeit kenne ich keine andere Möglichkeit, Iframe-Weiterleitungen zu realisieren, freue mich aber über Vorschläge dazu 🙂</li>
|
||||
</ul>
|
||||
```
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"extensionName": {
|
||||
"message": "Privacy Redirect",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"extensionDescription": {
|
||||
"message": "Redirects Twitter, YouTube, Instagram & Google Maps requests to privacy friendly alternatives.",
|
||||
"description": "Description of the extension."
|
||||
},
|
||||
"nitterInstance": {
|
||||
"message": "Nitter Instance",
|
||||
"description": "Label for Nitter instance field option (options)."
|
||||
},
|
||||
"invidiousInstance": {
|
||||
"message": "Invidious Instance",
|
||||
"description": "Label for Invidious instance field option (options)."
|
||||
},
|
||||
"bibliogramInstance": {
|
||||
"message": "Bibliogram Instance",
|
||||
"description": "Label for Bibliogram instance field option (options)."
|
||||
},
|
||||
"osmInstance": {
|
||||
"message": "OpenStreetMap Instance",
|
||||
"description": "Label for OSM instance field option (options)."
|
||||
},
|
||||
"disableNitter": {
|
||||
"message": "Nitter Redirects",
|
||||
"description": "Label for enable/disable Nitter redirects option (options & pop-up)."
|
||||
},
|
||||
"disableInvidious": {
|
||||
"message": "Invidious Redirects",
|
||||
"description": "Label for enable/disable Invidious redirects option (options & pop-up)."
|
||||
},
|
||||
"disableBibliogram": {
|
||||
"message": "Bibliogram Redirects",
|
||||
"description": "Label for enable/disable Bibliogram redirects option (options & pop-up)."
|
||||
},
|
||||
"disableOsm": {
|
||||
"message": "OpenStreetMap Redirects",
|
||||
"description": "Label for enable/disable OSM redirects option (options & pop-up)."
|
||||
},
|
||||
"alwaysProxy": {
|
||||
"message": "Always proxy videos through Invidious",
|
||||
"description": "Label for 'Always proxy videos through Invidious' option (options)."
|
||||
},
|
||||
"onlyEmbeddedVideo": {
|
||||
"message": "Only redirect embedded video to Invidious",
|
||||
"description": "Label for 'Only redirect embedded video to Invidious' option (options)."
|
||||
},
|
||||
"videoQuality": {
|
||||
"message": "Invidious Video Quality",
|
||||
"description": "Label for 'Invidious Video Quality' option (options)."
|
||||
},
|
||||
"removeTwitterSW": {
|
||||
"message": "Proactively remove Twitter service worker",
|
||||
"description": "Label for 'Proactively remove Twitter service worker' option (options)."
|
||||
},
|
||||
"invidiousDarkMode": {
|
||||
"message": "Invidious dark mode always on",
|
||||
"description": "Label for 'Invidious dark mode always on' option (options)."
|
||||
},
|
||||
"persistInvidiousPrefs": {
|
||||
"message": "Persist Invidious preferences (as cookie)",
|
||||
"description": "Label for 'Persist Invidious preferences (as cookie)' option (options)."
|
||||
},
|
||||
"generalTab": {
|
||||
"message": "General",
|
||||
"description": "General tab (options)."
|
||||
},
|
||||
"advancedTab": {
|
||||
"message": "Advanced",
|
||||
"description": "Advanced tab (options)."
|
||||
},
|
||||
"exceptionsTab": {
|
||||
"message": "Exceptions",
|
||||
"description": "Exceptions tab (options)."
|
||||
},
|
||||
"exceptionsDescriptionP1": {
|
||||
"message": "Enter a URL or Regular Expression to be excluded from redirects.",
|
||||
"description": "A description of the 'Exceptions' feature paragraph 1 (options)."
|
||||
},
|
||||
"exceptionsDescriptionP2": {
|
||||
"message": "All requests for or initiating from a URL that matches the exception will be excluded from redirects.",
|
||||
"description": "A description of the 'Exceptions' feature paragraph 2 (options)."
|
||||
},
|
||||
"exceptionsDescriptionP3": {
|
||||
"message": "Note - Supports JavaScript regular expressions, excluding the enclosing forward slashes.",
|
||||
"description": "A description of the 'Exceptions' feature paragraph 3 (options)."
|
||||
},
|
||||
"addException": {
|
||||
"message": "Add Exception",
|
||||
"description": "'Add Exceptions' button (options)."
|
||||
},
|
||||
"moreOptions": {
|
||||
"message": "More Options",
|
||||
"description": "More Options button (pop-up)."
|
||||
},
|
||||
"privacy": {
|
||||
"message": "Privacy",
|
||||
"description": "Extension title - Privacy (pop-up)."
|
||||
},
|
||||
"redirect": {
|
||||
"message": "Redirect",
|
||||
"description": "Extension title - Redirect (pop-up)."
|
||||
},
|
||||
"version": {
|
||||
"message": "Version",
|
||||
"description": "Version"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
# Extension Store (AMO & Chrome Web Store) Listing
|
||||
|
||||
## Summary:
|
||||
```
|
||||
A simple web extension that redirects Twitter, YouTube, Instagram & Google Maps requests to privacy friendly alternatives.
|
||||
```
|
||||
## Description:
|
||||
```
|
||||
Redirects Twitter, YouTube, Instagram, & Google Maps requests to privacy friendly alternatives - <a href='https://nitter.net/'>Nitter</a>, <a href='https://invidio.us/'>Invidious</a>, <a href='https://bibliogram.art/'>Bibliogram</a>, & <a href='https://www.openstreetmap.org'>OpenStreetMap</a>.
|
||||
|
||||
Allows for setting custom instances, toggling all redirects on/off and more.
|
||||
|
||||
<b>★ More Info: ℹ️</b>
|
||||
<ul>
|
||||
<li><a href='https://github.com/zedeus/nitter#nitter-wip'>Nitter</a></li>
|
||||
<li><a href='https://github.com/omarroth/invidious#invidious'>Invidious</a></li>
|
||||
<li><a href='https://github.com/cloudrac3r/bibliogram#bibliogram'>Bibliogram</a></li>
|
||||
<li><a href='https://wiki.openstreetmap.org/'>OpenStreetMap</a></li>
|
||||
</ul>
|
||||
|
||||
The code for this web extension is available on <a href='https://github.com/SimonBrazell/privacy-redirect'>Github</a>.
|
||||
|
||||
<b>★ Donate: 👨🏻💻</b>
|
||||
If you like this extension and are financially able please consider <a href='https://www.buymeacoffee.com/SimonBrazell'>buying me a coffee</a> ☕️ ️to show your appreciation and support the continuation of the project.
|
||||
|
||||
<b>★ What's New in This Version (v1.1.36) 🆕</b>
|
||||
<ul>
|
||||
<li>Added Russian language translation.</li>
|
||||
<li>Fix Invidious autoplay parameter.</li>
|
||||
</ul>
|
||||
|
||||
<b>★ Permissions: ℹ️</b>
|
||||
<ul>
|
||||
<li>Please note, access to all website navigation events ( all URLs), not just the target domains, is required to allow embedded video redirects to occur. At this time I know of no other way to achieve iframe redirects, happy to hear some suggestions on this though 🙂</li>
|
||||
</ul>
|
||||
```
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"extensionName": {
|
||||
"message": "Privacy Redirect",
|
||||
"description": "Nom du module complémentaire."
|
||||
},
|
||||
"extensionDescription": {
|
||||
"message": "Redirige les requêtes les demandes Twitter, YouTube, Instagram et Google Maps vers des alternatives respectueuses de la vie privée. pour Twitter, YouTube, Instagram et Google Maps vers des alternatives respectueuses de la vie privée.",
|
||||
"description": "Description du module complémentaire."
|
||||
},
|
||||
"nitterInstance": {
|
||||
"message": "Instance de Nitter",
|
||||
"description": "Étiquette pour l'option de champ d'instance Nitter (options)."
|
||||
},
|
||||
"invidiousInstance": {
|
||||
"message": "Instance de Invidious",
|
||||
"description": "Étiquette pour l'option de champ d'instance Invidious (options)."
|
||||
},
|
||||
"bibliogramInstance": {
|
||||
"message": "Instance de Bibliogram",
|
||||
"description": "Étiquette pour l'option de champ d'instance Bibliogram (options)."
|
||||
},
|
||||
"osmInstance": {
|
||||
"message": "Instance de OpenStreetMap",
|
||||
"description": "Étiquette pour l'option de champ d'instance OpenStreetMap (options)."
|
||||
},
|
||||
"disableNitter": {
|
||||
"message": "Redirection vers Nitter",
|
||||
"description": "Étiquette pour activer / désactiver l'option de redirection vers Nitter (options et pop-up)."
|
||||
},
|
||||
"disableInvidious": {
|
||||
"message": "Redirection vers Invidious",
|
||||
"description": "Étiquette pour activer / désactiver l'option de redirection vers Invidious (options et pop-up)."
|
||||
},
|
||||
"disableBibliogram": {
|
||||
"message": "Redirection vers Bibliogram",
|
||||
"description": "Étiquette pour activer / désactiver l'option de redirection vers Bibliogram (options et pop-up)."
|
||||
},
|
||||
"disableOsm": {
|
||||
"message": "Redirection vers OpenStreetMap",
|
||||
"description": "Étiquette pour activer / désactiver l'option de redirection vers OpenStreetMap (options et pop-up)."
|
||||
},
|
||||
"alwaysProxy": {
|
||||
"message": "Toujours transiter par proxy les vidéos via Invidious",
|
||||
"description": "Libellé pour l'option 'Toujours transiter par proxy les vidéos via Invidious' (options)."
|
||||
},
|
||||
"onlyEmbeddedVideo": {
|
||||
"message": "Rediriger uniquement les vidéos intégrées vers Invidious",
|
||||
"description": "Libellé pour l'option 'Rediriger uniquement les vidéos intégrées vers Invidious' (options)."
|
||||
},
|
||||
"videoQuality": {
|
||||
"message": "Qualité des vidéos Invidious",
|
||||
"description": "Libellé pour l'option 'Qualité des vidéos Invidious' (options)."
|
||||
},
|
||||
"removeTwitterSW": {
|
||||
"message": "Supprimer proactivement le service worker de Twitter",
|
||||
"description": "Libellé pour l'option 'Supprimer proactivement le service worker de Twitter' (options)."
|
||||
},
|
||||
"invidiousDarkMode": {
|
||||
"message": "Mode sombre toujours activé pour Invidious",
|
||||
"description": "Libellé pour l'option 'Mode sombre toujours activé pour Invidious' (options)."
|
||||
},
|
||||
"persistInvidiousPrefs": {
|
||||
"message": "Conserver les préférences d’Invidious (sous forme de cookie)",
|
||||
"description": "Libellé pour 'Conserver les préférences d’Invidious (sous forme de cookie)' option (options)."
|
||||
},
|
||||
"generalTab": {
|
||||
"message": "Général",
|
||||
"description": "Onglet général (options)."
|
||||
},
|
||||
"advancedTab": {
|
||||
"message": "Avancé",
|
||||
"description": "Onglet avancé (options)."
|
||||
},
|
||||
"exceptionsTab": {
|
||||
"message": "Exceptions",
|
||||
"description": "Onglet des Exceptions dans les options."
|
||||
},
|
||||
"exceptionsDescriptionP1": {
|
||||
"message": "Entrez une adresse URL ou une expression régulière qui sera exclue des redirections.",
|
||||
"description": "Description pour la rubrique 'Exceptions' dans les options."
|
||||
},
|
||||
"exceptionsDescriptionP2": {
|
||||
"message": "Toutes les demandes émanant d'une adresse URL et correspondant à l'exception seront exclues des redirections.",
|
||||
"description": "Description pour la rubrique 'Exceptions' dans les options."
|
||||
},
|
||||
"exceptionsDescriptionP3": {
|
||||
"message": "Remarque - Prend en charge les expressions régulières JavaScript, à l'exclusion des barres slash.",
|
||||
"description": "Description pour la rubrique 'Exceptions' dans les options."
|
||||
},
|
||||
"addException": {
|
||||
"message": "Ajoutez une exception",
|
||||
"description": "boutton 'Ajoutez une exception' dans les options."
|
||||
},
|
||||
"moreOptions": {
|
||||
"message": "Options supplémentaires",
|
||||
"description": "Boutton des options supplémentaires (pop-up)."
|
||||
},
|
||||
"privacy": {
|
||||
"message": "Vie privée",
|
||||
"description": "Titre du module complémentaire - Vie privée (pop-up)."
|
||||
},
|
||||
"redirect": {
|
||||
"message": "Redirection",
|
||||
"description": "Titre du module complémentaire - Redirection (pop-up)."
|
||||
},
|
||||
"version": {
|
||||
"message": "Version",
|
||||
"description": "Version"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
# Extension Store (AMO & Chrome Web Store) Listing
|
||||
|
||||
## Summary:
|
||||
```
|
||||
Redirige les requêtes les demandes Twitter, YouTube, Instagram et Google Maps vers des alternatives respectueuses de la vie privée. pour Twitter, YouTube, Instagram et Google Maps vers des alternatives respectueuses de la vie privée.
|
||||
```
|
||||
## Description:
|
||||
```
|
||||
Redirige les requètes pour Twitter, YouTube, Instagram et Google Maps vers des alternatives respectueuses de la confidentialité - <a href="https://nitter.net/">Nitter</a>, <a href="https://invidio.us/">Invidious</a>, <a href="https://bibliogram.art/">Bibliogram</a>, & <a href="https://www.openstreetmap.org">OpenStreetMap</a>.
|
||||
|
||||
Permet de définir des instances personnalisées et d'activer ou désactiver toutes les redirections.
|
||||
|
||||
<b>★ Plus d'informations: ℹ️</b>
|
||||
<ul>
|
||||
<li><a href="https://github.com/zedeus/nitter#nitter-wip">Nitter</a></li>
|
||||
<li><a href="https://github.com/omarroth/invidious#invidious">Invidious</a></li>
|
||||
<li><a href="https://github.com/cloudrac3r/bibliogram#bibliogram">Bibliogram</a></li>
|
||||
<li><a href="https://wiki.openstreetmap.org/">OpenStreetMap</a></li>
|
||||
</ul>
|
||||
|
||||
Le code de cette extension Web est disponible sur <a href="https://github.com/SimonBrazell/privacy-redirect">Github</a>.
|
||||
|
||||
<b>★ Faire un don: 👨🏻💻</b>
|
||||
Si vous aimez ce module complémentaire et si vous avez une bonne situation financière, pensez à <a href="https://www.buymeacoffee.com/SimonBrazell">m'acheter un café</a> ☕️ pour montrer que vous appréciez et soutenez la poursuite du projet.
|
||||
|
||||
<b>★ Nouveautés de cette version (v1.1.36) 🆕</b>
|
||||
<ul>
|
||||
<li>Added Russian language translation.</li>
|
||||
<li>Fix Invidious autoplay parameter.</li>
|
||||
</ul>
|
||||
|
||||
<b>★ Autorisations: ℹ️</b>
|
||||
<ul>
|
||||
<li>Veuillez noter que l'accès à tous les événements de navigation sur le site Web (toutes les adresses URL), et pas seulement aux domaines cibles, est requis pour permettre aux redirections vidéo intégrées de se faire correctement. Pour le moment, je ne connais aucun autre moyen de réaliser des redirections iframe, je serais heureux d'entendre quelques suggestions à ce sujet cependant 🙂</li>
|
||||
</ul>
|
||||
```
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"extensionName": {
|
||||
"message": "Privacy Redirect",
|
||||
"description": "Nazwa rozszerzenia."
|
||||
},
|
||||
"extensionDescription": {
|
||||
"message": "Przekierowuje serwisy takie jak: Twitter, YouTube, Instagram i Google Maps do alternatyw sprzyjających prywatności.",
|
||||
"description": "Opis rozszerzenia."
|
||||
},
|
||||
"nitterInstance": {
|
||||
"message": "Instancja Nitter",
|
||||
"description": "Etykieta dla pola wyboru instancji Nitter (opcje)."
|
||||
},
|
||||
"invidiousInstance": {
|
||||
"message": "Instancja Invidious",
|
||||
"description": "Etykieta dla pola wyboru instancji Invidious (opcje)."
|
||||
},
|
||||
"bibliogramInstance": {
|
||||
"message": "Instancja Bibliogram",
|
||||
"description": "Etykieta dla pola wyboru instancji Bibliogram (opcje)."
|
||||
},
|
||||
"osmInstance": {
|
||||
"message": "Instancja OpenStreetMap",
|
||||
"description": "Etykieta dla pola wyboru instancji OpenStreetMap (opcje)."
|
||||
},
|
||||
"disableNitter": {
|
||||
"message": "Przekierowanie Nitter",
|
||||
"description": "Etykieta dla włączenia/wyłączenia opcji przekierowania Nitter (opcje i okno pop-up)."
|
||||
},
|
||||
"disableInvidious":
|
||||
"message": "Przekierowanie Invidious ",
|
||||
"description": "Etykieta dla włączenia/wyłączenia opcji przekierowania Invidious (opcje i okno pop-up)."
|
||||
},
|
||||
"disableBibliogram": {
|
||||
"message": "Przekierowanie Bibliogram",
|
||||
"description": "Etykieta dla włączenia/wyłączenia opcji przekierowania Bibliogram (opcje i okno pop-up)."
|
||||
},
|
||||
"disableOsm": {
|
||||
"message": "Przekierowanie OpenStreetMap",
|
||||
"description": "Etykieta dla włączenia/wyłączenia opcji przekierowania OpenStreetMap (opcje i okno pop-up)."
|
||||
},
|
||||
"alwaysProxy": {
|
||||
"message": "Zawsze buforuj i wyświetlaj odnośniki wideo z YouTube poprzez Invidious",
|
||||
"description": "Etykieta dla opcji 'Zawsze buforuj i wyświetlaj odnośniki wideo poprzez Invidious'."
|
||||
},
|
||||
"onlyEmbeddedVideo": {
|
||||
"message": "Jedynie przekieruj odnośniki wideo do instancji Invidious",
|
||||
"description": "Etykieta dla opcji 'Jedynie przekieruj odnośniki wideo do instancji Invidious'."
|
||||
},
|
||||
"videoQuality": {
|
||||
"message": "Jakość wideo Invidious",
|
||||
"description": "Etykieta dla opcji 'Jakość wideo Invidious'."
|
||||
},
|
||||
"removeTwitterSW": {
|
||||
"message": "Proaktywnie usuwaj skrypty serwisowe (service worker) Twittera",
|
||||
"description": "Etykieta dla opcji 'Proaktywnie usuwaj skrypty serwisowe (service worker) Twittera'."
|
||||
},
|
||||
"invidiousDarkMode": {
|
||||
"message": "Tryb ciemny dla Invidious zawsze włączony",
|
||||
"description": "Etykieta dla opcji 'Tryb ciemny dla Invidious zawsze włączony'."
|
||||
},
|
||||
"persistInvidiousPrefs": {
|
||||
"message": "Zapisz ustawienia Invidious (jako plik cookie)",
|
||||
"description": "Etykieta dla 'Zapisz ustawienia Invidious (jako plik cookie)'."
|
||||
},
|
||||
"generalTab": {
|
||||
"message": "Główne",
|
||||
"description": "Zakładka Główne (opcje)."
|
||||
},
|
||||
"advancedTab": {
|
||||
"message": "Advanced",
|
||||
"description": "Zakładka zaawansowane (opcje)."
|
||||
},
|
||||
"exceptionsTab": {
|
||||
"message": "Wyjątki",
|
||||
"description": "Zakładka wyjątki (opcje)."
|
||||
},
|
||||
"exceptionsDescriptionP1": {
|
||||
"message": "Wprowadź adres URL lub wyrażenie regularne, które zostanie wyłączone z przekierowania. ",
|
||||
"description": "Opis funkcji 'Wyjątki' paragraf 1 (opcje)."
|
||||
},
|
||||
"exceptionsDescriptionP2": {
|
||||
"message": "Wszystkie żądania dla lub inicjalizujące z adresu URL które spełniają wyjątek zostaną wyłączone z przekierowania.",
|
||||
"description": "Opis funkcji 'Wyjątki' paragraf 2 (opcje)."
|
||||
},
|
||||
"exceptionsDescriptionP3": {
|
||||
"message": "Informacja - Wspierane są wyrażenia regularne JavaScript, wyłączając ukośniki lewe zamykające.",
|
||||
"description": "Opis funkcji 'Wyjątki' paragraf 3 (opcje)."
|
||||
},
|
||||
"addException": {
|
||||
"message": "Dodaj wyjątek",
|
||||
"description": "Przycisk 'Dodaj wyjątek' (opcje)."
|
||||
},
|
||||
"moreOptions": {
|
||||
"message": "Więcej opcji",
|
||||
"description": "Przycisk 'Więcej opcji' (okno pop-up)."
|
||||
},
|
||||
"privacy": {
|
||||
"message": "Prywatność",
|
||||
"description": "Tytuł rozszerzenia - Privacy (okno pop-up)."
|
||||
},
|
||||
"redirect": {
|
||||
"message": "Redirect",
|
||||
"description": "Tytuł rozszerzenia - Redirect (pop-up)."
|
||||
},
|
||||
"version": {
|
||||
"message": "Version",
|
||||
"description": "Wersja"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
{
|
||||
"extensionName": {
|
||||
"message": "Privacy Redirect",
|
||||
"description": "Название расширения."
|
||||
},
|
||||
"extensionDescription": {
|
||||
"message": "Перенаправляет запросы к Twitter, YouTube, Instagram и Google Maps на альтернативные сервисы, дружелюбные к приватности.",
|
||||
"description": "Описание расширения."
|
||||
},
|
||||
"nitterInstance": {
|
||||
"message": "Сервис Nitter",
|
||||
"description": "Название настройки (в настройках) поля сервиса Nitter."
|
||||
},
|
||||
"invidiousInstance": {
|
||||
"message": "Сервис Invidious",
|
||||
"description": "Название настройки (в настройках) поля сервиса Invidious."
|
||||
},
|
||||
"bibliogramInstance": {
|
||||
"message": "Сервис Bibliogram",
|
||||
"description": "Название настройки (в настройках) поля сервиса Bibliogram."
|
||||
},
|
||||
"osmInstance": {
|
||||
"message": "Сервис OpenStreetMap",
|
||||
"description": "Название настройки (в настройках) поля сервиса OSM."
|
||||
},
|
||||
"disableNitter": {
|
||||
"message": "Перенаправление на Nitter",
|
||||
"description": "Название настройки для включения/выключения перенаправления на Nitter (в настройках и всплывающем окне)."
|
||||
},
|
||||
"disableInvidious": {
|
||||
"message": "Перенаправление на Invidious",
|
||||
"description": "Название настройки для включения/выключения перенаправления на Invidious redirects option (в настройках и всплывающем окне)."
|
||||
},
|
||||
"disableBibliogram": {
|
||||
"message": "Перенаправление на Bibliogram",
|
||||
"description": "Название настройки для включения/выключения перенаправления на Bibliogram (в настройках и всплывающем окне)."
|
||||
},
|
||||
"disableOsm": {
|
||||
"message": "Перенаправление на OpenStreetMap",
|
||||
"description": "Название настройки для включения/выключения перенаправления на OSM (в настройках и всплывающем окне)."
|
||||
},
|
||||
"theme": {
|
||||
"message": "Тема",
|
||||
"description": "Название настройки для 'Тема' (в настройках)."
|
||||
},
|
||||
"alwaysProxy": {
|
||||
"message": "Всегда проксировать видео через Invidious",
|
||||
"description": "Название настройки для 'Всегда проксировать видео через Invidious' (в настройках)."
|
||||
},
|
||||
"onlyEmbeddedVideo": {
|
||||
"message": "Перенаправлять только встроенные видео на Invidious",
|
||||
"description": "Название настройки для 'Перенаправлять только встроенные видео на Invidious' (в настройках)."
|
||||
},
|
||||
"videoQuality": {
|
||||
"message": "Качество видео Invidious",
|
||||
"description": "Название настройки для 'Качество видео Invidious' (в настройках)."
|
||||
},
|
||||
"removeTwitterSW": {
|
||||
"message": "Проактивно удалять service worker для Twitter",
|
||||
"description": "Название настройки для 'Проактивно удалять service worker для Twitter' (в настройках)."
|
||||
},
|
||||
"invidiousDarkMode": {
|
||||
"message": "Всегда включать темный режим Invidious",
|
||||
"description": "Название настройки для 'Всегда включать темный режим Invidious' (в настройках)."
|
||||
},
|
||||
"invidiousVolume": {
|
||||
"message": "Громкость Invidious",
|
||||
"description": "Название настройки для 'Громкость Invidious' (в настройках)."
|
||||
},
|
||||
"invidiousPlayerStyle": {
|
||||
"message": "Стиль плеера Invidious",
|
||||
"description": "Название настройки для 'Стиль плеера Invidious' (в настройках)."
|
||||
},
|
||||
"invidiousSubtitles": {
|
||||
"message": "Субтитры Invidious - коды языков (разделяются запятой)",
|
||||
"description": "Название настройки для 'Субтитры Invidious - коды языков (разделяются запятой)' (в настройках)."
|
||||
},
|
||||
"invidiousAutoplay": {
|
||||
"message": "Автоматически воспроизводить видео Invidious при загрузке",
|
||||
"description": "Название настройки для 'Автоматически воспроизводить видео Invidious при загрузке' (в настройках)."
|
||||
},
|
||||
"persistInvidiousPrefs": {
|
||||
"message": "Сохранять настройки Invidious (в файле cookie)",
|
||||
"description": "Название настройки для 'Сохранять настройки Invidious (в файле cookie)' (в настройках)."
|
||||
},
|
||||
"generalTab": {
|
||||
"message": "Общие",
|
||||
"description": "Вкладка 'Общие' (в настройках)."
|
||||
},
|
||||
"advancedTab": {
|
||||
"message": "Дополнительно",
|
||||
"description": "Вкладка 'Дополнительно' (в настройках)."
|
||||
},
|
||||
"exceptionsTab": {
|
||||
"message": "Исключения",
|
||||
"description": "Вкладка 'Исключения' (в настройках)."
|
||||
},
|
||||
"exceptionsDescriptionP1": {
|
||||
"message": "Введите URL или регулярное выражение для исключения из перенаправлений.",
|
||||
"description": "Описание функции 'Исключения' (в настройках)."
|
||||
},
|
||||
"exceptionsDescriptionP2": {
|
||||
"message": "Все запросы на URL, совпадающие с исключениями, или инициированные с них будут исключены из перенаправлений.",
|
||||
"description": "Описание функции 'Исключения' (в настройках)."
|
||||
},
|
||||
"exceptionsDescriptionP3": {
|
||||
"message": "Примечание: Поддерживает регулярные выражения JavaScript, кроме закрывающих обратных слэшей.",
|
||||
"description": "Описание функции 'Исключения' (в настройках)."
|
||||
},
|
||||
"addException": {
|
||||
"message": "Добавить исключение",
|
||||
"description": "Кнопка 'Добавить исключения' (в настройках)."
|
||||
},
|
||||
"moreOptions": {
|
||||
"message": "Другие настройки",
|
||||
"description": "Кнопка 'Другие настройки' (во всплывающем окне)."
|
||||
},
|
||||
"privacy": {
|
||||
"message": "Privacy",
|
||||
"description": "Название расширения - Privacy (во всплывающем окне)."
|
||||
},
|
||||
"redirect": {
|
||||
"message": "Redirect",
|
||||
"description": "Название расширения - Redirect (во всплывающем окне)."
|
||||
},
|
||||
"version": {
|
||||
"message": "Версия",
|
||||
"description": "Версия."
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
# Extension Store (AMO & Chrome Web Store) Listing
|
||||
|
||||
## Summary:
|
||||
```
|
||||
Простое расширение для браузера, которое перенаправляет запросы к Twitter, YouTube, Instagram & Google Maps на альтернативные сервисы, дружелюбные к приватности.
|
||||
```
|
||||
## Description:
|
||||
```
|
||||
Перенаправляет запросы к Twitter, YouTube, Instagram, & Google Maps на альтернативные сервисы, дружелюбные к приватности - <a href='https://nitter.net/'>Nitter</a>, <a href='https://invidio.us/'>Invidious</a>, <a href='https://bibliogram.art/'>Bibliogram</a> и <a href='https://www.openstreetmap.org'>OpenStreetMap</a>.
|
||||
|
||||
Позволяет настраивать пользовательские сервисы, включать/выключать все перенаправления и т.д.
|
||||
|
||||
<b>★ Дополнительная информация: ℹ</b>
|
||||
<ul>
|
||||
<li><a href='https://github.com/zedeus/nitter#nitter-wip'>Nitter</a></li>
|
||||
<li><a href='https://github.com/omarroth/invidious#invidious'>Invidious</a></li>
|
||||
<li><a href='https://github.com/cloudrac3r/bibliogram#bibliogram'>Bibliogram</a></li>
|
||||
<li><a href='https://wiki.openstreetmap.org/'>OpenStreetMap</a></li>
|
||||
</ul>
|
||||
|
||||
Исходный код данного расширения доступен на <a href='https://github.com/SimonBrazell/privacy-redirect'>Github</a>.
|
||||
|
||||
<b>★ Пожертвовать: 👨🏻💻</b>
|
||||
Если вам нравится это расширение и вы можете помочь финансово, пожалуйста, <a href='https://www.buymeacoffee.com/SimonBrazell'>купите мне кофе</a> ☕ и покажите ваше одобрение и поддержку развития проекта.
|
||||
|
||||
<b>★ Что нового в этой версии (v1.1.36) 🆕</b>
|
||||
<ul>
|
||||
<li>Добавлен перевод на русский язык.</li>
|
||||
<li>Исправлен параметр автоматического воспроизведения Invidious.</li>
|
||||
</ul>
|
||||
|
||||
<b>★ Разрешения: ℹ</b>
|
||||
<ul>
|
||||
<li>Важно: доступ ко всем сайтам (URL), не только к целевым, требуется для разрешения перенаправления встроенных видео. В данный момент я не знаю, как осуществить перенаправление iframe, буду рад выслушать ваши предложения 🙂</li>
|
||||
</ul>
|
||||
```
|
|
@ -0,0 +1,35 @@
|
|||
# Extension Store (AMO & Chrome Web Store) Listing
|
||||
|
||||
## Summary:
|
||||
```
|
||||
Prosta wtyczka która przekierowuje żądania Twitter, YouTube, Instagram oraz Google Maps na odpowiedniki przyjazne dla prywatności.
|
||||
```
|
||||
## Description:
|
||||
```
|
||||
Przekierowuje żądania Twitter, YouTube, Instagram oraz Google Maps na odpowiedniki przyjazne dla prywatności - <a href='https://nitter.net/'>Nitter</a>, <a href='https://invidio.us/'>Invidious</a>, <a href='https://bibliogram.art/'>Bibliogram</a>, & <a href='https://www.openstreetmap.org'>OpenStreetMap</a>.
|
||||
|
||||
Umożliwia ustawienie niestandardowych instancji usług, przełączania przekierowania jako aktywne/nieaktwne i o wiele więcej.
|
||||
<b>★ Więcej informacji: ℹ️</b>
|
||||
<ul>
|
||||
<li><a href='https://github.com/zedeus/nitter#nitter-wip'>Nitter</a></li>
|
||||
<li><a href='https://github.com/omarroth/invidious#invidious'>Invidious</a></li>
|
||||
<li><a href='https://github.com/cloudrac3r/bibliogram#bibliogram'>Bibliogram</a></li>
|
||||
<li><a href='https://wiki.openstreetmap.org/'>OpenStreetMap</a></li>
|
||||
</ul>
|
||||
|
||||
Kod źródłowy tego rozszerzenia jest dostępny na: <a href='https://github.com/SimonBrazell/privacy-redirect'>Github</a>.
|
||||
|
||||
<b>★ Donate: 👨🏻💻</b>
|
||||
Jeżeli lubisz to rozszerzenie i chcesz wesprzeć autora finanosowo, proszę pomyśl o <a href='https://www.buymeacoffee.com/SimonBrazell'>zaserwowaniu małej czarnej</a> ☕️ ️aby pokazać swoją wdzięczność i wesprzeć możliwości kontynuowania projektu.
|
||||
|
||||
<b>★ Co nowego w tej wersji (v1.1.36) 🆕</b>
|
||||
<ul>
|
||||
<li>Dodano tłumaczenie w wersji Rosyjskiej</li>
|
||||
<li>Naprawiono parametr autoodtwarzania Invidious</li>
|
||||
</ul>
|
||||
|
||||
<b>★ Uprawnienia: ℹ️</b>
|
||||
<ul>
|
||||
<li>Zwróć uwagę, że dostęp do wszystkich zdarzeń dotyczących nawigacji po stronach (wszystkie adresy URL) jest wymagany dla poprawnego odtwarzania osadzonych plików wideo. Obecnie nie znam innych możliwości aby obsłużyć przekierowania ramek iFrame, będę wdzięczny za sugestie 🙂</li>
|
||||
</ul>
|
||||
```
|
|
@ -1,5 +0,0 @@
|
|||
/*
|
||||
Retrieved February 19, 2020, from https://www.youtube.com/iframe_api
|
||||
*/
|
||||
|
||||
if (!window['YT']) { var YT = { loading: 0, loaded: 0 }; } if (!window['YTConfig']) { var YTConfig = { 'host': 'http://www.youtube.com' }; } if (!YT.loading) { YT.loading = 1; (function () { var l = []; YT.ready = function (f) { if (YT.loaded) { f(); } else { l.push(f); } }; window.onYTReady = function () { YT.loaded = 1; for (var i = 0; i < l.length; i++) { try { l[i](); } catch (e) { } } }; YT.setConfig = function (c) { for (var k in c) { if (c.hasOwnProperty(k)) { YTConfig[k] = c[k]; } } }; var a = document.createElement('script'); a.type = 'text/javascript'; a.id = 'www-widgetapi-script'; a.src = 'https://s.ytimg.com/yts/jsbin/www-widgetapi-vflYl14TA/www-widgetapi.js'; a.async = true; var c = document.currentScript; if (c) { var n = c.nonce || c.getAttribute('nonce'); if (n) { a.setAttribute('nonce', n); } } var b = document.getElementsByTagName('script')[0]; b.parentNode.insertBefore(a, b); })(); }
|
After Width: | Height: | Size: 454 KiB |
After Width: | Height: | Size: 875 KiB |
After Width: | Height: | Size: 270 KiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 279 KiB |
After Width: | Height: | Size: 640 KiB |
After Width: | Height: | Size: 2.8 MiB |
After Width: | Height: | Size: 433 KiB |
After Width: | Height: | Size: 3.7 MiB |
After Width: | Height: | Size: 490 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 512 512'>
|
||||
<polyline points='112 184 256 328 400 184' style='fill:none;stroke:#FF5B56;stroke-linecap:round;stroke-linejoin:round;stroke-width:48px'/>
|
||||
</svg>
|
After Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 976 B After Width: | Height: | Size: 976 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 138 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
@ -0,0 +1,19 @@
|
|||
window.browser = window.browser || window.chrome;
|
||||
|
||||
function localisePage() {
|
||||
var data = document.querySelectorAll("[data-localise]");
|
||||
|
||||
for (var i in data)
|
||||
if (data.hasOwnProperty(i)) {
|
||||
var obj = data[i];
|
||||
var tag = obj.getAttribute("data-localise").toString();
|
||||
|
||||
var msg = tag.replace(/__MSG_(\w+)__/g, function (_match, v1) {
|
||||
return v1 ? browser.i18n.getMessage(v1) : null;
|
||||
});
|
||||
|
||||
if (msg && msg !== tag) obj.textContent = msg;
|
||||
}
|
||||
}
|
||||
|
||||
localisePage();
|
|
@ -0,0 +1,91 @@
|
|||
"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",
|
||||
];
|
||||
|
||||
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()) {
|
||||
const redirect = redirectTwitter(url);
|
||||
console.info("Redirecting", `"${url.href}"`, "=>", `"${redirect}"`);
|
||||
window.location = redirect;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
|
@ -1,44 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const nitterDefault = 'https://nitter.net';
|
||||
|
||||
let disableNitter;
|
||||
let nitterInstance;
|
||||
|
||||
window.browser = window.browser || window.chrome;
|
||||
|
||||
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'],
|
||||
(result) => {
|
||||
if (!result.removeTwitterSW) {
|
||||
disableNitter = result.disableNitter;
|
||||
nitterInstance = result.nitterInstance || nitterDefault;
|
||||
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 (!disableNitter && url.host !== nitterInstance) {
|
||||
const redirect = redirectTwitter(url);
|
||||
console.info(
|
||||
'Redirecting', `"${url.href}"`, '=>', `"${redirect}"`
|
||||
);
|
||||
window.location = redirect;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
|
@ -1,268 +0,0 @@
|
|||
/*
|
||||
Retrieved February 19, 2020, from https://s.ytimg.com/yts/jsbin/www-widgetapi-vflYl14TA/www-widgetapi.js
|
||||
*/
|
||||
|
||||
(function () {/*
|
||||
|
||||
Copyright The Closure Library Authors.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var k; function aa() { var a = l, b = 0; return function () { return b < a.length ? { done: !1, value: a[b++] } : { done: !0 } } }
|
||||
var ba = "function" == typeof Object.create ? Object.create : function (a) {
|
||||
function b() { }
|
||||
b.prototype = a; return new b
|
||||
}, p;
|
||||
if ("function" == typeof Object.setPrototypeOf) p = Object.setPrototypeOf; else { var q; a: { var ca = { K: !0 }, da = {}; try { da.__proto__ = ca; q = da.K; break a } catch (a) { } q = !1 } p = q ? function (a, b) { a.__proto__ = b; if (a.__proto__ !== b) throw new TypeError(a + " is not extensible"); return a } : null } var ea = p;
|
||||
function fa(a, b) { a.prototype = ba(b.prototype); a.prototype.constructor = a; if (ea) ea(a, b); else for (var c in b) if ("prototype" != c) if (Object.defineProperties) { var d = Object.getOwnPropertyDescriptor(b, c); d && Object.defineProperty(a, c, d) } else a[c] = b[c]; a.J = b.prototype }
|
||||
var ha = "function" == typeof Object.defineProperties ? Object.defineProperty : function (a, b, c) { a != Array.prototype && a != Object.prototype && (a[b] = c.value) };
|
||||
function ia(a) { a = ["object" == typeof window && window, "object" == typeof self && self, "object" == typeof global && global, a]; for (var b = 0; b < a.length; ++b) { var c = a[b]; if (c && c.Math == Math) return c } return globalThis }
|
||||
var ja = ia(this); function ka(a, b) { if (b) { for (var c = ja, d = a.split("."), e = 0; e < d.length - 1; e++) { var f = d[e]; f in c || (c[f] = {}); c = c[f] } d = d[d.length - 1]; e = c[d]; f = b(e); f != e && null != f && ha(c, d, { configurable: !0, writable: !0, value: f }) } }
|
||||
var la = "function" == typeof Object.assign ? Object.assign : function (a, b) { for (var c = 1; c < arguments.length; c++) { var d = arguments[c]; if (d) for (var e in d) Object.prototype.hasOwnProperty.call(d, e) && (a[e] = d[e]) } return a };
|
||||
ka("Object.assign", function (a) { return a || la });
|
||||
var r = this || self; function v(a) { a = a.split("."); for (var b = r, c = 0; c < a.length; c++)if (b = b[a[c]], null == b) return null; return b }
|
||||
function ma() { }
|
||||
function w(a) {
|
||||
var b = typeof a; if ("object" == b) if (a) { if (a instanceof Array) return "array"; if (a instanceof Object) return b; var c = Object.prototype.toString.call(a); if ("[object Window]" == c) return "object"; if ("[object Array]" == c || "number" == typeof a.length && "undefined" != typeof a.splice && "undefined" != typeof a.propertyIsEnumerable && !a.propertyIsEnumerable("splice")) return "array"; if ("[object Function]" == c || "undefined" != typeof a.call && "undefined" != typeof a.propertyIsEnumerable && !a.propertyIsEnumerable("call")) return "function" } else return "null";
|
||||
else if ("function" == b && "undefined" == typeof a.call) return "object"; return b
|
||||
}
|
||||
function x(a) { var b = typeof a; return "object" == b && null != a || "function" == b }
|
||||
function na(a) { return Object.prototype.hasOwnProperty.call(a, y) && a[y] || (a[y] = ++oa) }
|
||||
var y = "closure_uid_" + (1E9 * Math.random() >>> 0), oa = 0; function pa(a, b, c) { return a.call.apply(a.bind, arguments) }
|
||||
function qa(a, b, c) { if (!a) throw Error(); if (2 < arguments.length) { var d = Array.prototype.slice.call(arguments, 2); return function () { var e = Array.prototype.slice.call(arguments); Array.prototype.unshift.apply(e, d); return a.apply(b, e) } } return function () { return a.apply(b, arguments) } }
|
||||
function z(a, b, c) { Function.prototype.bind && -1 != Function.prototype.bind.toString().indexOf("native code") ? z = pa : z = qa; return z.apply(null, arguments) }
|
||||
var ra = Date.now || function () { return +new Date };
|
||||
function A(a, b) { var c = a.split("."), d = r; c[0] in d || "undefined" == typeof d.execScript || d.execScript("var " + c[0]); for (var e; c.length && (e = c.shift());)c.length || void 0 === b ? d[e] && d[e] !== Object.prototype[e] ? d = d[e] : d = d[e] = {} : d[e] = b }
|
||||
function sa(a, b) {
|
||||
function c() { }
|
||||
c.prototype = b.prototype; a.J = b.prototype; a.prototype = new c; a.prototype.constructor = a
|
||||
}
|
||||
; var ta = Array.prototype.indexOf ? function (a, b) { return Array.prototype.indexOf.call(a, b, void 0) } : function (a, b) {
|
||||
if ("string" === typeof a) return "string" !== typeof b || 1 != b.length ? -1 : a.indexOf(b, 0);
|
||||
for (var c = 0; c < a.length; c++)if (c in a && a[c] === b) return c; return -1
|
||||
}, B = Array.prototype.forEach ? function (a, b, c) { Array.prototype.forEach.call(a, b, c) } : function (a, b, c) { for (var d = a.length, e = "string" === typeof a ? a.split("") : a, f = 0; f < d; f++)f in e && b.call(c, e[f], f, a) }, ua = Array.prototype.reduce ? function (a, b, c) { return Array.prototype.reduce.call(a, b, c) } : function (a, b, c) {
|
||||
var d = c;
|
||||
B(a, function (e, f) { d = b.call(void 0, d, e, f, a) });
|
||||
return d
|
||||
};
|
||||
function va(a, b) { a: { var c = a.length; for (var d = "string" === typeof a ? a.split("") : a, e = 0; e < c; e++)if (e in d && b.call(void 0, d[e], e, a)) { c = e; break a } c = -1 } return 0 > c ? null : "string" === typeof a ? a.charAt(c) : a[c] }
|
||||
function wa(a) { return Array.prototype.concat.apply([], arguments) }
|
||||
function xa(a) { var b = a.length; if (0 < b) { for (var c = Array(b), d = 0; d < b; d++)c[d] = a[d]; return c } return [] }
|
||||
; function ya(a) { var b = !1, c; return function () { b || (c = a(), b = !0); return c } }
|
||||
; var za = /&/g, Aa = /</g, Ba = />/g, Ca = /"/g, Da = /'/g, Ea = /\x00/g, Fa = /[\x00&<>"']/; var E; a: { var Ga = r.navigator; if (Ga) { var Ha = Ga.userAgent; if (Ha) { E = Ha; break a } } E = "" }; function Ia(a, b) { for (var c in a) b.call(void 0, a[c], c, a) }
|
||||
function Ja(a) { var b = F, c; for (c in b) if (a.call(void 0, b[c], c, b)) return c }
|
||||
; function G(a, b) { this.b = a === Ka && b || ""; this.a = La }
|
||||
var La = {}, Ka = {}, H = new G(Ka, ""); function I(a, b) { this.b = a === Ma && b || ""; this.a = Na }
|
||||
var Na = {}, Ma = {}; function Oa() { this.a = ""; this.b = Pa }
|
||||
var Pa = {}; function Qa(a) { var b = new Oa; b.a = a; return b }
|
||||
Qa("<!DOCTYPE html>"); var J = Qa(""); Qa("<br>"); function Ra(a) { var b = new I(Ma, H instanceof G && H.constructor === G && H.a === La ? H.b : "type_error:Const"); a.src = (b instanceof I && b.constructor === I && b.a === Na ? b.b : "type_error:TrustedResourceUrl").toString() }
|
||||
; var K = window; function L(a, b) { this.width = a; this.height = b }
|
||||
L.prototype.aspectRatio = function () { return this.width / this.height };
|
||||
L.prototype.ceil = function () { this.width = Math.ceil(this.width); this.height = Math.ceil(this.height); return this };
|
||||
L.prototype.floor = function () { this.width = Math.floor(this.width); this.height = Math.floor(this.height); return this };
|
||||
L.prototype.round = function () { this.width = Math.round(this.width); this.height = Math.round(this.height); return this }; function Sa(a, b) { var c, d; var e = document; e = b || e; if (e.querySelectorAll && e.querySelector && a) return e.querySelectorAll(a ? "." + a : ""); if (a && e.getElementsByClassName) { var f = e.getElementsByClassName(a); return f } f = e.getElementsByTagName("*"); if (a) { var g = {}; for (c = d = 0; e = f[c]; c++) { var h = e.className, m; if (m = "function" == typeof h.split) m = 0 <= ta(h.split(/\s+/), a); m && (g[d++] = e) } g.length = d; return g } return f }
|
||||
function M(a) { var b = document; a = String(a); "application/xhtml+xml" === b.contentType && (a = a.toLowerCase()); return b.createElement(a) }
|
||||
function Ta(a, b) { for (var c = 0; a;) { if (b(a)) return a; a = a.parentNode; c++ } return null }
|
||||
; var Ua = /^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/\\#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#([\s\S]*))?$/; function Va(a) { var b = a.match(Ua); a = b[1]; var c = b[2], d = b[3]; b = b[4]; var e = ""; a && (e += a + ":"); d && (e += "//", c && (e += c + "@"), e += d, b && (e += ":" + b)); return e }
|
||||
function Wa(a, b, c) { if ("array" == w(b)) for (var d = 0; d < b.length; d++)Wa(a, String(b[d]), c); else null != b && c.push(a + ("" === b ? "" : "=" + encodeURIComponent(String(b)))) }
|
||||
function Xa(a) { var b = [], c; for (c in a) Wa(c, a[c], b); return b.join("&") }
|
||||
var Ya = /#|$/; function Za(a) { var b = $a; if (b) for (var c in b) Object.prototype.hasOwnProperty.call(b, c) && a.call(void 0, b[c], c, b) }
|
||||
function ab() {
|
||||
var a = []; Za(function (b) { a.push(b) });
|
||||
return a
|
||||
}
|
||||
var $a = { M: "allow-forms", N: "allow-modals", O: "allow-orientation-lock", P: "allow-pointer-lock", R: "allow-popups", S: "allow-popups-to-escape-sandbox", T: "allow-presentation", U: "allow-same-origin", V: "allow-scripts", W: "allow-top-navigation", X: "allow-top-navigation-by-user-activation" }, bb = ya(function () { return ab() });
|
||||
function cb() {
|
||||
var a = M("IFRAME"), b = {}; B(bb(), function (c) { a.sandbox && a.sandbox.supports && a.sandbox.supports(c) && (b[c] = !0) });
|
||||
return b
|
||||
}
|
||||
; var db = (new Date).getTime(); function eb() { this.b = []; this.a = -1 }
|
||||
eb.prototype.set = function (a, b) { b = void 0 === b ? !0 : b; 0 <= a && 52 > a && 0 === a % 1 && this.b[a] != b && (this.b[a] = b, this.a = -1) };
|
||||
eb.prototype.get = function (a) { return !!this.b[a] };
|
||||
function fb(a) {
|
||||
-1 == a.a && (a.a = ua(a.b, function (b, c, d) { return c ? b + Math.pow(2, d) : b }, 0));
|
||||
return a.a
|
||||
}
|
||||
; function gb(a, b) { this.f = a; this.g = b; this.b = 0; this.a = null }
|
||||
gb.prototype.get = function () { if (0 < this.b) { this.b--; var a = this.a; this.a = a.next; a.next = null } else a = this.f(); return a }; function hb(a) { r.setTimeout(function () { throw a; }, 0) }
|
||||
var ib;
|
||||
function jb() {
|
||||
var a = r.MessageChannel; "undefined" === typeof a && "undefined" !== typeof window && window.postMessage && window.addEventListener && -1 == E.indexOf("Presto") && (a = function () {
|
||||
var e = M("IFRAME"); e.style.display = "none"; Ra(e); document.documentElement.appendChild(e); var f = e.contentWindow; e = f.document; e.open(); e.write(J instanceof Oa && J.constructor === Oa && J.b === Pa ? J.a : "type_error:SafeHtml"); e.close(); var g = "callImmediate" + Math.random(), h = "file:" == f.location.protocol ? "*" : f.location.protocol + "//" + f.location.host; e =
|
||||
z(function (m) { if (("*" == h || m.origin == h) && m.data == g) this.port1.onmessage() }, this);
|
||||
f.addEventListener("message", e, !1); this.port1 = {}; this.port2 = { postMessage: function () { f.postMessage(g, h) } }
|
||||
});
|
||||
if ("undefined" !== typeof a && -1 == E.indexOf("Trident") && -1 == E.indexOf("MSIE")) {
|
||||
var b = new a, c = {}, d = c; b.port1.onmessage = function () { if (void 0 !== c.next) { c = c.next; var e = c.C; c.C = null; e() } };
|
||||
return function (e) { d.next = { C: e }; d = d.next; b.port2.postMessage(0) }
|
||||
} return "undefined" !== typeof document && "onreadystatechange" in M("SCRIPT") ? function (e) {
|
||||
var f = M("SCRIPT");
|
||||
f.onreadystatechange = function () { f.onreadystatechange = null; f.parentNode.removeChild(f); f = null; e(); e = null };
|
||||
document.documentElement.appendChild(f)
|
||||
} : function (e) { r.setTimeout(e, 0) }
|
||||
}
|
||||
; function kb() { this.b = this.a = null }
|
||||
var mb = new gb(function () { return new lb }, function (a) { a.reset() });
|
||||
kb.prototype.add = function (a, b) { var c = mb.get(); c.set(a, b); this.b ? this.b.next = c : this.a = c; this.b = c };
|
||||
kb.prototype.remove = function () { var a = null; this.a && (a = this.a, this.a = this.a.next, this.a || (this.b = null), a.next = null); return a };
|
||||
function lb() { this.next = this.b = this.a = null }
|
||||
lb.prototype.set = function (a, b) { this.a = a; this.b = b; this.next = null };
|
||||
lb.prototype.reset = function () { this.next = this.b = this.a = null }; function nb(a) { N || ob(); pb || (N(), pb = !0); qb.add(a, void 0) }
|
||||
var N; function ob() {
|
||||
if (r.Promise && r.Promise.resolve) { var a = r.Promise.resolve(void 0); N = function () { a.then(rb) } } else N = function () {
|
||||
var b = rb, c;
|
||||
!(c = "function" != w(r.setImmediate)) && (c = r.Window && r.Window.prototype) && (c = -1 == E.indexOf("Edge") && r.Window.prototype.setImmediate == r.setImmediate); c ? (ib || (ib = jb()), ib(b)) : r.setImmediate(b)
|
||||
}
|
||||
}
|
||||
var pb = !1, qb = new kb; function rb() { for (var a; a = qb.remove();) { try { a.a.call(a.b) } catch (c) { hb(c) } var b = mb; b.g(a); 100 > b.b && (b.b++ , a.next = b.a, b.a = a) } pb = !1 }
|
||||
; function O() { this.f = this.f; this.g = this.g }
|
||||
O.prototype.f = !1; O.prototype.dispose = function () { this.f || (this.f = !0, this.w()) };
|
||||
O.prototype.w = function () { if (this.g) for (; this.g.length;)this.g.shift()() }; var sb = r.JSON.stringify; function P(a) { O.call(this); this.m = 1; this.h = []; this.i = 0; this.a = []; this.b = {}; this.o = !!a }
|
||||
sa(P, O); k = P.prototype; k.subscribe = function (a, b, c) { var d = this.b[a]; d || (d = this.b[a] = []); var e = this.m; this.a[e] = a; this.a[e + 1] = b; this.a[e + 2] = c; this.m = e + 3; d.push(e); return e };
|
||||
function tb(a, b, c) { var d = Q; if (a = d.b[a]) { var e = d.a; (a = va(a, function (f) { return e[f + 1] == b && e[f + 2] == c })) && d.B(a) } }
|
||||
k.B = function (a) { var b = this.a[a]; if (b) { var c = this.b[b]; if (0 != this.i) this.h.push(a), this.a[a + 1] = ma; else { if (c) { var d = ta(c, a); 0 <= d && Array.prototype.splice.call(c, d, 1) } delete this.a[a]; delete this.a[a + 1]; delete this.a[a + 2] } } return !!b };
|
||||
k.G = function (a, b) { var c = this.b[a]; if (c) { for (var d = Array(arguments.length - 1), e = 1, f = arguments.length; e < f; e++)d[e - 1] = arguments[e]; if (this.o) for (e = 0; e < c.length; e++) { var g = c[e]; ub(this.a[g + 1], this.a[g + 2], d) } else { this.i++; try { for (e = 0, f = c.length; e < f; e++)g = c[e], this.a[g + 1].apply(this.a[g + 2], d) } finally { if (this.i-- , 0 < this.h.length && 0 == this.i) for (; c = this.h.pop();)this.B(c) } } return 0 != e } return !1 };
|
||||
function ub(a, b, c) { nb(function () { a.apply(b, c) }) }
|
||||
k.clear = function (a) { if (a) { var b = this.b[a]; b && (B(b, this.B, this), delete this.b[a]) } else this.a.length = 0, this.b = {} };
|
||||
k.w = function () { P.J.w.call(this); this.clear(); this.h.length = 0 }; var R = window.yt && window.yt.config_ || window.ytcfg && window.ytcfg.data_ || {}; A("yt.config_", R); function vb(a) { var b = arguments; 1 < b.length ? R[b[0]] = b[1] : 1 === b.length && Object.assign(R, b[0]) }
|
||||
function wb() { var a = []; return "ERRORS" in R ? R.ERRORS : a }
|
||||
; var xb = []; function yb(a) { xb.forEach(function (b) { return b(a) }) }
|
||||
function zb(a) { return a && window.yterr ? function () { try { return a.apply(this, arguments) } catch (d) { var b = d, c = v("yt.logging.errors.log"); c ? c(b, "ERROR", void 0, void 0, void 0) : (c = wb(), c.push([b, "ERROR", void 0, void 0, void 0]), vb("ERRORS", c)); yb(d) } } : a }
|
||||
; var Ab = 0; A("ytDomDomGetNextId", v("ytDomDomGetNextId") || function () { return ++Ab }); var Bb = { stopImmediatePropagation: 1, stopPropagation: 1, preventMouseEvent: 1, preventManipulation: 1, preventDefault: 1, layerX: 1, layerY: 1, screenX: 1, screenY: 1, scale: 1, rotation: 1, webkitMovementX: 1, webkitMovementY: 1 };
|
||||
function S(a) {
|
||||
this.type = ""; this.state = this.source = this.data = this.currentTarget = this.relatedTarget = this.target = null; this.charCode = this.keyCode = 0; this.metaKey = this.shiftKey = this.ctrlKey = this.altKey = !1; this.clientY = this.clientX = 0; this.changedTouches = this.touches = null; try {
|
||||
if (a = a || window.event) {
|
||||
this.event = a; for (var b in a) b in Bb || (this[b] = a[b]); var c = a.target || a.srcElement; c && 3 == c.nodeType && (c = c.parentNode); this.target = c; var d = a.relatedTarget; if (d) try { d = d.nodeName ? d : null } catch (e) { d = null } else "mouseover" ==
|
||||
this.type ? d = a.fromElement : "mouseout" == this.type && (d = a.toElement); this.relatedTarget = d; this.clientX = void 0 != a.clientX ? a.clientX : a.pageX; this.clientY = void 0 != a.clientY ? a.clientY : a.pageY; this.keyCode = a.keyCode ? a.keyCode : a.which; this.charCode = a.charCode || ("keypress" == this.type ? this.keyCode : 0); this.altKey = a.altKey; this.ctrlKey = a.ctrlKey; this.shiftKey = a.shiftKey; this.metaKey = a.metaKey
|
||||
}
|
||||
} catch (e) { }
|
||||
}
|
||||
S.prototype.preventDefault = function () { this.event && (this.event.returnValue = !1, this.event.preventDefault && this.event.preventDefault()) };
|
||||
S.prototype.stopPropagation = function () { this.event && (this.event.cancelBubble = !0, this.event.stopPropagation && this.event.stopPropagation()) };
|
||||
S.prototype.stopImmediatePropagation = function () { this.event && (this.event.cancelBubble = !0, this.event.stopImmediatePropagation && this.event.stopImmediatePropagation()) }; var F = v("ytEventsEventsListeners") || {}; A("ytEventsEventsListeners", F); var Cb = v("ytEventsEventsCounter") || { count: 0 }; A("ytEventsEventsCounter", Cb);
|
||||
function Db(a, b, c, d) {
|
||||
d = void 0 === d ? {} : d; a.addEventListener && ("mouseenter" != b || "onmouseenter" in document ? "mouseleave" != b || "onmouseenter" in document ? "mousewheel" == b && "MozBoxSizing" in document.documentElement.style && (b = "MozMousePixelScroll") : b = "mouseout" : b = "mouseover"); return Ja(function (e) {
|
||||
var f = "boolean" === typeof e[4] && e[4] == !!d, g; if (g = x(e[4]) && x(d)) a: { g = e[4]; for (var h in g) if (!(h in d) || g[h] !== d[h]) { g = !1; break a } for (var m in d) if (!(m in g)) { g = !1; break a } g = !0 } return !!e.length && e[0] == a && e[1] == b && e[2] ==
|
||||
c && (f || g)
|
||||
})
|
||||
}
|
||||
function Eb(a) { a && ("string" == typeof a && (a = [a]), B(a, function (b) { if (b in F) { var c = F[b], d = c[0], e = c[1], f = c[3]; c = c[4]; d.removeEventListener ? Fb() || "boolean" === typeof c ? d.removeEventListener(e, f, c) : d.removeEventListener(e, f, !!c.capture) : d.detachEvent && d.detachEvent("on" + e, f); delete F[b] } })) }
|
||||
var Fb = ya(function () {
|
||||
var a = !1; try {
|
||||
var b = Object.defineProperty({}, "capture", { get: function () { a = !0 } });
|
||||
window.addEventListener("test", null, b)
|
||||
} catch (c) { } return a
|
||||
});
|
||||
function Gb(a, b, c) {
|
||||
var d = void 0 === d ? {} : d; if (a && (a.addEventListener || a.attachEvent)) {
|
||||
var e = Db(a, b, c, d); if (!e) {
|
||||
e = ++Cb.count + ""; var f = !("mouseenter" != b && "mouseleave" != b || !a.addEventListener || "onmouseenter" in document); var g = f ? function (h) { h = new S(h); if (!Ta(h.relatedTarget, function (m) { return m == a })) return h.currentTarget = a, h.type = b, c.call(a, h) } : function (h) {
|
||||
h = new S(h);
|
||||
h.currentTarget = a; return c.call(a, h)
|
||||
};
|
||||
g = zb(g); a.addEventListener ? ("mouseenter" == b && f ? b = "mouseover" : "mouseleave" == b && f ? b = "mouseout" : "mousewheel" == b && "MozBoxSizing" in document.documentElement.style && (b = "MozMousePixelScroll"), Fb() || "boolean" === typeof d ? a.addEventListener(b, g, d) : a.addEventListener(b, g, !!d.capture)) : a.attachEvent("on" + b, g); F[e] = [a, b, c, g, d]
|
||||
}
|
||||
}
|
||||
}
|
||||
; function Hb(a) { "function" == w(a) && (a = zb(a)); return window.setInterval(a, 250) }
|
||||
; function Ib(a) {
|
||||
var b = []; Ia(a, function (c, d) { var e = encodeURIComponent(String(d)), f; "array" == w(c) ? f = c : f = [c]; B(f, function (g) { "" == g ? b.push(e) : b.push(e + "=" + encodeURIComponent(String(g))) }) });
|
||||
return b.join("&")
|
||||
}
|
||||
; var Jb = {}; function Kb(a) { return Jb[a] || (Jb[a] = String(a).replace(/\-([a-z])/g, function (b, c) { return c.toUpperCase() })) }
|
||||
; var T = {}, l = [], Q = new P, Lb = {}; function Mb() { var a = "undefined" != typeof Symbol && Symbol.iterator && l[Symbol.iterator]; var b; a ? b = a.call(l) : b = { next: aa() }; a = b; for (b = a.next(); !b.done; b = a.next())b = b.value, b() }
|
||||
function Nb(a, b) { b || (b = document); var c = xa(b.getElementsByTagName("yt:" + a)), d = "yt-" + a, e = b || document; d = xa(e.querySelectorAll && e.querySelector ? e.querySelectorAll("." + d) : Sa(d, b)); return wa(c, d) }
|
||||
function U(a, b) { var c; "yt:" == a.tagName.toLowerCase().substr(0, 3) ? c = a.getAttribute(b) : c = a ? a.dataset ? a.dataset[Kb(b)] : a.getAttribute("data-" + b) : null; return c }
|
||||
function Ob(a, b) { Q.G.apply(Q, arguments) }
|
||||
; function Pb(a) { this.b = a || {}; this.f = this.a = !1; a = document.getElementById("www-widgetapi-script"); if (this.a = !!("https:" == document.location.protocol || a && 0 == a.src.indexOf("https:"))) { a = [this.b, window.YTConfig || {}]; for (var b = 0; b < a.length; b++)a[b].host && (a[b].host = a[b].host.replace("http://", "https://")) } }
|
||||
function V(a, b) { for (var c = [a.b, window.YTConfig || {}], d = 0; d < c.length; d++) { var e = c[d][b]; if (void 0 != e) return e } return null }
|
||||
function Qb(a, b, c) { W || (W = {}, Gb(window, "message", z(a.g, a))); W[c] = b }
|
||||
Pb.prototype.g = function (a) { if (a.origin == V(this, "host") || a.origin == V(this, "host").replace(/^http:/, "https:")) { try { var b = JSON.parse(a.data) } catch (c) { return } this.f = !0; this.a || 0 != a.origin.indexOf("https:") || (this.a = !0); if (a = W[b.id]) a.o = !0, a.o && (B(a.m, a.A, a), a.m.length = 0), a.H(b) } };
|
||||
var W = null; function Rb() {
|
||||
var a = Sb, b = {}; b.dt = db; b.flash = "0"; a: { try { var c = a.a.top.location.href } catch (f) { a = 2; break a } a = c ? c === a.b.location.href ? 0 : 1 : 2 } b = (b.frm = a, b); b.u_tz = -(new Date).getTimezoneOffset(); var d = void 0 === d ? K : d; try { var e = d.history.length } catch (f) { e = 0 } b.u_his = e; b.u_java = !!K.navigator && "unknown" !== typeof K.navigator.javaEnabled && !!K.navigator.javaEnabled && K.navigator.javaEnabled(); K.screen && (b.u_h = K.screen.height, b.u_w = K.screen.width, b.u_ah = K.screen.availHeight, b.u_aw = K.screen.availWidth, b.u_cd = K.screen.colorDepth);
|
||||
K.navigator && K.navigator.plugins && (b.u_nplug = K.navigator.plugins.length); K.navigator && K.navigator.mimeTypes && (b.u_nmime = K.navigator.mimeTypes.length); return b
|
||||
}
|
||||
function Tb() {
|
||||
var a = Sb; var b = a.a; try { var c = b.screenX; var d = b.screenY } catch (t) { } try { var e = b.outerWidth; var f = b.outerHeight } catch (t) { } try { var g = b.innerWidth; var h = b.innerHeight } catch (t) { } b = [b.screenLeft, b.screenTop, c, d, b.screen ? b.screen.availWidth : void 0, b.screen ? b.screen.availTop : void 0, e, f, g, h]; c = a.a.top; try { var m = (c || window).document, n = "CSS1Compat" == m.compatMode ? m.documentElement : m.body; var u = (new L(n.clientWidth, n.clientHeight)).round() } catch (t) { u = new L(-12245933, -12245933) } m = u; u = {}; n = new eb; r.SVGElement &&
|
||||
r.document.createElementNS && n.set(0); c = cb(); c["allow-top-navigation-by-user-activation"] && n.set(1); c["allow-popups-to-escape-sandbox"] && n.set(2); r.crypto && r.crypto.subtle && n.set(3); r.TextDecoder && r.TextEncoder && n.set(4); n = fb(n); u.bc = n; u.bih = m.height; u.biw = m.width; u.brdim = b.join(); a = a.b; return u.vis = { visible: 1, hidden: 2, prerender: 3, preview: 4, unloaded: 5 }[a.visibilityState || a.webkitVisibilityState || a.mozVisibilityState || ""] || 0, u.wgl = !!K.WebGLRenderingContext, u
|
||||
}
|
||||
var Sb = new function () { var a = window.document; this.a = window; this.b = a };
|
||||
A("yt.ads_.signals_.getAdSignalsString", function (a) { a = void 0 === a ? v("yt.ads.biscotti.lastId_") || "" : a; var b = Object.assign(Rb(), Tb()); b.ca_type = "image"; a && (b.bid = a); return Ib(b) }); ra(); function X(a, b, c) {
|
||||
this.i = this.a = this.b = null; this.h = na(this); this.f = 0; this.o = !1; this.m = []; this.g = null; this.D = c; this.I = {}; c = document; if (a = "string" === typeof a ? c.getElementById(a) : a) if (c = "iframe" == a.tagName.toLowerCase(), b.host || (b.host = c ? Va(a.src) : "https://www.youtube.com"), this.b = new Pb(b), c || (b = Ub(this, a), this.i = a, (c = a.parentNode) && c.replaceChild(b, a), a = b), this.a = a, this.a.id || (this.a.id = "widget" + na(this.a)), T[this.a.id] = this, window.postMessage) {
|
||||
this.g = new P; Vb(this); b = V(this.b, "events"); for (var d in b) b.hasOwnProperty(d) &&
|
||||
this.addEventListener(d, b[d]); for (var e in Lb) Wb(this, e)
|
||||
}
|
||||
}
|
||||
k = X.prototype; k.setSize = function (a, b) { this.a.width = a; this.a.height = b; return this };
|
||||
k.L = function () { return this.a };
|
||||
k.H = function (a) { this.s(a.event, a) };
|
||||
k.addEventListener = function (a, b) {
|
||||
var c = b; "string" == typeof b && (c = function () { window[b].apply(window, arguments) });
|
||||
if (!c) return this; this.g.subscribe(a, c); Xb(this, a); return this
|
||||
};
|
||||
function Wb(a, b) { var c = b.split("."); if (2 == c.length) { var d = c[1]; a.D == c[0] && Xb(a, d) } }
|
||||
k.destroy = function () { this.a.id && (T[this.a.id] = null); var a = this.g; a && "function" == typeof a.dispose && a.dispose(); if (this.i) { a = this.a; var b = a.parentNode; b && b.replaceChild(this.i, a) } else (a = this.a) && a.parentNode && a.parentNode.removeChild(a); W && (W[this.h] = null); this.b = null; a = this.a; for (var c in F) F[c][0] == a && Eb(c); this.i = this.a = null };
|
||||
k.u = function () { return {} };
|
||||
function Yb(a, b, c) { c = c || []; c = Array.prototype.slice.call(c); b = { event: "command", func: b, args: c }; a.o ? a.A(b) : a.m.push(b) }
|
||||
k.s = function (a, b) { if (!this.g.f) { var c = { target: this, data: b }; this.g.G(a, c); Ob(this.D + "." + a, c) } };
|
||||
function Ub(a, b) {
|
||||
for (var c = document.createElement("iframe"), d = b.attributes, e = 0, f = d.length; e < f; e++) { var g = d[e].value; null != g && "" != g && "null" != g && c.setAttribute(d[e].name, g) } c.setAttribute("frameBorder", 0); c.setAttribute("allowfullscreen", 1); c.setAttribute("allow", "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"); c.setAttribute("title", "YouTube " + V(a.b, "title")); (d = V(a.b, "width")) && c.setAttribute("width", d); (d = V(a.b, "height")) && c.setAttribute("height", d); var h = a.u(); h.enablejsapi =
|
||||
window.postMessage ? 1 : 0; window.location.host && (h.origin = window.location.protocol + "//" + window.location.host); h.widgetid = a.h; window.location.href && B(["debugjs", "debugcss"], function (m) {
|
||||
var n = window.location.href; var u = n.search(Ya); b: { var t = 0; for (var C = m.length; 0 <= (t = n.indexOf(m, t)) && t < u;) { var D = n.charCodeAt(t - 1); if (38 == D || 63 == D) if (D = n.charCodeAt(t + C), !D || 61 == D || 38 == D || 35 == D) break b; t += C + 1 } t = -1 } if (0 > t) n = null; else {
|
||||
C = n.indexOf("&", t); if (0 > C || C > u) C = u; t += m.length + 1; n = decodeURIComponent(n.substr(t, C - t).replace(/\+/g,
|
||||
" "))
|
||||
} null !== n && (h[m] = n)
|
||||
});
|
||||
c.src = V(a.b, "host") + a.v() + "?" + Xa(h); return c
|
||||
}
|
||||
k.F = function () { this.a && this.a.contentWindow ? this.A({ event: "listening" }) : window.clearInterval(this.f) };
|
||||
function Vb(a) { Qb(a.b, a, a.h); a.f = Hb(z(a.F, a)); Gb(a.a, "load", z(function () { window.clearInterval(this.f); this.f = Hb(z(this.F, this)) }, a)) }
|
||||
function Xb(a, b) { a.I[b] || (a.I[b] = !0, Yb(a, "addEventListener", [b])) }
|
||||
k.A = function (a) {
|
||||
a.id = this.h; a.channel = "widget"; a = sb(a); var b = this.b; var c = Va(this.a.src || ""); b = 0 == c.indexOf("https:") ? [c] : b.a ? [c.replace("http:", "https:")] : b.f ? [c] : [c, c.replace("http:", "https:")]; if (this.a.contentWindow) for (c = 0; c < b.length; c++)try { this.a.contentWindow.postMessage(a, b[c]) } catch (f) {
|
||||
if (f.name && "SyntaxError" == f.name) {
|
||||
if (!(f.message && 0 < f.message.indexOf("target origin ''"))) {
|
||||
var d = f, e = v("yt.logging.errors.log"); e ? e(d, "WARNING", void 0, void 0, !1, void 0) : (e = wb(), e.push([d, "WARNING", void 0,
|
||||
void 0, !1, void 0]), vb("ERRORS", e))
|
||||
}
|
||||
} else throw f;
|
||||
} else console && console.warn && console.warn("The YouTube player is not attached to the DOM. API calls should be made after the onReady event. See more: https://developers.google.com/youtube/iframe_api_reference#Events")
|
||||
}; function Zb(a) { return (0 == a.search("cue") || 0 == a.search("load")) && "loadModule" != a }
|
||||
function $b(a) { return 0 == a.search("get") || 0 == a.search("is") }
|
||||
; function Y(a, b) { if (!a) throw Error("YouTube player element ID required."); var c = { title: "video player", videoId: "", width: 640, height: 360 }; if (b) for (var d in b) c[d] = b[d]; X.call(this, a, c, "player"); this.j = {}; this.l = {} }
|
||||
fa(Y, X); k = Y.prototype; k.v = function () { return "/embed/" + V(this.b, "videoId") };
|
||||
k.u = function () { var a = V(this.b, "playerVars"); if (a) { var b = {}, c; for (c in a) b[c] = a[c]; a = b } else a = {}; window != window.top && document.referrer && (a.widget_referrer = document.referrer.substring(0, 256)); if (c = V(this.b, "embedConfig")) { if (x(c)) try { c = JSON.stringify(c) } catch (d) { console.error("Invalid embed config JSON", d) } a.embed_config = c } return a };
|
||||
k.H = function (a) { var b = a.event; a = a.info; switch (b) { case "apiInfoDelivery": if (x(a)) for (var c in a) this.j[c] = a[c]; break; case "infoDelivery": ac(this, a); break; case "initialDelivery": window.clearInterval(this.f); this.l = {}; this.j = {}; bc(this, a.apiInterface); ac(this, a); break; default: this.s(b, a) } };
|
||||
function ac(a, b) { if (x(b)) for (var c in b) a.l[c] = b[c] }
|
||||
function bc(a, b) {
|
||||
B(b, function (c) {
|
||||
this[c] || ("getCurrentTime" == c ? this[c] = function () { var d = this.l.currentTime; if (1 == this.l.playerState) { var e = (ra() / 1E3 - this.l.currentTimeLastUpdated_) * this.l.playbackRate; 0 < e && (d += Math.min(e, 1)) } return d } : Zb(c) ? this[c] = function () {
|
||||
this.l = {};
|
||||
this.j = {}; Yb(this, c, arguments); return this
|
||||
} : $b(c) ? this[c] = function () {
|
||||
var d = 0;
|
||||
0 == c.search("get") ? d = 3 : 0 == c.search("is") && (d = 2); return this.l[c.charAt(d).toLowerCase() + c.substr(d + 1)]
|
||||
} : this[c] = function () {
|
||||
Yb(this, c, arguments);
|
||||
return this
|
||||
})
|
||||
}, a)
|
||||
}
|
||||
k.getVideoEmbedCode = function () {
|
||||
var a = parseInt(V(this.b, "width"), 10); var b = parseInt(V(this.b, "height"), 10), c = V(this.b, "host") + this.v(); Fa.test(c) && (-1 != c.indexOf("&") && (c = c.replace(za, "&")), -1 != c.indexOf("<") && (c = c.replace(Aa, "<")), -1 != c.indexOf(">") && (c = c.replace(Ba, ">")), -1 != c.indexOf('"') && (c = c.replace(Ca, """)), -1 != c.indexOf("'") && (c = c.replace(Da, "'")), -1 != c.indexOf("\x00") && (c = c.replace(Ea, "�"))); a = '<iframe width="' + a + '" height="' + b + '" src="' + c + '" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>';
|
||||
return a
|
||||
};
|
||||
k.getOptions = function (a) { return this.j.namespaces ? a ? this.j[a].options || [] : this.j.namespaces || [] : [] };
|
||||
k.getOption = function (a, b) { if (this.j.namespaces && a && b) return this.j[a][b] };
|
||||
function cc(a) { if ("iframe" != a.tagName.toLowerCase()) { var b = U(a, "videoid"); b && (b = { videoId: b, width: U(a, "width"), height: U(a, "height") }, new Y(a, b)) } }
|
||||
; function Z(a, b) { var c = { title: "Thumbnail", videoId: "", width: 120, height: 68 }; if (b) for (var d in b) c[d] = b[d]; X.call(this, a, c, "thumbnail") }
|
||||
fa(Z, X); Z.prototype.v = function () { return "/embed/" + V(this.b, "videoId") };
|
||||
Z.prototype.u = function () { return { player: 0, thumb_width: V(this.b, "thumbWidth"), thumb_height: V(this.b, "thumbHeight"), thumb_align: V(this.b, "thumbAlign") } };
|
||||
Z.prototype.s = function (a, b) { X.prototype.s.call(this, a, b ? b.info : void 0) };
|
||||
function dc(a) { if ("iframe" != a.tagName.toLowerCase()) { var b = U(a, "videoid"); if (b) { b = { videoId: b, events: {}, width: U(a, "width"), height: U(a, "height"), thumbWidth: U(a, "thumb-width"), thumbHeight: U(a, "thumb-height"), thumbAlign: U(a, "thumb-align") }; var c = U(a, "onclick"); c && (b.events.onClick = c); new Z(a, b) } } }
|
||||
; A("YT.PlayerState.UNSTARTED", -1); A("YT.PlayerState.ENDED", 0); A("YT.PlayerState.PLAYING", 1); A("YT.PlayerState.PAUSED", 2); A("YT.PlayerState.BUFFERING", 3); A("YT.PlayerState.CUED", 5); A("YT.get", function (a) { return T[a] });
|
||||
A("YT.scan", Mb); A("YT.subscribe", function (a, b, c) { Q.subscribe(a, b, c); Lb[a] = !0; for (var d in T) Wb(T[d], a) });
|
||||
A("YT.unsubscribe", function (a, b, c) { tb(a, b, c) });
|
||||
A("YT.Player", Y); A("YT.Thumbnail", Z); X.prototype.destroy = X.prototype.destroy; X.prototype.setSize = X.prototype.setSize; X.prototype.getIframe = X.prototype.L; X.prototype.addEventListener = X.prototype.addEventListener; Y.prototype.getVideoEmbedCode = Y.prototype.getVideoEmbedCode; Y.prototype.getOptions = Y.prototype.getOptions; Y.prototype.getOption = Y.prototype.getOption; l.push(function (a) { a = Nb("player", a); B(a, cc) });
|
||||
l.push(function () { var a = Nb("thumbnail"); B(a, dc) });
|
||||
"undefined" != typeof YTConfig && YTConfig.parsetags && "onload" != YTConfig.parsetags || Mb(); var ec = v("onYTReady"); ec && ec(); var fc = v("onYouTubeIframeAPIReady"); fc && fc(); var gc = v("onYouTubePlayerAPIReady"); gc && gc();
|
||||
}).call(this);
|
512
background.js
|
@ -1,25 +1,47 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const invidiousDefault = 'https://invidio.us';
|
||||
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',
|
||||
"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 invidiousInstances = [
|
||||
"https://invidious.snopyta.org",
|
||||
"https://yewtu.be",
|
||||
"https://invidious.13ad.de",
|
||||
"https://invidious.xyz",
|
||||
"https://invidious.site",
|
||||
"https://invidiou.site",
|
||||
"https://invidious.fdn.fr",
|
||||
"https://invidious.toot.koeln",
|
||||
];
|
||||
const nitterDefault = 'https://nitter.net';
|
||||
const twitterDomains = [
|
||||
'twitter.com',
|
||||
'www.twitter.com',
|
||||
'mobile.twitter.com',
|
||||
'pbs.twimg.com',
|
||||
'video.twimg.com',
|
||||
"twitter.com",
|
||||
"www.twitter.com",
|
||||
"mobile.twitter.com",
|
||||
"pbs.twimg.com",
|
||||
"video.twimg.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.tedomum.net",
|
||||
"https://nitter.cattube.org",
|
||||
"https://nitter.fdn.fr",
|
||||
"https://nitter.1d4.us",
|
||||
"https://nitter.kavin.rocks",
|
||||
];
|
||||
const bibliogramDefault = 'https://bibliogram.art';
|
||||
const instagramDomains = [
|
||||
"instagram.com",
|
||||
"www.instagram.com",
|
||||
|
@ -27,50 +49,57 @@ const instagramDomains = [
|
|||
"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'
|
||||
"about",
|
||||
"explore",
|
||||
"support",
|
||||
"press",
|
||||
"api",
|
||||
"privacy",
|
||||
"safety",
|
||||
"admin",
|
||||
"graphql",
|
||||
"accounts",
|
||||
"help",
|
||||
"terms",
|
||||
"contact",
|
||||
"blog",
|
||||
"igtv",
|
||||
"u",
|
||||
"p",
|
||||
"fragment",
|
||||
"imageproxy",
|
||||
"videoproxy",
|
||||
".well-known",
|
||||
];
|
||||
const bibliogramBypassPaths = /\/(accounts\/|embeds?.js)/;
|
||||
const bibliogramInstances = [
|
||||
'https://bibliogram.art',
|
||||
'https://bibliogram.snopyta.org'
|
||||
"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.stemy.me ",
|
||||
"https://bibliogram.hamster.dance",
|
||||
"https://bibliogram.ggc-project.de",
|
||||
];
|
||||
const osmDefault = 'https://openstreetmap.org';
|
||||
const googleMapsRegex = /https?:\/\/(((www|maps)\.)?(google).*(\/maps)|maps\.(google).*)/;
|
||||
const osmDefault = "https://openstreetmap.org";
|
||||
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.
|
||||
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'
|
||||
}
|
||||
none: "S",
|
||||
transit: "T",
|
||||
traffic: "S", // not implemented on OSM, default to standard.
|
||||
bicycling: "C",
|
||||
};
|
||||
|
||||
let disableNitter;
|
||||
let disableInvidious;
|
||||
|
@ -84,85 +113,119 @@ let alwaysProxy;
|
|||
let onlyEmbeddedVideo;
|
||||
let videoQuality;
|
||||
let invidiousDarkMode;
|
||||
let whitelist;
|
||||
let invidiousVolume;
|
||||
let invidiousPlayerStyle;
|
||||
let invidiousSubtitles;
|
||||
let invidiousAutoplay;
|
||||
let exceptions;
|
||||
|
||||
window.browser = window.browser || window.chrome;
|
||||
|
||||
browser.storage.sync.get(
|
||||
[
|
||||
'nitterInstance',
|
||||
'invidiousInstance',
|
||||
'bibliogramInstance',
|
||||
'osmInstance',
|
||||
'disableNitter',
|
||||
'disableInvidious',
|
||||
'disableBibliogram',
|
||||
'disableOsm',
|
||||
'alwaysProxy',
|
||||
'onlyEmbeddedVideo',
|
||||
'videoQuality',
|
||||
'invidiousDarkMode',
|
||||
'whitelist'
|
||||
"nitterInstance",
|
||||
"invidiousInstance",
|
||||
"bibliogramInstance",
|
||||
"osmInstance",
|
||||
"disableNitter",
|
||||
"disableInvidious",
|
||||
"disableBibliogram",
|
||||
"disableOsm",
|
||||
"alwaysProxy",
|
||||
"onlyEmbeddedVideo",
|
||||
"videoQuality",
|
||||
"invidiousDarkMode",
|
||||
"invidiousVolume",
|
||||
"invidiousPlayerStyle",
|
||||
"invidiousSubtitles",
|
||||
"invidiousAutoplay",
|
||||
"exceptions",
|
||||
],
|
||||
result => {
|
||||
(result) => {
|
||||
disableNitter = result.disableNitter;
|
||||
disableInvidious = result.disableInvidious;
|
||||
disableBibliogram = result.disableBibliogram;
|
||||
disableOsm = result.disableOsm;
|
||||
nitterInstance = result.nitterInstance || nitterDefault;
|
||||
invidiousInstance = result.invidiousInstance || invidiousDefault;
|
||||
bibliogramInstance = result.bibliogramInstance || bibliogramDefault;
|
||||
nitterInstance = result.nitterInstance;
|
||||
invidiousInstance = result.invidiousInstance;
|
||||
bibliogramInstance = result.bibliogramInstance;
|
||||
osmInstance = result.osmInstance || osmDefault;
|
||||
alwaysProxy = result.alwaysProxy;
|
||||
onlyEmbeddedVideo = result.onlyEmbeddedVideo;
|
||||
videoQuality = result.videoQuality;
|
||||
invidiousDarkMode = result.invidiousDarkMode;
|
||||
whitelist = result.whitelist ? result.whitelist.map(e => new RegExp(e)) : [];
|
||||
exceptions = result.exceptions
|
||||
? result.exceptions.map((e) => {
|
||||
return new RegExp(e);
|
||||
})
|
||||
: [];
|
||||
invidiousVolume = result.invidiousVolume;
|
||||
invidiousPlayerStyle = result.invidiousPlayerStyle;
|
||||
invidiousSubtitles = result.invidiousSubtitles || "";
|
||||
invidiousAutoplay = result.invidiousAutoplay;
|
||||
}
|
||||
);
|
||||
|
||||
browser.storage.onChanged.addListener(changes => {
|
||||
if ('nitterInstance' in changes) {
|
||||
nitterInstance = changes.nitterInstance.newValue || nitterDefault;
|
||||
browser.storage.onChanged.addListener((changes) => {
|
||||
if ("nitterInstance" in changes) {
|
||||
nitterInstance = changes.nitterInstance.newValue;
|
||||
}
|
||||
if ('invidiousInstance' in changes) {
|
||||
invidiousInstance = changes.invidiousInstance.newValue || invidiousDefault;
|
||||
if ("invidiousInstance" in changes) {
|
||||
invidiousInstance = changes.invidiousInstance.newValue;
|
||||
}
|
||||
if ('bibliogramInstance' in changes) {
|
||||
bibliogramInstance = changes.bibliogramInstance.newValue || bibliogramDefault;
|
||||
if ("bibliogramInstance" in changes) {
|
||||
bibliogramInstance = changes.bibliogramInstance.newValue;
|
||||
}
|
||||
if ('osmInstance' in changes) {
|
||||
if ("osmInstance" in changes) {
|
||||
osmInstance = changes.osmInstance.newValue || osmDefault;
|
||||
}
|
||||
if ('disableNitter' in changes) {
|
||||
if ("disableNitter" in changes) {
|
||||
disableNitter = changes.disableNitter.newValue;
|
||||
}
|
||||
if ('disableInvidious' in changes) {
|
||||
if ("disableInvidious" in changes) {
|
||||
disableInvidious = changes.disableInvidious.newValue;
|
||||
}
|
||||
if ('disableBibliogram' in changes) {
|
||||
if ("disableBibliogram" in changes) {
|
||||
disableBibliogram = changes.disableBibliogram.newValue;
|
||||
}
|
||||
if ('disableOsm' in changes) {
|
||||
if ("disableOsm" in changes) {
|
||||
disableOsm = changes.disableOsm.newValue;
|
||||
}
|
||||
if ('alwaysProxy' in changes) {
|
||||
if ("alwaysProxy" in changes) {
|
||||
alwaysProxy = changes.alwaysProxy.newValue;
|
||||
}
|
||||
if ('onlyEmbeddedVideo' in changes) {
|
||||
if ("onlyEmbeddedVideo" in changes) {
|
||||
onlyEmbeddedVideo = changes.onlyEmbeddedVideo.newValue;
|
||||
}
|
||||
if ('videoQuality' in changes) {
|
||||
if ("videoQuality" in changes) {
|
||||
videoQuality = changes.videoQuality.newValue;
|
||||
}
|
||||
if ('invidiousDarkMode' in changes) {
|
||||
if ("invidiousDarkMode" in changes) {
|
||||
invidiousDarkMode = changes.invidiousDarkMode.newValue;
|
||||
}
|
||||
if ('whitelist' in changes) {
|
||||
whitelist = changes.whitelist.newValue.map(e => new RegExp(e));
|
||||
if ("invidiousVolume" in changes) {
|
||||
invidiousVolume = changes.invidiousVolume.newValue;
|
||||
}
|
||||
if ("invidiousPlayerStyle" in changes) {
|
||||
invidiousPlayerStyle = changes.invidiousPlayerStyle.newValue;
|
||||
}
|
||||
if ("invidiousSubtitles" in changes) {
|
||||
invidiousSubtitles = changes.invidiousSubtitles.newValue;
|
||||
}
|
||||
if ("invidiousAutoplay" in changes) {
|
||||
invidiousAutoplay = changes.invidiousAutoplay.newValue;
|
||||
}
|
||||
if ("exceptions" in changes) {
|
||||
exceptions = changes.exceptions.newValue.map((e) => {
|
||||
return new RegExp(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function getRandomInstance(instanceList) {
|
||||
return instanceList[~~(instanceList.length * Math.random())];
|
||||
}
|
||||
|
||||
function addressToLatLng(address, callback) {
|
||||
const xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.onreadystatechange = () => {
|
||||
|
@ -175,120 +238,181 @@ function addressToLatLng(address, callback) {
|
|||
`${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}`
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
console.info("Error: Status is " + xmlhttp.status);
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlhttp.open(
|
||||
'GET',
|
||||
"GET",
|
||||
`https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`,
|
||||
false
|
||||
);
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
function isWhitelisted(initiator) {
|
||||
return initiator && whitelist.some(regex => (regex.test(initiator.href)));
|
||||
function isException(url, initiator) {
|
||||
return (
|
||||
exceptions.some((regex) => regex.test(url.href)) ||
|
||||
(initiator && exceptions.some((regex) => regex.test(initiator.href)))
|
||||
);
|
||||
}
|
||||
|
||||
function isFirefox() {
|
||||
return typeof InstallTrigger !== "undefined";
|
||||
}
|
||||
|
||||
function redirectYouTube(url, initiator, type) {
|
||||
if (disableInvidious || isWhitelisted(initiator)) {
|
||||
if (disableInvidious || isException(url, initiator)) {
|
||||
return null;
|
||||
}
|
||||
if (initiator && (initiator.origin === invidiousInstance || youtubeDomains.includes(initiator.host))) {
|
||||
if (
|
||||
initiator &&
|
||||
(initiator.origin === invidiousInstance ||
|
||||
invidiousInstances.includes(initiator.origin) ||
|
||||
youtubeDomains.includes(initiator.host))
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
if (url.pathname.match(/iframe_api/)) {
|
||||
// Redirect requests for YouTube Player API to local files instead
|
||||
return browser.runtime.getURL('assets/iframe_api.js');
|
||||
} else if (url.pathname.match(/www-widgetapi/)) {
|
||||
// Redirect requests for YouTube Player API to local files instead
|
||||
return browser.runtime.getURL('assets/www-widgetapi.js');
|
||||
} else {
|
||||
// Proxy video through the server if enabled by user
|
||||
if (alwaysProxy) {
|
||||
url.searchParams.append('local', true);
|
||||
}
|
||||
if (videoQuality) {
|
||||
url.searchParams.append('quality', videoQuality);
|
||||
}
|
||||
if (onlyEmbeddedVideo && type !== 'sub_frame') {
|
||||
return null;
|
||||
}
|
||||
if (invidiousDarkMode) {
|
||||
url.searchParams.append('dark_mode', invidiousDarkMode);
|
||||
}
|
||||
return `${invidiousInstance}${url.pathname}${url.search}`;
|
||||
if (url.pathname.match(/iframe_api/) || url.pathname.match(/www-widgetapi/)) {
|
||||
// Don't redirect YouTube Player API.
|
||||
return null;
|
||||
}
|
||||
if (url.host.split(".")[0] === "studio") {
|
||||
// Avoid redirecting `studio.youtube.com`
|
||||
return null;
|
||||
}
|
||||
if (onlyEmbeddedVideo && type !== "sub_frame") {
|
||||
return null;
|
||||
}
|
||||
// Apply settings
|
||||
if (alwaysProxy) {
|
||||
url.searchParams.append("local", true);
|
||||
}
|
||||
if (videoQuality) {
|
||||
url.searchParams.append("quality", videoQuality);
|
||||
}
|
||||
if (invidiousDarkMode) {
|
||||
url.searchParams.append("dark_mode", invidiousDarkMode);
|
||||
}
|
||||
if (invidiousVolume) {
|
||||
url.searchParams.append("volume", invidiousVolume);
|
||||
}
|
||||
if (invidiousPlayerStyle) {
|
||||
url.searchParams.append("player_style", invidiousPlayerStyle);
|
||||
}
|
||||
if (invidiousSubtitles) {
|
||||
url.searchParams.append("subtitles", invidiousSubtitles);
|
||||
}
|
||||
url.searchParams.append("autoplay", invidiousAutoplay ? 1 : 0);
|
||||
|
||||
return `${invidiousInstance || getRandomInstance(invidiousInstances)}${
|
||||
url.pathname
|
||||
}${url.search}`;
|
||||
}
|
||||
|
||||
function redirectTwitter(url, initiator) {
|
||||
if (disableNitter || isWhitelisted(initiator)) {
|
||||
if (disableNitter || isException(url, initiator)) {
|
||||
return null;
|
||||
}
|
||||
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 if (url.pathname.includes('tweets')) {
|
||||
return `${nitterInstance}${url.pathname.replace('/tweets', '')}${url.search}`;
|
||||
if (url.pathname.includes("/home")) {
|
||||
return null;
|
||||
}
|
||||
if (
|
||||
isFirefox() &&
|
||||
initiator &&
|
||||
(initiator.origin === nitterInstance ||
|
||||
nitterInstances.includes(initiator.origin) ||
|
||||
twitterDomains.includes(initiator.host))
|
||||
) {
|
||||
browser.storage.sync.set({
|
||||
redirectBypassFlag: true,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
if (url.host.split(".")[0] === "pbs") {
|
||||
return `${
|
||||
nitterInstance || getRandomInstance(nitterInstances)
|
||||
}/pic/${encodeURIComponent(url.href)}`;
|
||||
} else if (url.host.split(".")[0] === "video") {
|
||||
return `${
|
||||
nitterInstance || getRandomInstance(nitterInstances)
|
||||
}/gif/${encodeURIComponent(url.href)}`;
|
||||
} else if (url.pathname.includes("tweets")) {
|
||||
return `${
|
||||
nitterInstance || getRandomInstance(nitterInstances)
|
||||
}${url.pathname.replace("/tweets", "")}${url.search}`;
|
||||
} else {
|
||||
return `${nitterInstance}${url.pathname}${url.search}`;
|
||||
return `${nitterInstance || getRandomInstance(nitterInstances)}${
|
||||
url.pathname
|
||||
}${url.search}`;
|
||||
}
|
||||
}
|
||||
|
||||
function redirectInstagram(url, initiator, type) {
|
||||
if (disableBibliogram || isWhitelisted(initiator)) {
|
||||
if (disableBibliogram || isException(url, initiator)) {
|
||||
return null;
|
||||
}
|
||||
// Do not redirect Bibliogram view on Instagram links
|
||||
if (initiator && (initiator.origin === bibliogramInstance || instagramDomains.includes(initiator.host))) {
|
||||
if (
|
||||
initiator &&
|
||||
(initiator.origin === bibliogramInstance ||
|
||||
bibliogramInstances.includes(initiator.origin) ||
|
||||
instagramDomains.includes(initiator.host))
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
// Do not redirect /accounts, /embeds.js, or anything other than main_frame
|
||||
if (type !== 'main_frame' || url.pathname.match(bibliogramBypassPaths)) {
|
||||
if (type !== "main_frame" || url.pathname.match(bibliogramBypassPaths)) {
|
||||
return null;
|
||||
}
|
||||
if (url.pathname === '/' || instagramReservedPaths.includes(url.pathname.split('/')[1])) {
|
||||
return `${bibliogramInstance}${url.pathname}${url.search}`;
|
||||
if (
|
||||
url.pathname === "/" ||
|
||||
instagramReservedPaths.includes(url.pathname.split("/")[1])
|
||||
) {
|
||||
return `${bibliogramInstance || getRandomInstance(bibliogramInstances)}${
|
||||
url.pathname
|
||||
}${url.search}`;
|
||||
} else {
|
||||
// Likely a user profile, redirect to '/u/...'
|
||||
return `${bibliogramInstance}/u${url.pathname}${url.search}`;
|
||||
return `${bibliogramInstance || getRandomInstance(bibliogramInstances)}/u${
|
||||
url.pathname
|
||||
}${url.search}`;
|
||||
}
|
||||
}
|
||||
|
||||
function redirectGoogleMaps(url, initiator) {
|
||||
if (disableOsm || isWhitelisted(initiator)) {
|
||||
if (disableOsm || isException(url, initiator)) {
|
||||
return null;
|
||||
}
|
||||
let redirect;
|
||||
let mapCentre = '';
|
||||
let params = '';
|
||||
let mapCentre = "";
|
||||
let params = "";
|
||||
// Set map centre if present
|
||||
if (url.pathname.match(mapCentreRegex)) {
|
||||
const [, lat, lon, zoom] = url.pathname.match(mapCentreRegex);
|
||||
mapCentre = `#map=${zoom}/${lat}/${lon}`;
|
||||
} else if (url.search.includes('center=')) {
|
||||
const [lat, lon] = url.searchParams.get('center').split(',');
|
||||
mapCentre = `#map=${url.searchParams.get('zoom') || '17'}/${lat}/${lon}`;
|
||||
} else if (url.search.includes("center=")) {
|
||||
const [lat, lon] = url.searchParams.get("center").split(",");
|
||||
mapCentre = `#map=${url.searchParams.get("zoom") || "17"}/${lat}/${lon}`;
|
||||
// Set default zoom if mapCentre not present
|
||||
} else {
|
||||
params = '&zoom=17';
|
||||
params = "&zoom=17";
|
||||
}
|
||||
// Set map layer
|
||||
params = `${params}&layers=${layers[url.searchParams.get('layer')] || layers['none']}`;
|
||||
params = `${params}&layers=${
|
||||
layers[url.searchParams.get("layer")] || layers["none"]
|
||||
}`;
|
||||
// Handle Google Maps Embed API
|
||||
if (url.pathname.includes('/embed')) {
|
||||
let query = '';
|
||||
if (url.searchParams.has('q')) {
|
||||
query = url.searchParams.get('q');
|
||||
} else if (url.searchParams.has('query')) {
|
||||
query = url.searchParams.has('query');
|
||||
} else if (url.searchParams.has('pb')) {
|
||||
if (url.pathname.includes("/embed")) {
|
||||
let query = "";
|
||||
if (url.searchParams.has("q")) {
|
||||
query = url.searchParams.get("q");
|
||||
} else if (url.searchParams.has("query")) {
|
||||
query = url.searchParams.has("query");
|
||||
} else if (url.searchParams.has("pb")) {
|
||||
try {
|
||||
query = url.searchParams.get('pb').split(/!2s(.*?)!/)[1];
|
||||
query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1];
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
// Unable to find map marker in URL.
|
||||
|
@ -301,92 +425,118 @@ function redirectGoogleMaps(url, initiator) {
|
|||
});
|
||||
redirect = `${osmInstance}/export/embed.html?bbox=${bbox}&layer=mapnik&marker=${marker}`;
|
||||
// Handle Google Maps Directions
|
||||
} else if (url.pathname.includes('/dir')) {
|
||||
const travelMode = travelModes[url.searchParams.get('travelmode')] || travelModes['driving'];
|
||||
} else if (url.pathname.includes("/dir")) {
|
||||
const travelMode =
|
||||
travelModes[url.searchParams.get("travelmode")] || travelModes["driving"];
|
||||
let origin;
|
||||
addressToLatLng(url.searchParams.get('origin'), coords => {
|
||||
addressToLatLng(url.searchParams.get("origin"), (coords) => {
|
||||
origin = coords;
|
||||
});
|
||||
let destination;
|
||||
addressToLatLng(url.searchParams.get('destination'), coords => {
|
||||
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 (url.pathname.includes('data=') && url.pathname.match(dataLatLngRegex)) {
|
||||
} else if (
|
||||
url.pathname.includes("data=") &&
|
||||
url.pathname.match(dataLatLngRegex)
|
||||
) {
|
||||
const [mlat, mlon] = url.pathname.match(dataLatLngRegex);
|
||||
redirect = `${osmInstance}/?mlat=${mlat.replace('!3d', '')}&mlon=${mlon.replace('!4d', '')}${mapCentre}${params}`;
|
||||
redirect = `${osmInstance}/?mlat=${mlat.replace(
|
||||
"!3d",
|
||||
""
|
||||
)}&mlon=${mlon.replace("!4d", "")}${mapCentre}${params}`;
|
||||
// Get marker from ll param
|
||||
} else if (url.searchParams.has('ll')) {
|
||||
const [mlat, mlon] = url.searchParams.get('ll').split(',');
|
||||
} else if (url.searchParams.has("ll")) {
|
||||
const [mlat, mlon] = url.searchParams.get("ll").split(",");
|
||||
redirect = `${osmInstance}/?mlat=${mlat}&mlon=${mlon}${mapCentre}${params}`;
|
||||
// Get marker from viewpoint param.
|
||||
} else if (url.searchParams.has('viewpoint')) {
|
||||
const [mlat, mlon] = url.searchParams.get('viewpoint').split(',');
|
||||
} else if (url.searchParams.has("viewpoint")) {
|
||||
const [mlat, mlon] = url.searchParams.get("viewpoint").split(",");
|
||||
redirect = `${osmInstance}/?mlat=${mlat}&mlon=${mlon}${mapCentre}${params}`;
|
||||
// Use query as search if present.
|
||||
} else {
|
||||
let query;
|
||||
if (url.searchParams.has('q')) {
|
||||
query = url.searchParams.get('q');
|
||||
} else if (url.searchParams.has('query')) {
|
||||
query = url.searchParams.get('query');
|
||||
if (url.searchParams.has("q")) {
|
||||
query = url.searchParams.get("q");
|
||||
} else if (url.searchParams.has("query")) {
|
||||
query = url.searchParams.get("query");
|
||||
} else if (url.pathname.match(placeRegex)) {
|
||||
query = url.pathname.match(placeRegex)[1];
|
||||
}
|
||||
redirect = `${osmInstance}/${query ? 'search?query=' + query : ''}${mapCentre || '#'}${params}`;
|
||||
redirect = `${osmInstance}/${query ? "search?query=" + query : ""}${
|
||||
mapCentre || "#"
|
||||
}${params}`;
|
||||
}
|
||||
|
||||
return redirect;
|
||||
}
|
||||
|
||||
browser.webRequest.onBeforeRequest.addListener(
|
||||
details => {
|
||||
(details) => {
|
||||
const url = new URL(details.url);
|
||||
let initiator;
|
||||
if (details.initiator) {
|
||||
initiator = new URL(details.initiator);
|
||||
} else if (details.originUrl) {
|
||||
if (details.originUrl) {
|
||||
initiator = new URL(details.originUrl);
|
||||
} else if (details.initiator) {
|
||||
initiator = new URL(details.initiator);
|
||||
}
|
||||
let redirect;
|
||||
if (youtubeDomains.includes(url.host)) {
|
||||
redirect = {
|
||||
redirectUrl: redirectYouTube(url, initiator, details.type)
|
||||
redirectUrl: redirectYouTube(url, initiator, details.type),
|
||||
};
|
||||
} else if (twitterDomains.includes(url.host)) {
|
||||
redirect = {
|
||||
redirectUrl: redirectTwitter(url, initiator)
|
||||
redirectUrl: redirectTwitter(url, initiator),
|
||||
};
|
||||
} else if (instagramDomains.includes(url.host)) {
|
||||
redirect = {
|
||||
redirectUrl: redirectInstagram(url, initiator, details.type)
|
||||
redirectUrl: redirectInstagram(url, initiator, details.type),
|
||||
};
|
||||
} else if (url.href.match(googleMapsRegex)) {
|
||||
redirect = {
|
||||
redirectUrl: redirectGoogleMaps(url, initiator)
|
||||
redirectUrl: redirectGoogleMaps(url, initiator),
|
||||
};
|
||||
}
|
||||
if (redirect && redirect.redirectUrl) {
|
||||
console.info(
|
||||
'Redirecting', `"${url.href}"`, '=>', `"${redirect.redirectUrl}"`
|
||||
"Redirecting",
|
||||
`"${url.href}"`,
|
||||
"=>",
|
||||
`"${redirect.redirectUrl}"`
|
||||
);
|
||||
console.info('Details', details);
|
||||
console.info("Details", details);
|
||||
}
|
||||
return redirect;
|
||||
},
|
||||
{
|
||||
urls: ["<all_urls>"]
|
||||
urls: ["<all_urls>"],
|
||||
},
|
||||
['blocking']
|
||||
["blocking"]
|
||||
);
|
||||
|
||||
browser.runtime.onInstalled.addListener(
|
||||
details => {
|
||||
if (details.reason === 'install') {
|
||||
browser.storage.sync.set({
|
||||
bibliogramInstance: bibliogramInstances[~~(bibliogramInstances.length * Math.random())]
|
||||
});
|
||||
}
|
||||
browser.runtime.onInstalled.addListener((details) => {
|
||||
if (details.reason === "update") {
|
||||
browser.storage.sync.get(
|
||||
["whitelist", "exceptions", "invidiousInstance"],
|
||||
(result) => {
|
||||
if (result.whitelist) {
|
||||
let whitelist = result.whitelist.map((e) =>
|
||||
e.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")
|
||||
);
|
||||
browser.storage.sync.set({
|
||||
exceptions: result.exceptions.concat(whitelist),
|
||||
whitelist: null,
|
||||
});
|
||||
}
|
||||
if (result.invidiousInstance === "https://invidio.us") {
|
||||
browser.storage.sync.set({
|
||||
invidiousInstance: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
Before Width: | Height: | Size: 243 KiB |
Before Width: | Height: | Size: 569 KiB |
Before Width: | Height: | Size: 146 KiB |
Before Width: | Height: | Size: 814 KiB |
Before Width: | Height: | Size: 145 KiB |
Before Width: | Height: | Size: 262 KiB |
Before Width: | Height: | Size: 703 KiB |
Before Width: | Height: | Size: 185 KiB |
Before Width: | Height: | Size: 658 KiB |
Before Width: | Height: | Size: 199 KiB |
|
@ -1,34 +1,28 @@
|
|||
{
|
||||
"name": "Privacy Redirect",
|
||||
"description": "Redirects Twitter, YouTube, Instagram & Google Maps requests to privacy friendly alternatives.",
|
||||
"version": "1.1.29",
|
||||
"name": "__MSG_extensionName__",
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"version": "1.1.41",
|
||||
"manifest_version": 2,
|
||||
"background": {
|
||||
"scripts": [
|
||||
"background.js"
|
||||
],
|
||||
"scripts": ["background.js"],
|
||||
"persistent": true
|
||||
},
|
||||
"default_locale": "en",
|
||||
"icons": {
|
||||
"16": "images/icon16.png",
|
||||
"32": "images/icon32.png",
|
||||
"48": "images/icon48.png",
|
||||
"128": "images/icon128.png"
|
||||
"16": "assets/images/icon16.png",
|
||||
"32": "assets/images/icon32.png",
|
||||
"48": "assets/images/icon48.png",
|
||||
"128": "assets/images/icon128.png"
|
||||
},
|
||||
"permissions": [
|
||||
"storage",
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"<all_urls>"
|
||||
],
|
||||
"permissions": ["storage", "webRequest", "webRequestBlocking", "<all_urls>"],
|
||||
"browser_action": {
|
||||
"default_title": "Privacy Redirect",
|
||||
"default_popup": "pages/popup/popup.html",
|
||||
"default_icon": {
|
||||
"16": "images/icon16.png",
|
||||
"32": "images/icon32.png",
|
||||
"48": "images/icon48.png",
|
||||
"128": "images/icon128.png"
|
||||
"16": "assets/images/icon16.png",
|
||||
"32": "assets/images/icon32.png",
|
||||
"48": "assets/images/icon48.png",
|
||||
"128": "assets/images/icon128.png"
|
||||
}
|
||||
},
|
||||
"content_scripts": [
|
||||
|
@ -40,32 +34,32 @@
|
|||
"*://pbs.twimg.com/*",
|
||||
"*://video.twimg.com/*"
|
||||
],
|
||||
"js": [
|
||||
"assets/remove-twitter-sw.js"
|
||||
],
|
||||
"js": ["assets/javascript/remove-twitter-sw.js"],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"*://invidio.us/*",
|
||||
"*://invidio.us/*",
|
||||
"*://invidious.snopyta.org/*",
|
||||
"*://invidiou.sh/*",
|
||||
"*://yewtu.be/*",
|
||||
"*://yt.maisputain.ovh/*",
|
||||
"*://invidious.toot.koeln/*",
|
||||
"*://invidious.xyz/*",
|
||||
"*://invidious.site/*",
|
||||
"*://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/*",
|
||||
"*://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion/*",
|
||||
"*://qklhadlycap4cnod.onion/*",
|
||||
"*://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion/*",
|
||||
"*://mfqczy4mysscub2s.onio/*n"
|
||||
],
|
||||
"js": [
|
||||
"assets/persist-invidious-prefs.js"
|
||||
"*://mfqczy4mysscub2s.onion/*",
|
||||
"*://4l2dgddgsrkf2ous66i6seeyi6etzfgrue332grh2n7madpwopotugyd.onion/*"
|
||||
],
|
||||
"js": ["assets/javascript/persist-invidious-prefs.js"],
|
||||
"run_at": "document_start"
|
||||
}
|
||||
],
|
||||
|
@ -73,13 +67,9 @@
|
|||
"page": "pages/options/options.html",
|
||||
"open_in_tab": false
|
||||
},
|
||||
"web_accessible_resources": [
|
||||
"assets/iframe_api.js",
|
||||
"assets/www-widgetapi.js"
|
||||
],
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "{b7f9d2cd-d772-4302-8c3f-eb941af36f76}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,183 +1,448 @@
|
|||
<!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>
|
||||
|
||||
<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>
|
||||
|
||||
<body>
|
||||
<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">
|
||||
<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_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 class="tab">
|
||||
<button class="tablinks" id="general-tab">General</button>
|
||||
<button class="tablinks" id="advanced-tab">Advanced</button>
|
||||
<button class="tablinks" id="whitelist-tab">Whitelist</button>
|
||||
</div>
|
||||
<div id="advanced" class="tabcontent">
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<div id="general" class="tabcontent">
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Toggle Nitter redirects">
|
||||
<h1>Nitter Redirects</h1>
|
||||
<input aria-hidden="true" id="disable-nitter" type="checkbox" checked>
|
||||
<label for="disable-nitter" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
<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>
|
||||
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Toggle Invidious redirects">
|
||||
<h1>Invidious Redirects</h1>
|
||||
<input aria-hidden="true" id="disable-invidious" type="checkbox" checked>
|
||||
<label for="disable-invidious" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Toggle Bibliogram redirects">
|
||||
<h1>Bibliogram Redirects</h1>
|
||||
<input aria-hidden="true" id="disable-bibliogram" type="checkbox" checked>
|
||||
<label for="disable-bibliogram" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Toggle OpenStreetMap redirects">
|
||||
<h1>OpenStreetMap Redirects</h1>
|
||||
<input aria-hidden="true" id="disable-osm" type="checkbox" checked>
|
||||
<label for="disable-osm" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<h1>Nitter Instance</h1>
|
||||
<input id="nitter-instance" list="nitter-instance-list" type="url" placeholder="https://nitter.net">
|
||||
<datalist id="nitter-instance-list">
|
||||
<option value="https://nitter.net">
|
||||
<option value="https://nitter.snopyta.org">
|
||||
<option value="https://nitter.42l.fr">
|
||||
<option value="https://nitter.nixnet.xyz">
|
||||
<option value="https://nitter.13ad.de">
|
||||
<option value="https://tw.openalgeria.org">
|
||||
<option value="https://nitter.pussthecat.org">
|
||||
<option value="https://nitter.mastodont.cat">
|
||||
<option value="https://nitter.dark.fail">
|
||||
<option value="https://nitter.tedomum.net">
|
||||
<option value="https://t.maisputain.ovh">
|
||||
<option value="http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion">
|
||||
<option value="http://nitter.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd.onion">
|
||||
<option value="http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion">
|
||||
</datalist>
|
||||
<h1>Invidious Instance</h1>
|
||||
<input id="invidious-instance" list="invidious-instances-list" type="url" placeholder="https://invidio.us">
|
||||
<datalist id="invidious-instances-list">
|
||||
<option value="https://invidio.us">
|
||||
<option value="https://invidious.snopyta.org">
|
||||
<option value="https://invidiou.sh">
|
||||
<option value="https://yewtu.be">
|
||||
<option value="https://yt.maisputain.ovh">
|
||||
<option value="https://invidious.toot.koeln">
|
||||
<option value="https://invidious.ggc-project.de">
|
||||
<option value="https://invidious.toot.koeln">
|
||||
<option value="http://kgg2m7yk5aybusll.onion">
|
||||
<option value="http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid.onion">
|
||||
<option value="http://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion">
|
||||
<option value="http://qklhadlycap4cnod.onion">
|
||||
<option value="http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion">
|
||||
<option value="http://mfqczy4mysscub2s.onion">
|
||||
</datalist>
|
||||
<h1>Bibliogram Instance</h1>
|
||||
<input id="bibliogram-instance" list="bibliogram-instance-list" type="url" placeholder="https://bibliogram.art">
|
||||
<datalist id="bibliogram-instance-list">
|
||||
<option value="https://bibliogram.art">
|
||||
<option value="https://bibliogram.snopyta.org">
|
||||
<option value="https://bibliogram.pussthecat.org">
|
||||
<option value="https://insta.maisputain.ovh">
|
||||
<option value="https://bibliogram.nixnet.services">
|
||||
</datalist>
|
||||
<h1>OpenStreetMap Instance</h1>
|
||||
<input id="osm-instance" list="osm-instance-list" type="url" placeholder="https://openstreetmap.org">
|
||||
<datalist id="osm-instance-list">
|
||||
<option value="https://openstreetmap.org">
|
||||
</datalist>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div id="advanced" class="tabcontent">
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Always proxy videos through Invidious">
|
||||
<h1>Always proxy videos through Invidious</h1>
|
||||
<input aria-hidden="true" id="always-proxy" type="checkbox" checked>
|
||||
<label for="always-proxy" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Only redirect embedded video to Invidious">
|
||||
<h1>Only redirect embedded video to Invidious</h1>
|
||||
<input aria-hidden="true" id="only-embed" type="checkbox" checked>
|
||||
<label for="only-embed" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<h1>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>
|
||||
</select>
|
||||
</section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Invidious dark mode aways on">
|
||||
<h1>Invidious dark mode always on</h1>
|
||||
<input aria-hidden="true" id="invidious-dark-mode" type="checkbox" checked>
|
||||
<label for="invidious-dark-mode" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Persist Invidious preferences">
|
||||
<h1>Persist Invidious preferences (as cookie)</h1>
|
||||
<input aria-hidden="true" id="persist-invidious-prefs" type="checkbox" checked>
|
||||
<label for="persist-invidious-prefs" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Proactively remove Twitter service worker">
|
||||
<h1>Proactively remove Twitter service worker</h1>
|
||||
<input aria-hidden="true" id="remove-twitter-sw" type="checkbox" checked>
|
||||
<label for="remove-twitter-sw" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div id="whitelist" class="tabcontent">
|
||||
<section class="options settings_block">
|
||||
<h1>Whitelisted Sites</h1>
|
||||
<div class="whitelist">
|
||||
<input id="new-whitelist-item" type="text" placeholder="URL (RegExp accepted)">
|
||||
<button id="add-to-whitelist">Add to Whitelist</button>
|
||||
</div>
|
||||
</section>
|
||||
<ul id="whitelist-items"></ul>
|
||||
</div>
|
||||
|
||||
<script src="./options.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<script src="./options.js"></script>
|
||||
<script src="../../assets/javascript/localise.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,130 +1,213 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
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 disableNitter = document.getElementById('disable-nitter');
|
||||
let disableInvidious = document.getElementById('disable-invidious');
|
||||
let disableBibliogram = document.getElementById('disable-bibliogram');
|
||||
let disableOsm = document.getElementById('disable-osm');
|
||||
let alwaysProxy = document.getElementById('always-proxy');
|
||||
let onlyEmbeddedVideo = document.getElementById('only-embed');
|
||||
let videoQuality = document.getElementById('video-quality');
|
||||
let removeTwitterSW = document.getElementById('remove-twitter-sw');
|
||||
let invidiousDarkMode = document.getElementById('invidious-dark-mode');
|
||||
let persistInvidiousPrefs = document.getElementById('persist-invidious-prefs');
|
||||
let whitelist;
|
||||
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://t.maisputain.ovh",
|
||||
"http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion",
|
||||
"http://nitter.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd.onion",
|
||||
];
|
||||
const invidiousInstances = [
|
||||
"https://invidious.snopyta.org",
|
||||
"https://yewtu.be",
|
||||
"https://invidious.ggc-project.de",
|
||||
"https://invidious.13ad.de",
|
||||
"https://invidious.xyz",
|
||||
"https://invidious.toot.koeln",
|
||||
"https://invidious.site",
|
||||
"https://invidiou.site",
|
||||
"https://invidious.fdn.fr",
|
||||
"https://watch.nettohikari.com",
|
||||
"https://yt.iswleuven.be",
|
||||
"https://yt.maisputain.ovh",
|
||||
"http://kgg2m7yk5aybusll.onion",
|
||||
"http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid.onion",
|
||||
"http://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion",
|
||||
"http://qklhadlycap4cnod.onion",
|
||||
"http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion",
|
||||
"http://mfqczy4mysscub2s.onion",
|
||||
"http://4l2dgddgsrkf2ous66i6seeyi6etzfgrue332grh2n7madpwopotugyd.onion",
|
||||
];
|
||||
const bibliogramInstances = [
|
||||
"https://bibliogram.art",
|
||||
"https://bibliogram.snopyta.org",
|
||||
"https://bibliogram.pussthecat.org",
|
||||
"https://bibliogram.nixnet.services",
|
||||
"https://bibliogram.hamster.dance",
|
||||
"https://insta.maisputain.ovh",
|
||||
"https://bibliogram.ggc-project.de",
|
||||
];
|
||||
const osmInstances = ["https://openstreetmap.org"];
|
||||
const autocompletes = [
|
||||
{ id: "nitter-instance", instances: nitterInstances },
|
||||
{ id: "invidious-instance", instances: invidiousInstances },
|
||||
{ id: "bibliogram-instance", instances: bibliogramInstances },
|
||||
{ id: "osm-instance", instances: osmInstances },
|
||||
];
|
||||
|
||||
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 disableNitter = document.getElementById("disable-nitter");
|
||||
let disableInvidious = document.getElementById("disable-invidious");
|
||||
let disableBibliogram = document.getElementById("disable-bibliogram");
|
||||
let disableOsm = document.getElementById("disable-osm");
|
||||
let alwaysProxy = document.getElementById("always-proxy");
|
||||
let onlyEmbeddedVideo = document.getElementById("only-embed");
|
||||
let videoQuality = document.getElementById("video-quality");
|
||||
let removeTwitterSW = document.getElementById("remove-twitter-sw");
|
||||
let invidiousDarkMode = document.getElementById("invidious-dark-mode");
|
||||
let persistInvidiousPrefs = document.getElementById("persist-invidious-prefs");
|
||||
let invidiousVolume = document.getElementById("invidious-volume");
|
||||
let invidiousPlayerStyle = document.getElementById("invidious-player-style");
|
||||
let invidiousSubtitles = document.getElementById("invidious-subtitles");
|
||||
let invidiousAutoplay = document.getElementById("invidious-autoplay");
|
||||
let theme = document.getElementById("theme");
|
||||
let exceptions;
|
||||
|
||||
window.browser = window.browser || window.chrome;
|
||||
|
||||
function prependWhitelistItem(item, index) {
|
||||
const li = document.createElement('li');
|
||||
function prependExceptionsItem(item, index) {
|
||||
const li = document.createElement("li");
|
||||
li.appendChild(document.createTextNode(item.toString()));
|
||||
const button = document.createElement('button');
|
||||
button.appendChild(document.createTextNode('X'));
|
||||
button.addEventListener('click', () => {
|
||||
li.remove();
|
||||
whitelist.splice(index, 1);
|
||||
browser.storage.sync.set({
|
||||
whitelist: whitelist
|
||||
});
|
||||
});
|
||||
const button = document.createElement("button");
|
||||
li.appendChild(button);
|
||||
document.getElementById('whitelist-items').prepend(li);
|
||||
document.getElementById("exceptions-items").prepend(li);
|
||||
const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 512 512'>
|
||||
<line x1='368' y1='368' x2='144' y2='144'
|
||||
style='fill:none;stroke:#FFF;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px' />
|
||||
<line x1='368' y1='144' x2='144' y2='368'
|
||||
style='fill:none;stroke:#FFF;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px' />
|
||||
</svg>`;
|
||||
button.innerHTML = svg;
|
||||
button.addEventListener("click", () => {
|
||||
exceptions.splice(index, 1);
|
||||
browser.storage.sync.set({
|
||||
exceptions: exceptions,
|
||||
});
|
||||
li.remove();
|
||||
});
|
||||
}
|
||||
|
||||
browser.storage.sync.get(
|
||||
[
|
||||
'nitterInstance',
|
||||
'invidiousInstance',
|
||||
'bibliogramInstance',
|
||||
'osmInstance',
|
||||
'disableNitter',
|
||||
'disableInvidious',
|
||||
'disableBibliogram',
|
||||
'disableOsm',
|
||||
'alwaysProxy',
|
||||
'onlyEmbeddedVideo',
|
||||
'videoQuality',
|
||||
'removeTwitterSW',
|
||||
'whitelist',
|
||||
'invidiousDarkMode',
|
||||
'persistInvidiousPrefs'
|
||||
"nitterInstance",
|
||||
"invidiousInstance",
|
||||
"bibliogramInstance",
|
||||
"osmInstance",
|
||||
"disableNitter",
|
||||
"disableInvidious",
|
||||
"disableBibliogram",
|
||||
"disableOsm",
|
||||
"alwaysProxy",
|
||||
"onlyEmbeddedVideo",
|
||||
"videoQuality",
|
||||
"removeTwitterSW",
|
||||
"invidiousDarkMode",
|
||||
"persistInvidiousPrefs",
|
||||
"invidiousVolume",
|
||||
"invidiousPlayerStyle",
|
||||
"invidiousSubtitles",
|
||||
"invidiousAutoplay",
|
||||
"exceptions",
|
||||
"theme",
|
||||
],
|
||||
result => {
|
||||
nitterInstance.value = result.nitterInstance || '';
|
||||
invidiousInstance.value = result.invidiousInstance || '';
|
||||
bibliogramInstance.value = result.bibliogramInstance || '';
|
||||
osmInstance.value = result.osmInstance || '';
|
||||
(result) => {
|
||||
theme.value = result.theme || "";
|
||||
if (result.theme) document.body.classList.add(result.theme);
|
||||
nitterInstance.value = result.nitterInstance || "";
|
||||
invidiousInstance.value = result.invidiousInstance || "";
|
||||
bibliogramInstance.value = result.bibliogramInstance || "";
|
||||
osmInstance.value = result.osmInstance || "";
|
||||
disableNitter.checked = !result.disableNitter;
|
||||
disableInvidious.checked = !result.disableInvidious;
|
||||
disableBibliogram.checked = !result.disableBibliogram;
|
||||
disableOsm.checked = !result.disableOsm;
|
||||
alwaysProxy.checked = result.alwaysProxy;
|
||||
onlyEmbeddedVideo.checked = result.onlyEmbeddedVideo;
|
||||
videoQuality.value = result.videoQuality || '';
|
||||
videoQuality.value = result.videoQuality || "";
|
||||
removeTwitterSW.checked = !result.removeTwitterSW;
|
||||
invidiousDarkMode.checked = result.invidiousDarkMode;
|
||||
persistInvidiousPrefs.checked = result.persistInvidiousPrefs;
|
||||
whitelist = result.whitelist || [];
|
||||
whitelist.forEach(prependWhitelistItem);
|
||||
exceptions = result.exceptions || [];
|
||||
exceptions.forEach(prependExceptionsItem);
|
||||
invidiousVolume.value = result.invidiousVolume;
|
||||
document.querySelector("#volume-value").textContent = result.invidiousVolume
|
||||
? `${result.invidiousVolume}%`
|
||||
: " - ";
|
||||
invidiousPlayerStyle.value = result.invidiousPlayerStyle || "";
|
||||
invidiousSubtitles.value = result.invidiousSubtitles || "";
|
||||
invidiousAutoplay.checked = result.invidiousAutoplay;
|
||||
}
|
||||
);
|
||||
|
||||
function openTab(tab, event) {
|
||||
let i, tabcontent, tablinks;
|
||||
tabcontent = document.getElementsByClassName('tabcontent');
|
||||
tabcontent = document.getElementsByClassName("tabcontent");
|
||||
for (i = 0; i < tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = 'none';
|
||||
tabcontent[i].style.display = "none";
|
||||
}
|
||||
tablinks = document.getElementsByClassName('tablinks');
|
||||
tablinks = document.getElementsByClassName("tablinks");
|
||||
for (i = 0; i < tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(' active', '');
|
||||
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
||||
}
|
||||
document.getElementById(tab).style.display = 'block';
|
||||
event.currentTarget.className += ' active';
|
||||
document.getElementById(tab).style.display = "block";
|
||||
event.currentTarget.className += " active";
|
||||
}
|
||||
|
||||
document.getElementById('general-tab').addEventListener(
|
||||
'click', openTab.bind(null, 'general')
|
||||
);
|
||||
document.getElementById('advanced-tab').addEventListener(
|
||||
'click', openTab.bind(null, 'advanced')
|
||||
);
|
||||
document.getElementById('whitelist-tab').addEventListener(
|
||||
'click', openTab.bind(null, 'whitelist')
|
||||
);
|
||||
document
|
||||
.getElementById("general-tab")
|
||||
.addEventListener("click", openTab.bind(null, "general"));
|
||||
document
|
||||
.getElementById("advanced-tab")
|
||||
.addEventListener("click", openTab.bind(null, "advanced"));
|
||||
document
|
||||
.getElementById("exceptions-tab")
|
||||
.addEventListener("click", openTab.bind(null, "exceptions"));
|
||||
|
||||
document.getElementById('general-tab').click();
|
||||
document.getElementById("general-tab").click();
|
||||
|
||||
function addToWhitelist() {
|
||||
const input = document.getElementById('new-whitelist-item');
|
||||
function addToExceptions() {
|
||||
const input = document.getElementById("new-exceptions-item");
|
||||
const type = document.querySelector('input[name="type"]:checked').value;
|
||||
if (input.value) {
|
||||
try {
|
||||
let value = input.value;
|
||||
new RegExp(input.value);
|
||||
const index = whitelist.push(input.value);
|
||||
prependWhitelistItem(input.value, index);
|
||||
if (type === "URL") {
|
||||
value = value.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
||||
}
|
||||
exceptions.push(value);
|
||||
browser.storage.sync.set({
|
||||
whitelist: whitelist
|
||||
exceptions: exceptions,
|
||||
});
|
||||
input.value = '';
|
||||
prependExceptionsItem(value, exceptions.indexOf(value));
|
||||
input.value = "";
|
||||
} catch (error) {
|
||||
input.setCustomValidity('Invalid RegExp');
|
||||
input.setCustomValidity("Invalid RegExp");
|
||||
}
|
||||
} else {
|
||||
input.setCustomValidity('Invalid RegExp');
|
||||
input.setCustomValidity("Invalid RegExp");
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('add-to-whitelist').addEventListener(
|
||||
'click', addToWhitelist
|
||||
);
|
||||
document
|
||||
.getElementById("add-to-exceptions")
|
||||
.addEventListener("click", addToExceptions);
|
||||
|
||||
function debounce(func, wait, immediate) {
|
||||
let timeout;
|
||||
return () => {
|
||||
let context = this, args = arguments;
|
||||
let context = this,
|
||||
args = arguments;
|
||||
let later = () => {
|
||||
timeout = null;
|
||||
if (!immediate) func.apply(context, args);
|
||||
|
@ -134,100 +217,239 @@ function debounce(func, wait, immediate) {
|
|||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(context, args);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function parseURL(urlString) {
|
||||
if (urlString) {
|
||||
try {
|
||||
const url = new URL(urlString);
|
||||
if (url.username && url.password) {
|
||||
return `${url.protocol}//${url.username}:${url.password}@${url.host}`
|
||||
return `${url.protocol}//${url.username}:${url.password}@${url.host}`;
|
||||
} else {
|
||||
return url.origin;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
let nitterInstanceChange = debounce(() => {
|
||||
if (nitterInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
nitterInstance: parseURL(nitterInstance.value)
|
||||
nitterInstance: parseURL(nitterInstance.value),
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
nitterInstance.addEventListener('input', nitterInstanceChange);
|
||||
nitterInstance.addEventListener("input", nitterInstanceChange);
|
||||
|
||||
let invidiousInstanceChange = debounce(() => {
|
||||
if (invidiousInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
invidiousInstance: parseURL(invidiousInstance.value)
|
||||
invidiousInstance: parseURL(invidiousInstance.value),
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
invidiousInstance.addEventListener('input', invidiousInstanceChange);
|
||||
invidiousInstance.addEventListener("input", invidiousInstanceChange);
|
||||
|
||||
let bibliogramInstanceChange = debounce(() => {
|
||||
if (bibliogramInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
bibliogramInstance: parseURL(bibliogramInstance.value)
|
||||
bibliogramInstance: parseURL(bibliogramInstance.value),
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
bibliogramInstance.addEventListener('input', bibliogramInstanceChange);
|
||||
bibliogramInstance.addEventListener("input", bibliogramInstanceChange);
|
||||
|
||||
let osmInstanceChange = debounce(() => {
|
||||
if (osmInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
osmInstance: parseURL(osmInstance.value)
|
||||
osmInstance: parseURL(osmInstance.value),
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
osmInstance.addEventListener('input', osmInstanceChange);
|
||||
osmInstance.addEventListener("input", osmInstanceChange);
|
||||
|
||||
disableNitter.addEventListener('change', event => {
|
||||
disableNitter.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ disableNitter: !event.target.checked });
|
||||
});
|
||||
|
||||
disableInvidious.addEventListener('change', event => {
|
||||
disableInvidious.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ disableInvidious: !event.target.checked });
|
||||
});
|
||||
|
||||
disableBibliogram.addEventListener('change', event => {
|
||||
disableBibliogram.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ disableBibliogram: !event.target.checked });
|
||||
});
|
||||
|
||||
disableOsm.addEventListener('change', event => {
|
||||
disableOsm.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ disableOsm: !event.target.checked });
|
||||
});
|
||||
|
||||
alwaysProxy.addEventListener('change', event => {
|
||||
alwaysProxy.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ alwaysProxy: event.target.checked });
|
||||
});
|
||||
|
||||
onlyEmbeddedVideo.addEventListener('change', event => {
|
||||
onlyEmbeddedVideo.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ onlyEmbeddedVideo: event.target.checked });
|
||||
});
|
||||
|
||||
videoQuality.addEventListener('change', event => {
|
||||
videoQuality.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({
|
||||
videoQuality: event.target.options[videoQuality.selectedIndex].value
|
||||
videoQuality: event.target.options[videoQuality.selectedIndex].value,
|
||||
});
|
||||
});
|
||||
|
||||
removeTwitterSW.addEventListener('change', event => {
|
||||
removeTwitterSW.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ removeTwitterSW: !event.target.checked });
|
||||
});
|
||||
|
||||
invidiousDarkMode.addEventListener('change', event => {
|
||||
invidiousDarkMode.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ invidiousDarkMode: event.target.checked });
|
||||
});
|
||||
|
||||
persistInvidiousPrefs.addEventListener('change', event => {
|
||||
persistInvidiousPrefs.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ persistInvidiousPrefs: event.target.checked });
|
||||
});
|
||||
|
||||
let invidiousVolumeChange = debounce(() => {
|
||||
document.querySelector(
|
||||
"#volume-value"
|
||||
).textContent = `${invidiousVolume.value}%`;
|
||||
browser.storage.sync.set({
|
||||
invidiousVolume: invidiousVolume.value,
|
||||
});
|
||||
}, 500);
|
||||
invidiousVolume.addEventListener("input", invidiousVolumeChange);
|
||||
|
||||
invidiousPlayerStyle.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({
|
||||
invidiousPlayerStyle:
|
||||
event.target.options[invidiousPlayerStyle.selectedIndex].value,
|
||||
});
|
||||
});
|
||||
|
||||
let invidiousSubtitlesChange = debounce(() => {
|
||||
if (invidiousInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
invidiousSubtitles: invidiousSubtitles.value,
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
invidiousSubtitles.addEventListener("input", invidiousSubtitlesChange);
|
||||
|
||||
invidiousAutoplay.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ invidiousAutoplay: event.target.checked });
|
||||
});
|
||||
|
||||
theme.addEventListener("change", (event) => {
|
||||
const value = event.target.options[theme.selectedIndex].value;
|
||||
switch (value) {
|
||||
case "dark-theme":
|
||||
document.body.classList.add("dark-theme");
|
||||
document.body.classList.remove("light-theme");
|
||||
break;
|
||||
case "light-theme":
|
||||
document.body.classList.add("light-theme");
|
||||
document.body.classList.remove("dark-theme");
|
||||
break;
|
||||
default:
|
||||
document.body.classList.remove("light-theme");
|
||||
document.body.classList.remove("dark-theme");
|
||||
}
|
||||
browser.storage.sync.set({
|
||||
theme: value,
|
||||
});
|
||||
});
|
||||
|
||||
function autocomplete(input, list) {
|
||||
let currentFocus;
|
||||
input.addEventListener("focus", (e) => {
|
||||
showOptions(e, true);
|
||||
});
|
||||
input.addEventListener("input", (e) => {
|
||||
const val = e.target.value;
|
||||
if (!val) {
|
||||
return false;
|
||||
}
|
||||
currentFocus = -1;
|
||||
showOptions(e);
|
||||
});
|
||||
input.addEventListener("keydown", function (e) {
|
||||
let x = document.getElementById(this.id + "autocomplete-list");
|
||||
if (x) x = x.getElementsByTagName("div");
|
||||
if (e.keyCode == 40) {
|
||||
currentFocus++;
|
||||
addActive(x);
|
||||
} else if (e.keyCode == 38) {
|
||||
currentFocus--;
|
||||
addActive(x);
|
||||
} else if (e.keyCode == 13) {
|
||||
e.preventDefault();
|
||||
if (currentFocus > -1) {
|
||||
if (x) x[currentFocus].click();
|
||||
}
|
||||
}
|
||||
});
|
||||
function showOptions(event, showAll = false) {
|
||||
let div,
|
||||
i,
|
||||
val = event.target.value;
|
||||
closeAllLists();
|
||||
div = document.createElement("div");
|
||||
div.setAttribute("id", event.target.id + "autocomplete-list");
|
||||
div.setAttribute("class", "autocomplete-items");
|
||||
event.target.parentNode.appendChild(div);
|
||||
for (i = 0; i < list.length; i++) {
|
||||
if (list[i].toLowerCase().indexOf(val.toLowerCase()) > -1) {
|
||||
div.appendChild(getItem(list[i], val));
|
||||
} else if (showAll) {
|
||||
div.appendChild(getItem(list[i], val));
|
||||
}
|
||||
}
|
||||
}
|
||||
function getItem(item, val) {
|
||||
let div = document.createElement("div");
|
||||
div.innerHTML = "<strong>" + item.substr(0, val.length) + "</strong>";
|
||||
div.innerHTML += item.substr(val.length);
|
||||
div.innerHTML += "<input type='hidden' value='" + item + "'>";
|
||||
div.addEventListener("click", function (e) {
|
||||
input.value = e.target.getElementsByTagName("input")[0].value;
|
||||
input.dispatchEvent(new Event("input"));
|
||||
closeAllLists();
|
||||
});
|
||||
return div;
|
||||
}
|
||||
function addActive(x) {
|
||||
if (!x) return false;
|
||||
removeActive(x);
|
||||
if (currentFocus >= x.length) currentFocus = 0;
|
||||
if (currentFocus < 0) currentFocus = x.length - 1;
|
||||
x[currentFocus].classList.add("autocomplete-active");
|
||||
}
|
||||
function removeActive(x) {
|
||||
for (let i = 0; i < x.length; i++) {
|
||||
x[i].classList.remove("autocomplete-active");
|
||||
}
|
||||
}
|
||||
function closeAllLists(elmnt) {
|
||||
let x = document.getElementsByClassName("autocomplete-items");
|
||||
for (let i = 0; i < x.length; i++) {
|
||||
if (elmnt != x[i] && elmnt != input) {
|
||||
x[i].parentNode.removeChild(x[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!autocompletes.find((element) => element.id === e.target.id)) {
|
||||
closeAllLists(e.target);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
autocompletes.forEach((value) => {
|
||||
autocomplete(document.getElementById(value.id), value.instances);
|
||||
});
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'>
|
||||
<path d='M384,224V408a40,40,0,0,1-40,40H104a40,40,0,0,1-40-40V168a40,40,0,0,1,40-40H271.48' style='fill:none;stroke:#FFF;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px'/>
|
||||
<polyline points='336 64 448 64 448 176' style='fill:none;stroke:#FFF;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px'/>
|
||||
<line x1='224' y1='288' x2='440' y2='72' style='fill:none;stroke:#FFF;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px'/>
|
||||
</svg>
|
Before Width: | Height: | Size: 553 B |
|
@ -1,122 +1,170 @@
|
|||
<!doctype html>
|
||||
<!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" />
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title></title>
|
||||
<link href="../styles.css" rel="stylesheet">
|
||||
</head>
|
||||
<body class="popup">
|
||||
<header class="popup">
|
||||
<div class="logo-container">
|
||||
<img
|
||||
src="../../assets/images/icon128.png"
|
||||
alt="Privacy Redirect logo"
|
||||
/>
|
||||
<h1>
|
||||
<span data-localise="__MSG_privacy__" class="privacy">Privacy</span
|
||||
><br /><span data-localise="__MSG_redirect__">Redirect</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="version">
|
||||
<span data-localise="__MSG_version__">Version</span>: <span
|
||||
id="version"
|
||||
></span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<body class="popup">
|
||||
<header>
|
||||
<div class="logo-container">
|
||||
<img src="../../images/icon128.png" alt="Privacy Redirect logo">
|
||||
<h1><span class="privacy">Privacy</span><br>Redirect</h1>
|
||||
</div>
|
||||
<div class="version">
|
||||
<span>Version: <span id="version"></span></span>
|
||||
</div>
|
||||
</header>
|
||||
<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="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Toggle Nitter redirects">
|
||||
<h1>Nitter Redirects</h1>
|
||||
<input aria-hidden="true" id="disable-nitter" type="checkbox" checked>
|
||||
<label for="disable-nitter" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</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="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Toggle Invidious redirects">
|
||||
<h1>Invidious Redirects</h1>
|
||||
<input aria-hidden="true" id="disable-invidious" type="checkbox" checked>
|
||||
<label for="disable-invidious" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</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="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Toggle Bibliogram redirects">
|
||||
<h1>Bibliogram Redirects</h1>
|
||||
<input aria-hidden="true" id="disable-bibliogram" type="checkbox" checked>
|
||||
<label for="disable-bibliogram" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</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="options settings_block">
|
||||
<div class="onoffswitch switch" aria-label="Toggle OpenStreetMap redirects">
|
||||
<h1>OpenStreetMap Redirects</h1>
|
||||
<input aria-hidden="true" id="disable-osm" type="checkbox" checked>
|
||||
<label for="disable-osm" class="checkbox-label">
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
<section class="settings-block"></section>
|
||||
|
||||
<section class="options settings_block">
|
||||
<h1>Nitter Instance</h1>
|
||||
<input id="nitter-instance" list="nitter-instance-list" type="url" placeholder="https://nitter.net">
|
||||
<datalist id="nitter-instance-list">
|
||||
<option value="https://nitter.net">
|
||||
<option value="https://nitter.snopyta.org">
|
||||
<option value="https://nitter.42l.fr">
|
||||
<option value="https://nitter.nixnet.xyz">
|
||||
<option value="https://nitter.13ad.de">
|
||||
<option value="https://tw.openalgeria.org">
|
||||
<option value="https://nitter.pussthecat.org">
|
||||
<option value="https://nitter.mastodont.cat">
|
||||
<option value="https://nitter.dark.fail">
|
||||
<option value="https://nitter.tedomum.net">
|
||||
<option value="https://t.maisputain.ovh">
|
||||
<option value="http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion">
|
||||
<option value="http://nitter.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd.onion">
|
||||
<option value="http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion">
|
||||
</datalist>
|
||||
<h1>Invidious Instance</h1>
|
||||
<input id="invidious-instance" list="invidious-instances-list" type="url" placeholder="https://invidio.us">
|
||||
<datalist id="invidious-instances-list">
|
||||
<option value="https://invidio.us">
|
||||
<option value="https://invidious.snopyta.org">
|
||||
<option value="https://invidiou.sh">
|
||||
<option value="https://yewtu.be">
|
||||
<option value="https://yt.maisputain.ovh">
|
||||
<option value="https://invidious.toot.koeln">
|
||||
<option value="https://invidious.ggc-project.de">
|
||||
<option value="https://invidious.toot.koeln">
|
||||
<option value="http://kgg2m7yk5aybusll.onion">
|
||||
<option value="http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid.onion">
|
||||
<option value="http://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion">
|
||||
<option value="http://qklhadlycap4cnod.onion">
|
||||
<option value="http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion">
|
||||
<option value="http://mfqczy4mysscub2s.onion">
|
||||
</datalist>
|
||||
<h1>Bibliogram Instance</h1>
|
||||
<input id="bibliogram-instance" list="bibliogram-instance-list" type="url" placeholder="https://bibliogram.art">
|
||||
<datalist id="bibliogram-instance-list">
|
||||
<option value="https://bibliogram.art">
|
||||
<option value="https://bibliogram.snopyta.org">
|
||||
<option value="https://bibliogram.pussthecat.org">
|
||||
<option value="https://insta.maisputain.ovh">
|
||||
<option value="https://bibliogram.nixnet.services">
|
||||
</datalist>
|
||||
<h1>OpenStreetMap Instance</h1>
|
||||
<input id="osm-instance" list="osm-instance-list" type="url" placeholder="https://openstreetmap.org">
|
||||
<datalist id="osm-instance-list">
|
||||
<option value="https://openstreetmap.org">
|
||||
</datalist>
|
||||
</section>
|
||||
<footer>
|
||||
<a class="button" id="more-options">
|
||||
<span data-localise="__MSG_moreOptions__">More Options </span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
d="M384,224V408a40,40,0,0,1-40,40H104a40,40,0,0,1-40-40V168a40,40,0,0,1,40-40H271.48"
|
||||
style="
|
||||
fill: none;
|
||||
stroke: inherit;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 32px;
|
||||
"
|
||||
/>
|
||||
<polyline
|
||||
points="336 64 448 64 448 176"
|
||||
style="
|
||||
fill: none;
|
||||
stroke: inherit;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 32px;
|
||||
"
|
||||
/>
|
||||
<line
|
||||
x1="224"
|
||||
y1="288"
|
||||
x2="440"
|
||||
y2="72"
|
||||
style="
|
||||
fill: none;
|
||||
stroke: inherit;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 32px;
|
||||
"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</footer>
|
||||
|
||||
<footer>
|
||||
<a class="button" id="more-options">
|
||||
<span>More Options </span>
|
||||
<img height="18px" src="open.svg" alt="more-options" />
|
||||
</a>
|
||||
</footer>
|
||||
|
||||
<script src="./popup.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<script src="./popup.js"></script>
|
||||
<script src="../../assets/javascript/localise.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,33 +1,23 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
let nitterInstance = document.querySelector('#nitter-instance');
|
||||
let invidiousInstance = document.querySelector('#invidious-instance');
|
||||
let bibliogramInstance = document.querySelector('#bibliogram-instance');
|
||||
let osmInstance = document.querySelector('#osm-instance');
|
||||
let disableNitter = document.querySelector('#disable-nitter');
|
||||
let disableInvidious = document.querySelector('#disable-invidious');
|
||||
let disableBibliogram = document.querySelector('#disable-bibliogram');
|
||||
let disableOsm = document.querySelector('#disable-osm');
|
||||
let version = document.querySelector('#version');
|
||||
let disableNitter = document.querySelector("#disable-nitter");
|
||||
let disableInvidious = document.querySelector("#disable-invidious");
|
||||
let disableBibliogram = document.querySelector("#disable-bibliogram");
|
||||
let disableOsm = document.querySelector("#disable-osm");
|
||||
let version = document.querySelector("#version");
|
||||
|
||||
window.browser = window.browser || window.chrome;
|
||||
|
||||
browser.storage.sync.get(
|
||||
[
|
||||
'nitterInstance',
|
||||
'invidiousInstance',
|
||||
'bibliogramInstance',
|
||||
'osmInstance',
|
||||
'disableNitter',
|
||||
'disableInvidious',
|
||||
'disableBibliogram',
|
||||
'disableOsm'
|
||||
"disableNitter",
|
||||
"disableInvidious",
|
||||
"disableBibliogram",
|
||||
"disableOsm",
|
||||
"theme",
|
||||
],
|
||||
result => {
|
||||
nitterInstance.value = result.nitterInstance || '';
|
||||
invidiousInstance.value = result.invidiousInstance || '';
|
||||
bibliogramInstance.value = result.bibliogramInstance || '';
|
||||
osmInstance.value = result.osmInstance || '';
|
||||
(result) => {
|
||||
if (result.theme) document.body.classList.add(result.theme);
|
||||
disableNitter.checked = !result.disableNitter;
|
||||
disableInvidious.checked = !result.disableInvidious;
|
||||
disableBibliogram.checked = !result.disableBibliogram;
|
||||
|
@ -37,91 +27,22 @@ browser.storage.sync.get(
|
|||
|
||||
version.textContent = browser.runtime.getManifest().version;
|
||||
|
||||
function debounce(func, wait, immediate) {
|
||||
let timeout;
|
||||
return () => {
|
||||
let context = this, args = arguments;
|
||||
let later = () => {
|
||||
timeout = null;
|
||||
if (!immediate) func.apply(context, args);
|
||||
};
|
||||
let callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(context, args);
|
||||
};
|
||||
};
|
||||
|
||||
function parseURL(urlString) {
|
||||
if (urlString) {
|
||||
try {
|
||||
const url = new URL(urlString);
|
||||
if (url.username && url.password) {
|
||||
return `${url.protocol}//${url.username}:${url.password}@${url.host}`
|
||||
} else {
|
||||
return url.origin;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
let nitterInstanceChange = debounce(() => {
|
||||
if (nitterInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
nitterInstance: parseURL(nitterInstance.value)
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
nitterInstance.addEventListener('input', nitterInstanceChange);
|
||||
|
||||
let invidiousInstanceChange = debounce(() => {
|
||||
if (invidiousInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
invidiousInstance: parseURL(invidiousInstance.value)
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
invidiousInstance.addEventListener('input', invidiousInstanceChange);
|
||||
|
||||
let bibliogramInstanceChange = debounce(() => {
|
||||
if (bibliogramInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
bibliogramInstance: parseURL(bibliogramInstance.value)
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
bibliogramInstance.addEventListener('input', bibliogramInstanceChange);
|
||||
|
||||
let osmInstanceChange = debounce(() => {
|
||||
if (osmInstance.checkValidity()) {
|
||||
browser.storage.sync.set({
|
||||
osmInstance: parseURL(osmInstance.value)
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
osmInstance.addEventListener('input', osmInstanceChange);
|
||||
|
||||
disableNitter.addEventListener('change', event => {
|
||||
disableNitter.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ disableNitter: !event.target.checked });
|
||||
});
|
||||
|
||||
disableInvidious.addEventListener('change', event => {
|
||||
disableInvidious.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ disableInvidious: !event.target.checked });
|
||||
});
|
||||
|
||||
disableBibliogram.addEventListener('change', event => {
|
||||
disableBibliogram.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ disableBibliogram: !event.target.checked });
|
||||
});
|
||||
|
||||
disableOsm.addEventListener('change', event => {
|
||||
disableOsm.addEventListener("change", (event) => {
|
||||
browser.storage.sync.set({ disableOsm: !event.target.checked });
|
||||
});
|
||||
|
||||
document.querySelector('#more-options').addEventListener('click', () => {
|
||||
document.querySelector("#more-options").addEventListener("click", () => {
|
||||
browser.runtime.openOptionsPage();
|
||||
});
|
||||
|
|
301
pages/styles.css
|
@ -1,31 +1,41 @@
|
|||
:root {
|
||||
--text-main: #FFF;
|
||||
--text-secondary: #000;
|
||||
--dark: #3C4043;
|
||||
--darker: #292A2D;
|
||||
--light: #E3E7EA;
|
||||
--lighter: #FFF;
|
||||
--active: #FF5B56;
|
||||
body {
|
||||
--text: #fff;
|
||||
--bg-main: #3c4043;
|
||||
--bg-secondary: #292a2d;
|
||||
--active: #ff5b56;
|
||||
--space: 5px;
|
||||
--danger: #f04141;
|
||||
--danger-light: #F9D0D5;
|
||||
--danger-light: #f9d0d5;
|
||||
--dark-grey: #767676;
|
||||
--light-grey: #c3c3c3;
|
||||
}
|
||||
|
||||
body.light-theme {
|
||||
--text: #000;
|
||||
--bg-main: #e3e7ea;
|
||||
--bg-secondary: #fff;
|
||||
}
|
||||
|
||||
.light-theme.popup,
|
||||
.light-theme .popup {
|
||||
background-color: var(--bg-secondary);
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text-secondary);
|
||||
margin: 0;
|
||||
width: 400px;
|
||||
max-width: 400px;
|
||||
margin: auto;
|
||||
min-height: 572px;
|
||||
font-family: Sans-Serif;
|
||||
background-color: var(--darker);
|
||||
background-color: var(--bg-secondary);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.popup {
|
||||
width: 300px;
|
||||
min-height: auto;
|
||||
overflow: hidden;
|
||||
background-color: var(--dark);
|
||||
background-color: var(--bg-main);
|
||||
}
|
||||
|
||||
input {
|
||||
|
@ -35,8 +45,8 @@ input {
|
|||
}
|
||||
|
||||
header {
|
||||
background-color: var(--lighter);
|
||||
color: var(--text-secondary);
|
||||
background-color: var(--bg-main);
|
||||
color: var(--text);
|
||||
display: flex;
|
||||
padding: var(--space);
|
||||
}
|
||||
|
@ -45,7 +55,7 @@ header .logo-container {
|
|||
width: 100%;
|
||||
margin: var(--space) 0 var(--space) 0;
|
||||
display: flex;
|
||||
align-items:center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header .logo-container img {
|
||||
|
@ -75,7 +85,7 @@ header .version {
|
|||
|
||||
h1 {
|
||||
font-size: 14px;
|
||||
margin: var(--space) auto;
|
||||
margin: 7px auto;
|
||||
}
|
||||
|
||||
i {
|
||||
|
@ -95,7 +105,7 @@ h3 {
|
|||
|
||||
h1,
|
||||
h2 {
|
||||
color: var(--text-main);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
footer {
|
||||
|
@ -106,26 +116,40 @@ footer a.button {
|
|||
margin: var(--space);
|
||||
}
|
||||
|
||||
/* Elements */
|
||||
|
||||
input[type=url], input[type=text], select {
|
||||
input[type="url"],
|
||||
input[type="text"],
|
||||
select {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: var(--space);
|
||||
background-color: var(--bg-main);
|
||||
border-style: inset;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
input[type=url] {
|
||||
input[type="url"] {
|
||||
padding: 1px 2px;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
input[type="checkbox"] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
appearance: radio;
|
||||
-moz-appearance: radio;
|
||||
-webkit-appearance: radio;
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + label {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
margin-left: 5px;
|
||||
background: grey;
|
||||
border-radius: 25px;
|
||||
color: var(--text-main);
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
float: right;
|
||||
|
@ -137,37 +161,39 @@ input[type=checkbox] {
|
|||
}
|
||||
|
||||
.checkbox-label:after {
|
||||
background: #fff;
|
||||
background: white;
|
||||
border-radius: 90px;
|
||||
content: '';
|
||||
content: "";
|
||||
height: 20px;
|
||||
left: var(--space);
|
||||
position: absolute;
|
||||
top: var(--space);
|
||||
transition: 0.3s; /* Acts on transform below */
|
||||
transition: 0.3s;
|
||||
width: 20px;
|
||||
}
|
||||
input:checked+label {
|
||||
|
||||
input:checked + label {
|
||||
background: var(--active);
|
||||
}
|
||||
/* position when active*/
|
||||
input:checked+label:after {
|
||||
|
||||
input:checked + label:after {
|
||||
left: calc(100% - var(--space));
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.settings_block {
|
||||
.settings-block {
|
||||
display: block;
|
||||
padding: 10px 1em 1em 1em;
|
||||
padding: 5px 10px 5px 10px;
|
||||
}
|
||||
|
||||
.settings_block h1 {
|
||||
.settings-block h1 {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.button {
|
||||
border: var(--active) solid 1px;
|
||||
color: var(--text-main);
|
||||
color: var(--text);
|
||||
stroke: var(--text);
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
|
@ -186,12 +212,13 @@ input:checked+label:after {
|
|||
|
||||
.button:hover {
|
||||
background-color: var(--active);
|
||||
color: #fff;
|
||||
color: var(--text);
|
||||
stroke: var(--text);
|
||||
}
|
||||
|
||||
.button:active {
|
||||
background-color: var(--active);
|
||||
box-shadow: 0 var(--space) var(--dark);
|
||||
box-shadow: 0 var(--space) var(--bg-main);
|
||||
transform: translateY(4px);
|
||||
}
|
||||
|
||||
|
@ -207,13 +234,13 @@ input:invalid {
|
|||
|
||||
.tab {
|
||||
overflow: hidden;
|
||||
background-color: var(--darker);
|
||||
background-color: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.tab button {
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
color: var(--text-main);
|
||||
color: var(--text);
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
|
@ -221,7 +248,7 @@ input:invalid {
|
|||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
border: solid 1px var(--dark);
|
||||
border: solid 1px var(--bg-main);
|
||||
width: 33.333%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@ -231,106 +258,206 @@ input:invalid {
|
|||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: var(--dark);
|
||||
background-color: var(--bg-main);
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
padding-top: 10px;
|
||||
display: none;
|
||||
border: solid 1px var(--dark);
|
||||
background-color: var(--dark);
|
||||
background-color: var(--bg-main);
|
||||
min-height: 510px;
|
||||
}
|
||||
|
||||
div.whitelist {
|
||||
div.exceptions {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
div.whitelist > input {
|
||||
div.exceptions > input {
|
||||
width: 240px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#add-to-whitelist {
|
||||
width: 120px;
|
||||
#add-to-exceptions {
|
||||
float: right;
|
||||
border: var(--active) solid 1px;
|
||||
background-color: var(--active);
|
||||
color: var(--text-main);
|
||||
color: var(--text);
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
border-radius: 25px;
|
||||
border-radius: 50%;
|
||||
padding: 1px 1px 0px 1px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#add-to-exceptions svg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
color: var(--text-main);
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
color: var(--text);
|
||||
margin: 20px 20px 0 20px;
|
||||
}
|
||||
|
||||
li {
|
||||
border-bottom: solid 0.5px var(--darker);
|
||||
border-bottom: solid 0.5px var(--bg-secondary);
|
||||
padding: 20px 0px 20px 20px;
|
||||
}
|
||||
|
||||
#whitelist-items button {
|
||||
#exceptions-items button {
|
||||
float: right;
|
||||
margin-right: -5px;
|
||||
border: var(--active) solid 1px;
|
||||
background-color: var(--active);
|
||||
color: var(--text-main);
|
||||
color: var(--text);
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
padding: 2px 2px 0px 2px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.button svg {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
body.popup, header, h1, input, select, div.tabcontent, button.tablinks.active {
|
||||
background-color: var(--dark);
|
||||
color: var(--text-main);
|
||||
}
|
||||
.autocomplete {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--darker);
|
||||
}
|
||||
.autocomplete input {
|
||||
background: url(../assets/images/chevron-down.svg) right no-repeat;
|
||||
}
|
||||
|
||||
a.button {
|
||||
color: var(--text-main);
|
||||
}
|
||||
.autocomplete-items {
|
||||
position: absolute;
|
||||
border: 1px solid var(--bg-main);
|
||||
border-bottom: none;
|
||||
border-top: none;
|
||||
z-index: 99;
|
||||
top: 85%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow-y: auto;
|
||||
max-height: 175px;
|
||||
color: var(--text);
|
||||
overflow-x: hidden;
|
||||
max-width: 380px;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: var(--text-main);
|
||||
opacity: 0.7;
|
||||
}
|
||||
.autocomplete-items div {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
background-color: var(--bg-secondary);
|
||||
border-bottom: 1px solid var(--bg-main);
|
||||
}
|
||||
|
||||
.autocomplete-items div:hover {
|
||||
background-color: var(--active);
|
||||
}
|
||||
|
||||
.autocomplete-active {
|
||||
background-color: var(--active);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.option {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.option td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
-webkit-appearance: none;
|
||||
margin: 18px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input[type="range"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type="range"]::-webkit-slider-runnable-track {
|
||||
width: 100%;
|
||||
height: 8.4px;
|
||||
cursor: pointer;
|
||||
border-color: var(--dark-grey), var(--light-grey);
|
||||
background: var(--bg-main);
|
||||
border-radius: 1.3px;
|
||||
border: 0.2px inset var(--dark-grey);
|
||||
}
|
||||
|
||||
input[type="range"]::-webkit-slider-thumb {
|
||||
border-color: var(--active);
|
||||
border: 1px solid var(--dark-grey);
|
||||
height: 36px;
|
||||
width: 16px;
|
||||
border-radius: 3px;
|
||||
background: var(--active);
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
margin-top: -14px;
|
||||
}
|
||||
|
||||
input[type="range"]:focus::-webkit-slider-runnable-track {
|
||||
background: var(--bg-main);
|
||||
}
|
||||
|
||||
input[type="range"]::-moz-range-track {
|
||||
width: 100%;
|
||||
height: 8.4px;
|
||||
cursor: pointer;
|
||||
border-color: var(--dark-grey), var(--light-grey);
|
||||
background: var(--bg-main);
|
||||
border-radius: 1.3px;
|
||||
border: 0.2px inset var(--dark-grey);
|
||||
}
|
||||
|
||||
input[type="range"]::-moz-range-thumb {
|
||||
border-color: var(--active);
|
||||
border: 1px solid var(--dark-grey);
|
||||
height: 36px;
|
||||
width: 16px;
|
||||
border-radius: 3px;
|
||||
background: var(--active);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: var(--text);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
*:focus {
|
||||
outline: var(--active) solid 2px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
|
||||
body.popup, header, h1, input, select, div.tabcontent, button.tablinks.active {
|
||||
background-color: var(--lighter);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--light);
|
||||
--text: #000;
|
||||
--text-secondary: #fff;
|
||||
--bg-main: #e3e7ea;
|
||||
--bg-secondary: #fff;
|
||||
}
|
||||
|
||||
a.button {
|
||||
color: var(--text-secondary);
|
||||
body.dark-theme {
|
||||
--text: #fff;
|
||||
--text-secondary: #000;
|
||||
--bg-main: #3c4043;
|
||||
--bg-secondary: #292a2d;
|
||||
}
|
||||
|
||||
button.tablinks {
|
||||
background-color: var(--light);
|
||||
color: var(--text-secondary);
|
||||
.popup {
|
||||
background-color: var(--bg-secondary);
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: var(--text-secondary);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#volume-value {
|
||||
float: right;
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
# Privacy Policy for Privacy Redirect
|
||||
|
||||
**I solemnly swear this extension is up to only good! 🙂**
|
||||
|
||||
All aspects of the extension work locally on your device. With the exception of
|
||||
OpenStreetMap (OSM) reverse geocoding, done via the [OSM Nomantim API](https://nominatim.org/release-docs/latest/),
|
||||
used as part of OSM redirects, the extension does not connect to any other
|
||||
third-party web services and it doesn’t collect or transmit
|
||||
any information about you, your browsing habits, or your device.
|
||||
|
||||
The extension requires access to request data for **all websites** in order
|
||||
to intercept requests made to targeted services (Twitter, YouTube, Instagram &
|
||||
Google Maps) so that they may be redirected to the appropriate privacy
|
||||
respecting alternative, all other requests are ignored.
|
||||
|
||||
The extension also requires **local storage** permissions in order to store
|
||||
extension specific user preferences and settings.
|
||||
|
||||
The extension development is funded through gifts, donations and love.
|
|
@ -1,7 +1,8 @@
|
|||
module.exports = {
|
||||
ignoreFiles: [
|
||||
'images/Screen*.png',
|
||||
'images/small-tile.png',
|
||||
'buy-me-a-coffee.png'
|
||||
'assets/images/Screen Shot*.png',
|
||||
'assets/images/buy-me-a-coffee.png',
|
||||
'assets/images/logo*.png',
|
||||
'assets/images/badge*.png'
|
||||
],
|
||||
};
|
||||
|
|