1
0
mirror of https://github.com/SimonBrazell/privacy-redirect synced 2025-03-10 08:20:09 +01:00

Address issues #21, #22, #23, #24, #25 & #26

This commit is contained in:
SimonBrazell 2020-03-21 20:34:32 +11:00
parent 75e4b6a69c
commit abb1115b58
8 changed files with 198 additions and 52 deletions

View File

@ -1,9 +1,24 @@
'use strict'; 'use strict';
const invidiousDefault = 'https://invidio.us'; const invidiousDefault = 'https://invidio.us';
const youtubeRegex = /((www|m)\.)?(youtube|ytimg(-nocookie)?\.com|youtu.be)/; 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',
];
const nitterDefault = 'https://nitter.net'; const nitterDefault = 'https://nitter.net';
const twitterRegex = /((www|mobile)\.)?twitter\.com/; const twitterDomains = [
'twitter.com',
'www.twitter.com',
'mobile.twitter.com',
'pbs.twimg.com',
'video.twimg.com',
];
const bibliogramDefault = 'https://bibliogram.art'; const bibliogramDefault = 'https://bibliogram.art';
const instagramRegex = /((www|about|help)\.)?instagram\.com/; const instagramRegex = /((www|about|help)\.)?instagram\.com/;
const instagramPathsRegex = /\/(a|admin|api|favicon.ico|static|imageproxy|p|u|developer|about|legal|explore|director)/; const instagramPathsRegex = /\/(a|admin|api|favicon.ico|static|imageproxy|p|u|developer|about|legal|explore|director)/;
@ -34,6 +49,8 @@ let invidiousInstance;
let bibliogramInstance; let bibliogramInstance;
let osmInstance; let osmInstance;
let alwaysProxy; let alwaysProxy;
let onlyEmbeddedVideo;
let videoQuality;
window.browser = window.browser || window.chrome; window.browser = window.browser || window.chrome;
@ -46,7 +63,10 @@ browser.storage.sync.get(
'disableNitter', 'disableNitter',
'disableInvidious', 'disableInvidious',
'disableBibliogram', 'disableBibliogram',
'disableOsm' 'disableOsm',
'alwaysProxy',
'onlyEmbeddedVideo',
'videoQuality'
], ],
result => { result => {
disableNitter = result.disableNitter; disableNitter = result.disableNitter;
@ -58,6 +78,8 @@ browser.storage.sync.get(
bibliogramInstance = result.bibliogramInstance || bibliogramDefault; bibliogramInstance = result.bibliogramInstance || bibliogramDefault;
osmInstance = result.osmInstance || osmDefault; osmInstance = result.osmInstance || osmDefault;
alwaysProxy = result.alwaysProxy; alwaysProxy = result.alwaysProxy;
onlyEmbeddedVideo = result.onlyEmbeddedVideo;
videoQuality = result.videoQuality;
} }
); );
@ -89,6 +111,12 @@ browser.storage.onChanged.addListener(changes => {
if ('alwaysProxy' in changes) { if ('alwaysProxy' in changes) {
alwaysProxy = changes.alwaysProxy.newValue; alwaysProxy = changes.alwaysProxy.newValue;
} }
if ('onlyEmbeddedVideo' in changes) {
onlyEmbeddedVideo = changes.onlyEmbeddedVideo.newValue;
}
if ('videoQuality' in changes) {
videoQuality = changes.videoQuality.newValue;
}
}); });
function addressToLatLng(address, callback) { function addressToLatLng(address, callback) {
@ -117,11 +145,11 @@ function addressToLatLng(address, callback) {
xmlhttp.send(); xmlhttp.send();
} }
function redirectYouTube(url) { function redirectYouTube(url, type) {
if (url.host.split('.')[0] === 'studio') { if (disableInvidious) {
// Avoid redirecting `studio.youtube.com`
return null; return null;
} else if (url.pathname.match(/iframe_api/)) { }
if (url.pathname.match(/iframe_api/)) {
// Redirect requests for YouTube Player API to local files instead // Redirect requests for YouTube Player API to local files instead
return browser.runtime.getURL('assets/iframe_api.js'); return browser.runtime.getURL('assets/iframe_api.js');
} else if (url.pathname.match(/www-widgetapi/)) { } else if (url.pathname.match(/www-widgetapi/)) {
@ -132,20 +160,33 @@ function redirectYouTube(url) {
if (alwaysProxy) { if (alwaysProxy) {
url.searchParams.append('local', true); url.searchParams.append('local', true);
} }
if (videoQuality) {
url.searchParams.append('quality', videoQuality);
}
if (onlyEmbeddedVideo && type !== 'sub_frame') {
return null;
}
return `${invidiousInstance}${url.pathname}${url.search}`; return `${invidiousInstance}${url.pathname}${url.search}`;
} }
} }
function redirectTwitter(url) { function redirectTwitter(url) {
if (url.host.split('.')[0] === 'tweetdeck') { if (disableNitter) {
// Avoid redirecting `tweetdeck.twitter.com`
return null; 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 { } else {
return `${nitterInstance}${url.pathname}${url.search}`; return `${nitterInstance}${url.pathname}${url.search}`;
} }
} }
function redirectInstagram(url) { function redirectInstagram(url) {
if (disableBibliogram) {
return null;
}
if (url.pathname === '/' || url.pathname.match(instagramPathsRegex)) { if (url.pathname === '/' || url.pathname.match(instagramPathsRegex)) {
return `${bibliogramInstance}${url.pathname}${url.search}`; return `${bibliogramInstance}${url.pathname}${url.search}`;
} else { } else {
@ -155,6 +196,9 @@ function redirectInstagram(url) {
} }
function redirectGoogleMaps(url) { function redirectGoogleMaps(url) {
if (disableOsm) {
return null;
}
let redirect; let redirect;
let mapCentre = ''; let mapCentre = '';
let params = ''; let params = '';
@ -224,30 +268,22 @@ browser.webRequest.onBeforeRequest.addListener(
details => { details => {
const url = new URL(details.url); const url = new URL(details.url);
let redirect; let redirect;
if (url.host.match(youtubeRegex) && !url.host.includes('youtube-dl.org')) { if (youtubeDomains.includes(url.host)) {
if (!disableInvidious) { redirect = {
redirect = { redirectUrl: redirectYouTube(url, details.type)
redirectUrl: redirectYouTube(url) };
}; } else if (twitterDomains.includes(url.host)) {
} redirect = {
} else if (url.host.match(twitterRegex)) { redirectUrl: redirectTwitter(url)
if (!disableNitter) { };
redirect = {
redirectUrl: redirectTwitter(url)
};
}
} else if (url.host.match(instagramRegex)) { } else if (url.host.match(instagramRegex)) {
if (!disableBibliogram) { redirect = {
redirect = { redirectUrl: redirectInstagram(url)
redirectUrl: redirectInstagram(url) };
};
}
} else if (url.href.match(googleMapsRegex)) { } else if (url.href.match(googleMapsRegex)) {
if (!disableOsm) { redirect = {
redirect = { redirectUrl: redirectGoogleMaps(url)
redirectUrl: redirectGoogleMaps(url) };
};
}
} }
if (redirect && redirect.redirectUrl) { if (redirect && redirect.redirectUrl) {
console.info( console.info(

View File

@ -1,7 +1,7 @@
{ {
"name": "Privacy Redirect", "name": "Privacy Redirect",
"description": "Redirects Twitter, YouTube, Instagram & Google Maps requests to privacy friendly alternatives.", "description": "Redirects Twitter, YouTube, Instagram & Google Maps requests to privacy friendly alternatives.",
"version": "1.1.15", "version": "1.1.16",
"manifest_version": 2, "manifest_version": 2,
"background": { "background": {
"scripts": [ "scripts": [

View File

@ -92,9 +92,24 @@
</div> </div>
</section> </section>
<footer> <section class="options settings_block">
<a class="button" id="save">Save</a> <div class="onoffswitch switch" aria-label="Only redirect embedded video to Invidious">
</footer> <h1>Only redirect embedded video to Invidious?</h1>
<input aria-hidden="true" id="only-embed" type="checkbox" checked>&nbsp;
<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>
<script src="./options.js"></script> <script src="./options.js"></script>

View File

@ -9,6 +9,8 @@ let disableInvidious = document.querySelector('#disable-invidious');
let disableBibliogram = document.querySelector('#disable-bibliogram'); let disableBibliogram = document.querySelector('#disable-bibliogram');
let disableOsm = document.querySelector('#disable-osm'); let disableOsm = document.querySelector('#disable-osm');
let alwaysProxy = document.querySelector('#always-proxy'); let alwaysProxy = document.querySelector('#always-proxy');
let onlyEmbeddedVideo = document.querySelector('#only-embed');
let videoQuality = document.querySelector('#video-quality');
window.browser = window.browser || window.chrome; window.browser = window.browser || window.chrome;
@ -22,7 +24,9 @@ browser.storage.sync.get(
'disableInvidious', 'disableInvidious',
'disableBibliogram', 'disableBibliogram',
'disableOsm', 'disableOsm',
'alwaysProxy' 'alwaysProxy',
'onlyEmbeddedVideo',
'videoQuality'
], ],
result => { result => {
nitterInstance.value = result.nitterInstance || ''; nitterInstance.value = result.nitterInstance || '';
@ -34,20 +38,88 @@ browser.storage.sync.get(
disableBibliogram.checked = !result.disableBibliogram; disableBibliogram.checked = !result.disableBibliogram;
disableOsm.checked = !result.disableOsm; disableOsm.checked = !result.disableOsm;
alwaysProxy.checked = result.alwaysProxy; alwaysProxy.checked = result.alwaysProxy;
onlyEmbeddedVideo.checked = result.onlyEmbeddedVideo;
videoQuality.value = result.videoQuality || '';
} }
); );
document.querySelector('#save').addEventListener('click', () => { function debounce(func, wait, immediate) {
browser.storage.sync.set({ let timeout;
nitterInstance: nitterInstance.value && nitterInstance.checkValidity() ? new URL(nitterInstance.value).origin : '', return () => {
invidiousInstance: invidiousInstance.value && invidiousInstance.checkValidity() ? new URL(invidiousInstance.value).origin : '', let context = this, args = arguments;
bibliogramInstance: bibliogramInstance.value && bibliogramInstance.checkValidity() ? new URL(bibliogramInstance.value).origin : '', let later = () => {
osmInstance: osmInstance.value && osmInstance.checkValidity() ? new URL(osmInstance.value).origin : '', timeout = null;
disableNitter: !disableNitter.checked, if (!immediate) func.apply(context, args);
disableInvidious: !disableInvidious.checked, };
disableBibliogram: !disableBibliogram.checked, let callNow = immediate && !timeout;
disableOsm: !disableOsm.checked, clearTimeout(timeout);
alwaysProxy: alwaysProxy.checked timeout = setTimeout(later, wait);
}); if (callNow) func.apply(context, args);
window.close(); };
};
let nitterInstanceChange = debounce(() => {
if (nitterInstance.checkValidity()) {
browser.storage.sync.set({
nitterInstance: nitterInstance.value ? new URL(nitterInstance.value).origin : ''
});
}
}, 500);
nitterInstance.addEventListener('input', nitterInstanceChange);
let invidiousInstanceChange = debounce(() => {
if (invidiousInstance.checkValidity()) {
browser.storage.sync.set({
invidiousInstance: invidiousInstance.value ? new URL(invidiousInstance.value).origin : ''
});
}
}, 500);
invidiousInstance.addEventListener('input', invidiousInstanceChange);
let bibliogramInstanceChange = debounce(() => {
if (bibliogramInstance.checkValidity()) {
browser.storage.sync.set({
bibliogramInstance: bibliogramInstance.value ? new URL(bibliogramInstance.value).origin : ''
});
}
}, 500);
bibliogramInstance.addEventListener('input', bibliogramInstanceChange);
let osmInstanceChange = debounce(() => {
if (osmInstance.checkValidity()) {
browser.storage.sync.set({
osmInstance: osmInstance.value ? new URL(osmInstance.value).origin : ''
});
}
}, 500);
osmInstance.addEventListener('input', osmInstanceChange);
disableNitter.addEventListener('change', event => {
browser.storage.sync.set({ disableNitter: !event.target.checked });
});
disableInvidious.addEventListener('change', event => {
browser.storage.sync.set({ disableInvidious: !event.target.checked });
});
disableBibliogram.addEventListener('change', event => {
browser.storage.sync.set({ disableBibliogram: !event.target.checked });
});
disableOsm.addEventListener('change', event => {
browser.storage.sync.set({ disableOsm: !event.target.checked });
});
alwaysProxy.addEventListener('change', event => {
browser.storage.sync.set({ alwaysProxy: event.target.checked });
});
onlyEmbeddedVideo.addEventListener('change', event => {
browser.storage.sync.set({ onlyEmbeddedVideo: event.target.checked });
});
videoQuality.addEventListener('change', event => {
browser.storage.sync.set({
videoQuality: event.target.options[videoQuality.selectedIndex].value
});
}); });

5
pages/popup/open.svg Normal file
View File

@ -0,0 +1,5 @@
<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>

After

Width:  |  Height:  |  Size: 553 B

View File

@ -8,7 +8,7 @@
<link href="../styles.css" rel="stylesheet"> <link href="../styles.css" rel="stylesheet">
</head> </head>
<body> <body class="popup">
<header> <header>
<div class="logo-container"> <div class="logo-container">
<img src="../../images/logo.png" alt="Privacy Redirect logo"> <img src="../../images/logo.png" alt="Privacy Redirect logo">
@ -90,6 +90,13 @@
</datalist> </datalist>
</section> </section>
<footer>
<a class="button" id="more-options">
<span>More Options&nbsp;</span>
<img height="18px" src="open.svg" alt="more-options" />
</a>
</footer>
<script src="./popup.js"></script> <script src="./popup.js"></script>
</body> </body>

View File

@ -103,3 +103,7 @@ disableBibliogram.addEventListener('change', event => {
disableOsm.addEventListener('change', event => { disableOsm.addEventListener('change', event => {
browser.storage.sync.set({ disableOsm: !event.target.checked }); browser.storage.sync.set({ disableOsm: !event.target.checked });
}); });
document.querySelector('#more-options').addEventListener('click', () => {
browser.runtime.openOptionsPage();
});

View File

@ -12,9 +12,13 @@
body { body {
color: var(--text-secondary); color: var(--text-secondary);
margin: 0; margin: 0;
background-color: var(--dark-grey);
}
.popup {
max-width: 400px; max-width: 400px;
min-width: 300px; min-width: 300px;
background-color: var(--dark-grey); overflow: hidden;
} }
header { header {
@ -80,7 +84,7 @@ footer a.button {
/* Elements */ /* Elements */
input[type=url] { input[type=url], select {
width: 100%; width: 100%;
margin-bottom: 5px; margin-bottom: 5px;
} }
@ -148,6 +152,10 @@ input:checked+label:after {
transition-duration: 0.4s; transition-duration: 0.4s;
} }
.button * {
vertical-align: middle;
}
.button:hover { .button:hover {
background-color: var(--active); background-color: var(--active);
color: #fff; color: #fff;
@ -168,4 +176,3 @@ input[type="url"]:invalid {
.margin-bottom { .margin-bottom {
margin-bottom: 20px; margin-bottom: 20px;
} }